Eu tenho algo parecido com isto:
$scope.traveler = [
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
];
Agora, para ter uma quantidade total dessa matriz, estou fazendo algo assim:
$scope.totalAmount = function(){
var total = 0;
for (var i = 0; i < $scope.traveler.length; i++) {
total = total + $scope.traveler[i].Amount;
}
return total;
}
É fácil quando existe apenas uma matriz, mas tenho outras matrizes com um nome de propriedade diferente que gostaria de somar.
Eu ficaria mais feliz se eu pudesse fazer algo assim:
$scope.traveler.Sum({ Amount });
Mas não sei como passar por isso de uma maneira que possa reutilizá-lo no futuro assim:
$scope.someArray.Sum({ someProperty });
Responda
Decidi usar a sugestão @ gruff-bunny, para evitar a criação de protótipos de objetos nativos (Array)
Eu apenas fiz uma pequena modificação na resposta dele validando a matriz e o valor a somar não é nulo, esta é minha implementação 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
fonte
fonte
Respostas:
Resposta atualizada
Devido a todas as desvantagens de adicionar uma função ao protótipo Array, estou atualizando esta resposta para fornecer uma alternativa que mantenha a sintaxe semelhante à sintaxe originalmente solicitada na pergunta.
Resposta original
Como é uma matriz, você pode adicionar uma função ao protótipo da matriz.
The Fiddle: http://jsfiddle.net/9BAmj/
fonte
Array.prototype
pois isso pode quebrar seu código no futuro. Por que estender objetos nativos é uma má prática? .Eu sei que esta pergunta tem uma resposta aceita, mas pensei em usar uma alternativa que usa array.reduce , visto que somar uma matriz é o exemplo canônico de reduzir:
Fiddle
fonte
$scope.travelerTotal = $scope.sum($scope.traveler, 'Amount');
no início da função do controlador?fonte
return Number(item.Amount);
para verificar se há número sóprev
na função de redução. Para mim, isso implica que você está obtendo o valor anterior na matriz. Mas na verdade é a redução de todos os valores anteriores. Eu gostoaccumulator
,aggregator
ousumSoFar
para maior clareza.Eu sempre evito alterar o método do protótipo e adicionar a biblioteca, então esta é a minha solução:
O uso do método de protótipo de redução de matriz é suficiente
fonte
a
) faz o truque ao usarreduce
objetos: na primeira iteração,a
não será o primeiro objeto daitems
matriz, mas sim0
.const sumBy = (items, prop) => items.reduce((a, b) => +a + +b[prop], 0);
Uso:sumBy(traveler, 'Amount') // => 235
reduce
sintaxe parece totalmente obtusa para mim. Meu cérebro ainda "nativamente" entende isso melhor:let total = 0; items.forEach((item) => { total += item.price; });
let total = 0; items.forEach(item => total += item.price)
Eu pensei em colocar meus dois centavos nisso: essa é uma daquelas operações que sempre devem ser puramente funcionais, sem depender de variáveis externas. Alguns já deram uma boa resposta, usando
reduce
é o caminho a percorrer aqui.Como a maioria de nós já pode se dar ao luxo de usar a sintaxe do ES2015, aqui está minha proposta:
Estamos criando uma função imutável enquanto estamos nisso. O que
reduce
está fazendo aqui é simplesmente o seguinte: Comece com um valor de0
para o acumulador e adicione o valor do item em loop atual a ele.Yay para programação funcional e ES2015! :)
fonte
Alternativa para melhorar a legibilidade e usar
Map
eReduce
:Função reutilizável:
fonte
.reduce(*** => *** + ***, 0);
que faltava aos outros que "+1"Você pode fazer o seguinte:
fonte
Está trabalhando para mim
TypeScript
eJavaScript
:Espero que seja útil.
fonte
Não sei se isso foi mencionado ainda. Mas há uma função lodash para isso. O snippet abaixo de onde value é seu atributo, a soma é 'value'.
Ambos irão funcionar.
fonte
também pode usar Array.prototype.forEach ()
fonte
Aqui está uma linha única usando as funções de seta ES6.
fonte
Como somar matriz de objeto usando Javascript
fonte
Da matriz de objetos
fonte
Eu já estava usando jquery. Mas acho que é intuitivo o suficiente para ter:
Esta é basicamente apenas uma versão abreviada da resposta de @ akhouri.
fonte
Aqui está uma solução que acho mais flexível:
Para obter a soma, basta usá-lo assim:
fonte