Mejor manera de sumar el valor de una propiedad en una matriz

Resuelto nramirez asked hace 10 años • 20 respuestas

Tengo algo como esto:

$scope.traveler = [
            {  description: 'Senior', Amount: 50},
            {  description: 'Senior', Amount: 50},
            {  description: 'Adult', Amount: 75},
            {  description: 'Child', Amount: 35},
            {  description: 'Infant', Amount: 25 },
];

Ahora, para tener una cantidad total de esta matriz, estoy haciendo algo como esto:

$scope.totalAmount = function(){
       var total = 0;
       for (var i = 0; i < $scope.traveler.length; i++) {
              total = total + $scope.traveler[i].Amount;
            }
       return total;
}

Es fácil cuando solo hay una matriz, pero tengo otras matrices con un nombre de propiedad diferente que me gustaría sumar.

Sería más feliz si pudiera hacer algo como esto:

$scope.traveler.Sum({ Amount });

Pero no sé cómo realizar esto de manera que pueda reutilizarlo en el futuro de esta manera:

$scope.someArray.Sum({ someProperty });
nramirez avatar Apr 23 '14 21:04 nramirez
Aceptado

Sé que esta pregunta tiene una respuesta aceptada, pero pensé en agregar una alternativa que use array.reduce , ya que sumar una matriz es el ejemplo canónico de reducir:

$scope.sum = function(items, prop){
    return items.reduce( function(a, b){
        return a + b[prop];
    }, 0);
};

$scope.travelerTotal = $scope.sum($scope.traveler, 'Amount');

Fiddle

Gruff Bunny avatar Apr 23 '2014 15:04 Gruff Bunny

Utilice reducir con desestructuración para sumar Cantidad:

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));
Expandir fragmento

Patrick Leib avatar Sep 01 '2020 04:09 Patrick Leib

Solo otra toma, para esto nativefunciona JavaScript Mapy Reducepara esto fue creado (Map y Reduce son potencias en muchos idiomas).

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);

Nota : al crear funciones más pequeñas por separado, podemos volver a utilizarlas.

// 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.
SoEzPz avatar Apr 07 '2017 15:04 SoEzPz

Respuesta actualizada

Debido a todas las desventajas de agregar una función al prototipo de Array, estoy actualizando esta respuesta para proporcionar una alternativa que mantenga la sintaxis similar a la sintaxis solicitada originalmente en la pregunta.

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

Respuesta original

Dado que es una matriz, podría agregar una función al prototipo de matriz.

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"))

El violín: http://jsfiddle.net/9BAmj/

bottens avatar Apr 23 '2014 14:04 bottens