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 pasar por 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 evito crear prototipos de objetos nativos (Array)
Acabo de hacer una pequeña modificación a su respuesta validando 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);
};
javascript
arrays
prototype-programming
nramirez
fuente
fuente
Respuestas:
Respuesta actualizada
Debido a todas las desventajas de agregar una función al prototipo de matriz, estoy actualizando esta respuesta para proporcionar una alternativa que mantenga la sintaxis similar a la sintaxis solicitada originalmente en la pregunta.
Respuesta original
Como es una matriz, puede agregar una función al prototipo de matriz.
El violín: http://jsfiddle.net/9BAmj/
fuente
Array.prototype
ya que podría romper su código en el futuro. ¿Por qué extender objetos nativos es una mala práctica? .Sé que esta pregunta tiene una respuesta aceptada, pero pensé en incorporar una alternativa que usa array.reduce , ya que sumar una matriz es el ejemplo canónico para reducir:
Fiddle
fuente
$scope.travelerTotal = $scope.sum($scope.traveler, 'Amount');
al principio de la función del controlador?fuente
return Number(item.Amount);
para verificar solo el númeroprev
en la función reducir. Para mí, eso implica que está obteniendo el valor anterior en la matriz. Pero realmente es la reducción de todos los valores anteriores. Me gustaaccumulator
,aggregator
osumSoFar
por claridad.Siempre evito cambiar el método del prototipo y agregar la biblioteca, así que esta es mi solución:
Usar el método de prototipo de reducción de matriz es suficiente
fuente
a
) hace el truco cuando se usareduce
con objetos: en la primera iteración,a
no será el primer objeto de laitems
matriz, sino que lo será0
.const sumBy = (items, prop) => items.reduce((a, b) => +a + +b[prop], 0);
Uso:sumBy(traveler, 'Amount') // => 235
reduce
sintaxis me parece totalmente obtusa. Mi cerebro todavía "nativamente" entiende esto mejor:let total = 0; items.forEach((item) => { total += item.price; });
let total = 0; items.forEach(item => total += item.price)
Pensé en dejar mis dos centavos en esto: esta es una de esas operaciones que siempre debe ser puramente funcional, no depender de ninguna variable externa. Algunos ya dieron una buena respuesta, usando
reduce
es el camino a seguir aquí.Como la mayoría de nosotros ya podemos permitirnos usar la sintaxis ES2015, esta es mi propuesta:
Lo estamos haciendo una función inmutable mientras estamos en ello. Qué
reduce
está haciendo aquí es simplemente esto: comience con un valor de0
para el acumulador y agregue el valor del elemento en bucle actual.¡Yay para programación funcional y ES2015! :)
fuente
Alternativa para mejorar la legibilidad y el uso
Map
yReduce
:Función reutilizable:
fuente
.reduce(*** => *** + ***, 0);
otros le faltaba ese "+1"Puedes hacer lo siguiente:
fuente
Me está funcionando en
TypeScript
yJavaScript
:Espero sea de utilidad.
fuente
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'.
Ambos funcionarán.
fuente
también puede usar Array.prototype.forEach ()
fuente
Aquí hay una línea usando las funciones de flecha ES6.
fuente
Cómo sumar una matriz de objetos usando Javascript
fuente
De una matriz de objetos
fuente
Ya estaba usando jquery. Pero creo que es lo suficientemente intuitivo como para tener:
Esto es básicamente una versión abreviada de la respuesta de @ akhuri.
fuente
Aquí hay una solución que encuentro más flexible:
Para obtener la suma, simplemente úsela así:
fuente