Closed lilan123 closed 9 years ago
Can you give / show an example? I don't really understand how this would work, or actually what you mean.
Please find high level of the idea as below
ex: 1 $scope.obj1={id:001, name:jone}; $scope.obj2=[{empid:001, employeeType: permanent },{empid:002, employeeType: permanent }]
Expect : $scope.obj3={id:001,name:jone, empid:001, employeeType: permanent}
obj1 JOIN obj2 | where: obj1 .id==obj2.empid
ex: 2 $scope.obj2=[{Name:Harry, EmpId: 3415, DeptName:Finance},{Name:Sally, EmpId: 2241, DeptName:Sales},{Name:George, EmpId: 3401, DeptName:Finance}]
Expect : $scope.obj3=[{Name:Harry, EmpId: 3415, DeptName:Finance}, {Name:George, EmpId: 3401, DeptName:Finance}]
obj1 | where: obj1 .id=='Finance'
By this we will be able to use Projection, Join (Outer joins, Right outer join, Full outer join), Division and also addition to this it can be introduced sum, average, etc...
ex: 3 sum(e.salary) e in employees | where: e.salary>25000
Lambda expressions sample as below
ex: 4 $scope.numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; $scope.oddNumbers = $scope.numbers.Count(n => n % 2 == 1); $scope.firstNumbersLessThan6 = $scope.numbers.TakeWhile(n => n < 6);
Lambda expressions Where $scope.customers.Where(c => c.City == "London");
it will be helped developers to get above functions from the core itself rather than developing their own logic and much user friendly framework everyone loved to use, everything in one place and easy to use.
(Most of) what you describe can be easily achieved with filters. Although, I understand it might be very useful in specific cases, I don't feel like it is something that belongs in core (also considering how easy it is to achieve the same functionality with an external module). Additionally, I don't see how having it implemeted in core would add benefit in regard with performance.
Defining these features/filters in a module and including that as a dependency in any app you might need it, seems to be the way to go. (Publishing the module would also help other developers that might need similar functionality :))
would you be able to give a sample how to achieve this by filters ??? of course if that is the case i would develop myself and publish it here. :)
@lilan123, some things can already be accomplished (either using native JS or existing Angular stuff). Below is a rough version of how I would approach your examples above. There is also this demo fiddle.
There is a chance I have not understood your requirements correctly, so let me know.
(I have kept things ES5-y, but it can get shorter by using ES6 goodies.)
Example 1
---------
Input:
$scope.obj1 = {id: '001', name: 'John'};
$scope.obj2 = [
{empId: '001', employeeType: 'permanent'},
{empId: '002', employeeType: 'permanent'}
];
Output
$scope.obj3 = {id: '001', name: 'John', empId: '001', employeeType: 'permanent'};
Proposed syntax:
obj1 JOIN obj2 | where: obj1.id === obj2.empId
Suggested solution:
Option 1: {} | extend:obj1:(obj2 | filter:{empId: obj1.id}:true)[0]
Option 2: (obj1 | joinWhere:obj2:'@id':'@empId')[0] // <-- to retrieve the first "row"
Implemented filters:
function extendFilter() {
var slice = Array.prototype.slice;
return function _doFilter() {
return angular.extend.apply(null, slice.call(arguments));
};
}
function joinWhereFilter() {
function createValueGetter(value) {
return (angular.isString(value) && (value.charAt(0) === '@')) ?
function (obj) { return obj[value]; } :
function () { return value; };
}
return function _doFilter(obj1, obj2, prop1, prop2) {
var valueGetter1 = createValueGetter(prop1);
var valueGetter2 = createValueGetter(prop2);
var targetValue = valueGetter1(obj1);
var matching = obj2.filter(function (item) { return valueGetter2(item) === targetValue; });
var joined = matching.map(function (item) { return angular.extend({}, obj1, item); });
return joined;
}
}
Example 2
---------
Input:
$scope.obj1 = [
{name: 'Harry', empId: 3415, deptName: 'Finance'},
{name: 'Sally', empId: 2241, deptName: 'Sales'},
{name: 'George', empId: 3401, deptName: 'Finance'}
];
Output:
$scope.obj2 = [
{name: 'Harry', empId: 3415, deptName: 'Finance'},
{name: 'George', empId: 3401, deptName: 'Finance'}
];
Proposed syntax:
obj1 | where: obj1.deptName === 'Finance'
Suggested solution:
obj1 | filter:{deptName: 'Finance'}:true
Example 3
---------
Proposed syntax:
sum(e.salary) e in employees | where: 'e.salary>25000'
Suggested solution:
employees | where:'salary>25000' | sum:'salary'
Implemented filters:
function sumFilter() {
return function _doFilter(arr, prop) {
return arr.reduce(function (acc, item) { return acc + item[prop]; }, 0);
};
}
function whereFilter($parse) {
return function _doFilter(arr, expr) {
var evaluateExprFn = $parse(expr);
return arr.filter(function (item) { return evaluateExprFn(item) === true; });
};
}
Example 4
---------
Input:
$scope.numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0];
Proposed syntax:
$scope.oddNumbers = $scope.numbers.count(n => n % 2 == 1);
$scope.firstNumbersLessThan6 = $scope.numbers.takeWhile(n => n < 6);
$scope.customers.where(c => c.city == "London");
Suggested solution:
$scope.oddNumbers = $scope.numbers.filter(function (n) { return n % 2 === 1; });
$scope.firstNumbersLessThan6 = ... // No easy solution for that (you need more than one line; can write a helper.)
$scope.inLondon = $scope.customers.filter(function (c) { return c.city === 'London'; });
Woow, this is really good... Thanks a lot @gkalpak. well, now it feels like me to do a module here. :)
Based on the latest comment from opener and prior discussion I'm going to close this one as "not in core".
it will be a great feature to have relation algebra and lambda expressions (extended to | orderBy and | filter) to object manipulation in angularJs. Specially it will be helped to developers who worked with third party API and stuff. This will be used all most all.