Problem
Here’s an example of what I’m talking about:
$scope.traveler = [
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
];
Now to have a total Amount of this array I’m doing something like this:
$scope.totalAmount = function(){
var total = 0;
for (var i = 0; i < $scope.traveler.length; i++) {
total = total + $scope.traveler[i].Amount;
}
return total;
}
It’s simple when there’s only one array, however I’d like to sum multiple arrays, each with a different property name.
If I could do anything like this, I’d be much happier:
$scope.traveler.Sum({ Amount });
But I’m not sure how to go about doing this in such a way that I can reuse it in the future:
$scope.someArray.Sum({ someProperty });
Asked by nramirez
Solution #1
I’m aware that there is an established answer to this topic, but I thought I’d offer an option that makes use of array. reduce, since the canonical example of reduce is summing an array:
$scope.sum = function(items, prop){
return items.reduce( function(a, b){
return a + b[prop];
}, 0);
};
$scope.travelerTotal = $scope.sum($scope.traveler, 'Amount');
Fiddle
Answered by Gruff Bunny
Solution #2
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.
Answered by SoEzPz
Solution #3
Updated Answer
Because of the drawbacks of adding a function to the Array prototype, I’m revising this response to propose an option that maintains the syntax desired in the query.
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
Original Answer
You could add a function to the Array prototype because it’s an array.
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"))
The Fiddle: http://jsfiddle.net/9BAmj/
Answered by bottens
Solution #4
I always try to avoid modifying prototype methods and adding libraries, so here’s what I’ve come up with:
It is sufficient to use the reduce Array prototype function.
// + operator for casting to Number
items.reduce((a, b) => +a + +b.price, 0);
Answered by Eric Marcelino
Solution #5
To sum, combine reduction and destructuring. Amount:
const traveler = [
{ description: 'Senior', Amount: 50 },
{ description: 'Senior', Amount: 50 },
{ description: 'Adult', Amount: 75 },
{ description: 'Child', Amount: 35 },
{ description: 'Infant', Amount: 25 },
];
console.log(traveler.reduce((n, {Amount}) => n + Amount, 0))
Answered by Patrick Leib
Post is based on https://stackoverflow.com/questions/23247859/better-way-to-sum-a-property-value-in-an-array