Angesichts eines Arrays [1, 2, 3, 4]
Wie kann ich die Summe seiner Elemente finden? (In diesem Fall würde die Summe lauten 10
.)
Ich dachte $.each
könnte nützlich sein, aber ich bin mir nicht sicher, wie man es implementiert.
Angesichts eines Arrays [1, 2, 3, 4]
Wie kann ich die Summe seiner Elemente finden? (In diesem Fall würde die Summe lauten 10
.)
Ich dachte $.each
könnte nützlich sein, aber ich bin mir nicht sicher, wie man es implementiert.
Das wäre genau der richtige Job für reduce
.
Wenn Sie ECMAScript 2015 verwenden (auch bekannt als ECMAScript 6 ):
const sum = [1, 2, 3].reduce((partialSum, a) => partialSum + a, 0);
console.log(sum); // 6
Für ältere JS:
const sum = [1, 2, 3].reduce(add, 0); // with initial value to avoid when the array is empty
function add(accumulator, a) {
return accumulator + a;
}
console.log(sum); // 6
Ist das nicht schön? :-)
Wenn wir davon ausgehen, dass wir alle ES2015 verwenden, können wir es weniger ausführlich machen: [1, 2, 3].reduce((a,b)=>a+b)
Ich würde ja abstimmen, aber es ist wirklich hübsch, wenn man schon "1234" Bewertungen hat.
Eigentlich wäre es in Lisp effizienter, wenn man (apply #'+ '(1 2 3))
. Ich bin überrascht, dass man in JavaScript nicht dasselbe tun kann. Ich dachte, wenn ich kann Math.max.apply(Math,[-12,-3.33,11,0,1])
warum dann nicht Math.sum.apply(Math,[-12,-3.33,11,0,1])
?
Array.prototype.reduce kann verwendet werden, um das Array zu durchlaufen und den aktuellen Elementwert zur Summe der vorherigen Elementwerte zu addieren.
console.log(
[1, 2, 3, 4].reduce((a, b) => a + b, 0)
)
console.log(
[].reduce((a, b) => a + b, 0)
)
Sie erhalten einen TypeError
console.log(
[].reduce((a, b) => a + b)
)
console.log(
[1,2,3].reduce(function(acc, val) { return acc + val; }, 0)
)
console.log(
[].reduce(function(acc, val) { return acc + val; }, 0)
)
Wenn Nicht-Zahlen als Eingaben möglich sind, möchten Sie das vielleicht behandeln?
console.log(
["hi", 1, 2, "frog"].reduce((a, b) => a + b)
)
let numOr0 = n => isNaN(n) ? 0 : n
console.log(
["hi", 1, 2, "frog"].reduce((a, b) =>
numOr0(a) + numOr0(b))
)
Wir können verwenden eval um eine Zeichenfolgendarstellung von JavaScript-Code auszuführen. Mit der Funktion Array.prototype.join, die das Array in eine Zeichenkette umwandelt, ändern wir [1,2,3] in "1+2+3", was 6 ergibt.
console.log(
eval([1,2,3].join('+'))
)
//This way is dangerous if the array is built
// from user input as it may be exploited eg:
eval([1,"2;alert('Malicious code!')"].join('+'))
Natürlich ist die Anzeige einer Warnung nicht das Schlimmste, was passieren kann. Ich habe dies nur als Antwort auf Ortunds Frage aufgenommen, da ich nicht glaube, dass sie geklärt wurde.
Sie wissen doch, dass dieser Zauber mit reduce()
ist immer noch 25-30% langsamer als ein einfaches indiziertes for()
Schleife nach langen Jahren? jsperf.com/reduce-vs-loop/4
IE8 unterstützt es nicht, und es sieht nicht so aus, als ob jQuery beabsichtigt, es hinzuzufügen. Allerdings hat Prototype es.
@Ishmael, Sie können UnderscoreJS verwenden, das auf die Browser-Implementierung zurückgreift, wenn diese verfügbar ist, oder andernfalls seine eigene implementiert.
Sehr schön. Mit Blick auf die Ausführungszeittest von Riking, reduce
scheint ebenfalls sehr effizient zu sein.
@Sprog: Allerdings ist die Verwendung von (var i=0; i<arr.length; i++)
ist noch schneller. Und selbst dann, wenn man var sum=0; var i=arr.length; while(i--) sum += arr[i]
ist sogar noch schneller.
Bitte, bitte, bitte verwenden Sie die Antwort mit reduce
unten; deklarieren Sie keine veränderbaren Variablen, wenn Sie nicht müssen.
Bitte verwenden Sie diese nicht, auch wenn sie die "akzeptierte Antwort" ist; die Antwort von Florian unten ist viel besser!
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
37 Stimmen
@tereško Unlust zu googeln ist kein gültiger Abschlussgrund auf Stackoverflow. Bitte stimmen Sie ab, wenn Sie das Gefühl haben, dass die Frage nicht gut (re)gesucht ist. (Auch nach den Antworten zu urteilen, scheint dies ein sehr kontroverses Thema mit vielen möglichen Lösungen zu sein, einschließlich einiger sehr hoch bewerteter schlechter Praktiken (eval) - überraschenderweise).
13 Stimmen
Hinweis: Die meisten Antworten hier berechnen im Wesentlichen
a[0] + a[1] + ...
was sich in eine String-Verkettung verwandeln kann, wenn das Array Nicht-Zahlen-Elemente enthält. z.B.['foo', 42].reduce((a,b)=>a+b, 0) === "0foo42"
.4 Stimmen
Kein eingebauter Reducer, den man in Array.reduce einspeisen könnte? Ich dachte an etwas wie
[1,2,3].reduce(Math.sum)
.