Mam coś takiego:
$scope.traveler = [
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
];
Teraz, aby uzyskać całkowitą kwotę tej tablicy, robię coś takiego:
$scope.totalAmount = function(){
var total = 0;
for (var i = 0; i < $scope.traveler.length; i++) {
total = total + $scope.traveler[i].Amount;
}
return total;
}
Jest to łatwe, gdy jest tylko jedna tablica, ale mam inne tablice z inną nazwą właściwości, które chciałbym zsumować.
Byłbym szczęśliwszy, gdybym mógł zrobić coś takiego:
$scope.traveler.Sum({ Amount });
Ale nie wiem, jak przez to przejść w taki sposób, żebym mógł go ponownie wykorzystać w przyszłości w następujący sposób:
$scope.someArray.Sum({ someProperty });
Odpowiedź
Zdecydowałem się skorzystać z sugestii @ gruff-bunny, więc unikam prototypowania obiektu natywnego (Array)
Właśnie dokonałem niewielkiej modyfikacji jego odpowiedzi, sprawdzając poprawność tablicy, a wartość do zsumowania nie jest zerowa, oto moja ostateczna implementacja:
$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
źródło
źródło
Odpowiedzi:
Zaktualizowana odpowiedź
Ze względu na wszystkie wady dodania funkcji do prototypu Array, aktualizuję tę odpowiedź, aby zapewnić alternatywę, która zachowuje składnię podobną do składni pierwotnie żądanej w pytaniu.
Oryginalna odpowiedź
Ponieważ jest to tablica, możesz dodać funkcję do prototypu Array.
The Fiddle: http://jsfiddle.net/9BAmj/
źródło
Array.prototype
ponieważ może to spowodować uszkodzenie kodu w przyszłości. Dlaczego rozszerzanie obiektów natywnych jest złą praktyką? .Wiem, że to pytanie ma akceptowaną odpowiedź, ale pomyślałem, że poddam się alternatywą, która używa array.reduce , widząc, że sumowanie tablicy jest kanonicznym przykładem redukcji:
Fiddle
źródło
$scope.travelerTotal = $scope.sum($scope.traveler, 'Amount');
na początku funkcję kontrolera?źródło
return Number(item.Amount);
sprawdzić tylko numerprev
w funkcji redukuj. Dla mnie oznacza to, że otrzymujesz poprzednią wartość w tablicy. Ale tak naprawdę jest to redukcja wszystkich poprzednich wartości. Lubięaccumulator
,aggregator
lubsumSoFar
dla jasności.Zawsze unikam zmiany metody prototypu i dodawania biblioteki, więc takie jest moje rozwiązanie:
Wystarczy użyć metody prototypowej redukcji Array
źródło
a
) załatwia sprawę, gdy jest używanyreduce
z obiektami: w pierwszej iteracjia
nie będzie pierwszym obiektemitems
tablicy, zamiast tego będzie0
.const sumBy = (items, prop) => items.reduce((a, b) => +a + +b[prop], 0);
Zastosowanie:sumBy(traveler, 'Amount') // => 235
reduce
składnia wydaje mi się całkowicie tępa. Mój mózg nadal „natywnie” to rozumie lepiej:let total = 0; items.forEach((item) => { total += item.price; });
let total = 0; items.forEach(item => total += item.price)
Pomyślałem, że zrzucę na to moje dwa grosze: jest to jedna z tych operacji, które zawsze powinny być czysto funkcjonalne, nie polegające na żadnych zewnętrznych zmiennych. Kilku dało już dobrą odpowiedź, używając
reduce
jest sposobem, aby przejść tutaj.Ponieważ większość z nas może już sobie pozwolić na używanie składni ES2015, oto moja propozycja:
Robimy z tego niezmienną funkcję, gdy jesteśmy na tym. To,
reduce
co tutaj robi, jest po prostu następujące: Rozpocznij od wartości0
dla akumulatora i dodaj do niego wartość bieżącej zapętlonej pozycji.Yay za programowanie funkcjonalne i ES2015! :)
źródło
Alternatywa dla lepszej czytelności i używania
Map
orazReduce
:Funkcja wielokrotnego użytku:
źródło
.reduce(*** => *** + ***, 0);
której brakowało innym, że „+1”Możesz wykonać następujące czynności:
źródło
Działa na mnie
TypeScript
iJavaScript
:Mam nadzieję, że jest przydatny.
źródło
Nie jestem pewien, czy zostało to jeszcze wspomniane. Ale jest do tego funkcja lodash . Fragment poniżej, gdzie wartość jest atrybutem do zsumowania, to „wartość”.
Oba będą działać.
źródło
można również użyć Array.prototype.forEach ()
źródło
Oto jednowierszowy wykorzystujący funkcje strzałek ES6.
źródło
Jak podsumować tablicę obiektów za pomocą JavaScript
źródło
Z tablicy obiektów
źródło
Używałem już jquery. Ale myślę, że jest na tyle intuicyjny, że wystarczy:
To jest po prostu krótka wersja odpowiedzi @ akhouri.
źródło
Oto rozwiązanie, które uważam za bardziej elastyczne:
Aby otrzymać sumę, użyj jej w ten sposób:
źródło