suma array agrupar acumulativa javascript arrays prototype-programming

javascript - array - Mejor forma de sumar el valor de una propiedad en una matriz



agrupar array javascript (7)

Solo otra toma, esto es para lo que NATIVE JAVASCRIPT funciona MAP y REDUCE fueron construidas para (Map and 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 hacer funciones más pequeñas por separado, tenemos la posibilidad de usarlas de nuevo.

// 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.

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 resumir.

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

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

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

$scope.someArray.Sum({ someProperty });

Responder

Decidí usar la sugerencia de @ gruff-bunny, así que evité el prototipado del objeto nativo (Array)

Acabo de hacer una pequeña modificación en su respuesta para validar la matriz y el valor para sumar no es nulo, esta es mi implementación final:

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


Como es una matriz, puede agregar una función al prototipo de 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/


No estoy seguro de que esto haya sido mencionado todavía. Pero hay una función lodash para eso. El fragmento debajo de donde el valor es su atributo para sumar es ''valor''.

_.sumBy(objects, ''value''); _.sumBy(objects, function(o) { return o.value; });

Ambos funcionarán.


Pensé en poner mi granito de arena en esto: esta es una de esas operaciones que siempre debe ser puramente funcional, sin depender de ninguna variable externa. Algunos ya dieron una buena respuesta, usar reduce es el camino a seguir aquí.

Dado que la mayoría de nosotros ya podemos permitirnos usar la sintaxis de ES2015, esta es mi proposición:

const sumValues = (obj) => Object.keys(obj).reduce((acc, value) => acc + obj[value], 0);

Lo estamos haciendo una función inmutable mientras estamos en ello. Lo que se reduce aquí es simplemente esto: comience con un valor de 0 para el acumulador y agregue el valor del elemento en bucle actual.

¡Yay para la programación funcional y ES2015! :)



Siempre evito cambiar el método de prototipo y agregar una biblioteca, así que esta es mi solución:

Usar el método de prototipo Reducir Array es suficiente

// + operator for casting to Number items.reduce((a, b) => +a + +b.price, 0);


también puede usar Array.prototype.forEach()

let totalAmount = 0; $scope.traveler.forEach( data => totalAmount = totalAmount + data.Amount); return totalAmount;