我有这样的东西:
$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 });
更新后的答案
由于向Array原型添加函数的所有缺点,我正在更新这个答案,以提供一种替代方案,使语法与问题中最初请求的语法相似。
class TravellerCollection extends Array {
sum(key) {
return this.reduce((a, b) => a + (b[key] || 0), 0);
}
}
const traveler = new TravellerCollection(...[
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
]);
console.log(traveler.sum('Amount')); //~> 235
原来的答案
因为它是一个数组,你可以添加一个函数到数组原型。
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/
从对象数组
function getSum(array, column)
let values = array.map((item) => parseInt(item[column]) || 0)
return values.reduce((a, b) => a + b)
}
foo = [
{ a: 1, b: "" },
{ a: null, b: 2 },
{ a: 1, b: 2 },
{ a: 1, b: 2 },
]
getSum(foo, a) == 3
getSum(foo, b) == 6
只是另一种说法,这就是原生JavaScript函数Map和Reduce的用途(Map和Reduce是许多语言中的强大功能)。
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);
注意:通过创建独立的小函数,我们可以再次使用它们。
// 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 }];
// Directly above Travelers array I changed "Amount" to "amount" to match standards.
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.
提高可读性和使用Map和Reduce的替代方案:
const traveler = [
{ description: 'Senior', amount: 50 },
{ description: 'Senior', amount: 50 },
{ description: 'Adult', amount: 75 },
{ description: 'Child', amount: 35 },
{ description: 'Infant', amount: 25 },
];
const sum = traveler
.map(item => item.amount)
.reduce((prev, curr) => prev + curr, 0);
可重用功能:
const calculateSum = (obj, field) => obj
.map(items => items.attributes[field])
.reduce((prev, curr) => prev + curr, 0);