总结数组中的属性值的更好方法(使用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函数MAPREDUCE是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! 🙂