总结数组中的属性值的更好方法(使用Angularjs)
这些天我开始与Angularjs(真棒:D)合作,我发现了下一个问题:
我有这样的东西:
$scope.traveler = [ { description: 'Senior', Amount: 50}, { description: 'Senior', Amount: 50}, { description: 'Adult', Amount: 75}, { description: 'Child', Amount: 35}, { description: 'Infant', Amount: 25 }, ];
现在有一个总数量这个数组我正在做这样的事情:
$scope.totalAmount = function(){ var total = 0; for (var i = 0; i < $scope.traveler.length; i++) { total = total + $scope.traveler[i].Amount; } return total; }
只有一个数组是很容易的,但是我有其他数组,我想总结一下不同的属性名。
我会更快乐如果我能做到这样的事情:
$scope.traveler.Sum({ Amount });
但是我不知道如何去处理这个问题,以便我今后可以重用它:
$scope.someArray.Sum({ someProperty });
回答
我决定使用@ gruff-bunnybuild议,所以我避免了原型对象 (Array)
我只是对他的答案做了一些修改,validation了数组,sum的值不为null,这是我最后的实现:
$scope.sum = function (items, prop) { if (items == null) { return 0; } return items.reduce(function (a, b) { return b[prop] == null ? a : a + b[prop]; }, 0); };
既然它是一个数组,你可以添加一个函数给数组原型。
traveler = [ { description: 'Senior', Amount: 50}, { description: 'Senior', Amount: 50}, { description: 'Adult', Amount: 75}, { description: 'Child', Amount: 35}, { description: 'Infant', Amount: 25 }, ]; Array.prototype.sum = function (prop) { var total = 0 for ( var i = 0, _len = this.length; i < _len; i++ ) { total += this[i][prop] } return total } console.log(traveler.sum("Amount"))
小提琴: http : //jsfiddle.net/9BAmj/
我知道这个问题有一个公认的答案,但我认为我会用一个替代使用array.reduce ,看到总结一个数组是减less的典型例子:
$scope.sum = function(items, prop){ return items.reduce( function(a, b){ return a + b[prop]; }, 0); }; $scope.travelerTotal = $scope.sum($scope.traveler, 'Amount');
小提琴
只是另一个,这是什么NATIVE JAVASCRIPT函数MAP和REDUCE是build立(地图和减less是在许多语言的强大)。
var traveler = [{description: 'Senior', Amount: 50}, {description: 'Senior', Amount: 50}, {description: 'Adult', Amount: 75}, {description: 'Child', Amount: 35}, {description: 'Infant', Amount: 25}]; function amount(item){ return item.Amount; } function sum(prev, next){ return prev + next; } traveler.map(amount).reduce(sum); // => 235; // or use arrow functions traveler.map(item => item.Amount).reduce((prev, next) => prev + next);
注意 :通过分开更小的function,我们可以再次使用它们。
// Example of reuse. // Get only Amounts greater than 0; // Also, while using Javascript, stick with camelCase. // If you do decide to go against the standards, // then maintain your decision with all keys as in... // {description: 'Senior', Amount: 50} would be // {Description: 'Senior', Amount: 50}; var travelers = [{description: 'Senior', amount: 50}, {description: 'Senior', amount: 50}, {description: 'Adult', amount: 75}, {description: 'Child', amount: 35}, {description: 'Infant', amount: 0 }]; // I changed "Amount" to "amount" to match data. function amount(item){ return item.amount; } travelers.filter(amount); // => [{description: 'Senior', amount: 50}, // {description: 'Senior', amount: 50}, // {description: 'Adult', amount: 75}, // {description: 'Child', amount: 35}]; // Does not include "Infant" as 0 is falsey.
我以为我会放弃我的两分钱:这是那些应该始终是纯粹的function,而不是依赖任何外部variables的操作之一。 有几个已经给出了一个很好的答案,使用reduce
是这里的方式。
由于我们大多数人已经可以使用ES2015的语法,这里是我的主张:
const sumValues = (obj) => Object.keys(obj).reduce((acc, value) => acc + obj[value], 0);
我们正在使它成为一个不可变的函数。 在这里做什么简单的是这样的:从累加器的值为0
开始,并将当前循环项目的值添加到它。
Yayfunction编程和ES2015! 🙂