So finden Sie die Summe eines Arrays von Zahlen


808

[1, 2, 3, 4]Wie kann ich bei einem Array die Summe seiner Elemente finden? (In diesem Fall wäre die Summe 10.)

Ich dachte, es $.eachkönnte nützlich sein, bin mir aber nicht sicher, wie ich es implementieren soll.


4
Diese Frage wird derzeit diskutiert
Madaras Geist

18
@ tereško Die Unwilligkeit gegenüber Google ist kein gültiger enger Grund für Stackoverflow. Bitte stimmen Sie ab, wenn Sie der Meinung sind, dass die Frage nicht gut (erneut) gesucht wird. (Auch nach den Antworten zu urteilen - dies scheint ein sehr kontroverses Thema mit vielen möglichen Lösungen zu sein, einschließlich einiger hoch bewerteter schlechter Praktiken (Bewertung) - überraschenderweise.)
Trilarion

8
Hinweis: Die meisten Antworten hier berechnen im Wesentlichen a[0] + a[1] + ..., was zu einer Verkettung von Zeichenfolgen führen kann, wenn das Array nicht nummerierte Elemente enthält. ZB ['foo', 42].reduce((a,b)=>a+b, 0) === "0foo42".
Beni Cherniavsky-Paskin

Kein eingebauter Reduzierer, den man Array.reduce zuführen könnte? Ich denke so etwas wie [1,2,3].reduce(Math.sum).
Phil

Antworten:


544

Empfohlen (mit Standardwert reduzieren)

Array.prototype.reduce kann verwendet werden, um das Array zu durchlaufen und den aktuellen Elementwert zur Summe der vorherigen Elementwerte hinzuzufügen.

console.log(
  [1, 2, 3, 4].reduce((a, b) => a + b, 0)
)
console.log(
  [].reduce((a, b) => a + b, 0)
)

Ohne Standardwert

Sie erhalten einen TypeError

console.log(
  [].reduce((a, b) => a + b)
)

Vor den Pfeilfunktionen von ES6

console.log(
  [1,2,3].reduce(function(acc, val) { return acc + val; }, 0)
)

console.log(
  [].reduce(function(acc, val) { return acc + val; }, 0)
)

Nicht nummerierte Eingänge

Wenn Nicht-Zahlen mögliche Eingaben sind, möchten Sie vielleicht damit umgehen?

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))
)

Nicht empfohlene gefährliche Bewertung

Wir können eval verwenden , um eine Zeichenfolgendarstellung von JavaScript-Code auszuführen. Mit der Funktion Array.prototype.join zum Konvertieren des Arrays in einen String ä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('+'))

Das Anzeigen einer Warnung ist natürlich nicht das Schlimmste, was passieren kann. Der einzige Grund, warum ich dies aufgenommen habe, ist die Beantwortung von Ortunds Frage, da ich nicht glaube, dass sie geklärt wurde.


8
Sie wissen, dass diese Magie mit nach langen Jahren reduce()immer noch 25-30% langsamer ist als eine einfache indizierte for()Schleife? jsperf.com/reduce-vs-loop/4
tevemadar

Dies stößt übrigens auf Probleme, wenn die Zahl "0" ist - sie kann aus irgendeinem Grund als Zeichenfolge interpretiert werden. Das Hinzufügen von 1 * a + 1 * b hat bei mir funktioniert. Was die Geschwindigkeit angeht, war dies einfacher zu schreiben und mir ist die Geschwindigkeit egal
Peter Kay

1179

In Lisp wäre dies genau der richtige Job reduce. Sie würden diese Art von Code sehen:

(reduce #'+ '(1 2 3)) ; 6

Zum Glück haben wir in JavaScript auch reduce! Leider +ist ein Operator keine Funktion. Aber wir können es hübsch machen! Hier, schau:

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 hübsch? :-)

Noch besser! Wenn Sie ECMAScript 2015 (auch bekannt als ECMAScript 6 ) verwenden, kann dies so hübsch sein:

const sum = [1, 2, 3].reduce((partial_sum, a) => partial_sum + a,0); 
console.log(sum); // 6

28
Angenommen, wir alle verwenden ES2015, können wir es weniger ausführlich machen:[1, 2, 3].reduce((a,b)=>a+b)
Denys Séguret

1
Ich frage mich, ob die Ausführungszeit von Reduzieren mit einer Funktion (a, b) mit einer manuellen Iteration und Summierung vergleichbar ist oder ob ein erheblicher Overhead enthalten ist.
Trilarion

1
Ich glaube, es ist erwähnenswert, dass die Antwort tatsächlich auf der Seite zu finden ist, die Sie verlinkt haben: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Alex Cohn

2
Ich würde Array einige Methoden hinzufügen:Array.prototype.sum = function() { return this.reduce((a,b) => a+b, 0); } Array.prototype.avg = function() { return this.reduce((a,b) => a+b, 0)/this.length; }
Pilat

2
@Black reduziert ein Array auf einen einzigen Wert.
Florian Margaine

205

Warum nicht reduzieren? Es ist normalerweise etwas kontraintuitiv, aber es ist ziemlich einfach, es zu verwenden, um eine Summe zu finden:

var a = [1,2,3];
var sum = a.reduce(function(a, b) { return a + b; }, 0);

3
IE8 unterstützt es nicht und es sieht nicht so aus, als ob jQuery beabsichtigt, es hinzuzufügen. Prototype hat es jedoch.
Ishmael Smyrnow

4
@Ishmael, Sie können UnderscoreJS verwenden, das auf die Implementierung des Browsers zurückgreift, sofern verfügbar, oder auf andere Weise implementiert.
Pablo Diaz

3
Was ist kontraintuitiv reduce()?
Kanon

3
@ s4nji Array.prototype.reduce() reduziert ein Array auf einen einzelnen Rückgabewert.
Kanon

6
@ s4nji ... es sei denn, Sie reduzieren eine Sauce - in diesem Fall reduzieren Sie sie auf das Wesentliche, dh die Summe aller Aromen ohne das Wasser über dem Kopf. :-)
CB Du Rietz

97
var arr = [1,2,3,4];
var total=0;
for(var i in arr) { total += arr[i]; }

3
Dies ist viel schneller als die obige Lösung jQuery.each ().
Dan

41
@Sprog: Die Verwendung (var i=0; i<arr.length; i++)ist jedoch noch schneller. Und selbst dann ist die Verwendung var sum=0; var i=arr.length; while(i--) sum += arr[i]noch schneller.
Riking

14
Die Verwendung von for... inSchleifen für Arrays funktioniert in diesem Fall zufällig und weil Arrays Objekte erweitern. Rikings Lösung ist besser
Benjamin Gruenbaum

2
@BenjaminGruenbaum vorausgesetzt, dass nichts dem Prototyp des Arrays unzählige Eigenschaften hinzugefügt hat ...
Canon

1
@YSC nein, das tut es nicht. Eine for...inSchleife in JavaScript nimmt die Indizes auf, was ein häufiger Stolperstein für Codierer ist, die erwarten, die Werte zu erhalten. (Versuchen Sie es for(var i in [1,2,3]) { console.log(i); }in einer Konsole.)
Amber

61
var total = 0;
$.each(arr,function() {
    total += this;
});

87
Bitte, bitte, bitte benutze die Antwort mit reduceunten; Deklarieren Sie keine veränderlichen Variablen, wenn Sie keine haben.
Bruno Grieder

9
Diese Antwort wird derzeit diskutiert
Madaras Geist

11
Bitte verwenden Sie dies nicht, obwohl es die "akzeptierte Antwort" ist; Die Antwort von Florian unten ist viel besser!
Andy Sinclair

12
@BrunoGrieder "Deklariere keine veränderlichen Vars, wenn du nicht musst" ist eine extrem voreingenommene Meinung über eine imperative Sprache , es ist kaum ein Code-Geruch in irgendeiner Weise. An Tylers Antwort ist absolut nichts auszusetzen, und der einzige Unterschied zwischen Tylers und Florians ist der Stil.
Rob

5
Von OP: Ich dachte, $ .each könnte nützlich sein, bin mir aber nicht sicher, wie ich es implementieren soll. Dies ist vielleicht nicht die beste, aber beantworten Sie die Anfrage des OP.


29

Dies ist möglich, indem alle Elemente sumdurchlaufen und bei jeder Iteration zu einer Variablen hinzugefügt werden.

var array = [1, 2, 3];

for (var i = 0, sum = 0; i < array.length; sum += array[i++]);

JavaScript kennt das Block-Scoping nicht und ist daher sumzugänglich:

console.log(sum); // => 6

Das gleiche wie oben, jedoch als einfache Funktion kommentiert und vorbereitet:

function sumArray(array) {
  for (
    var
      index = 0,              // The iterator
      length = array.length,  // Cache the array length
      sum = 0;                // The total amount
      index < length;         // The "for"-loop condition
      sum += array[index++]   // Add number on each iteration
  );
  return sum;
}

12
Obwohl klug, würde ich Code, der sumaußerhalb der Schleife deklariert , viel besser lesbar finden.
Beni Cherniavsky-Paskin

@ BeniCherniavsky-Paskin Ja, das gleiche hier ... Ich weiß nicht, warum ich es an diesem Tag so gemacht habe ... Aber ich werde es so lassen, wie es ist! Es ist nur ein Beispiel, wie wir könnten ... ;)
Yckart

Seit ES6 kennt Javascript Block Scoping mit constund let. Sie können also sumaußerhalb der forSchleife als deklarieren let sum = 0;. Sie können die Array-Länge auch vor der Schleife alsconst length = array.length;
KSK

23
arr.reduce(function (a, b) {
    return a + b;
});

Referenz: Array.prototype.reduce ()


6
Dies wird fehlschlagen, wenn dies der Fall arrist [].

7
Fügen Sie einen Standardwert hinzu, wie arr.reduce(function (a, b) { return a + b; }, 0);
folgt

15
// Given array 'arr'
var i = arr.length;
var sum = 0;
while (--i) sum += arr[i];

Dies dauert durchschnittlich 1,57 ms / Lauf (gemessen über 1000 Läufe auf einem Array von 100 zufälligen Normalzahlen), verglichen mit 3,604 ms / Lauf mit der eval()obigen Methode und 2,151 ms / Lauf mit einem Standard für (i, Länge, ++) ) Schleife.

Hinweis zur Methodik: Dieser Test wurde auf einem Google Apps Script-Server ausgeführt, sodass die Javascript-Engines weitgehend mit denen von Chrome identisch sind.

BEARBEITEN: --ianstatt i--0,12 ms pro Lauf zu speichern (i-- ist 1,7)

EDIT: Holy Expletive, egal diesen ganzen Beitrag. Verwenden Sie die oben erwähnte Methode redu (), sie beträgt nur 1 ms / Lauf.


1
Ich liebe die Timings, die du benutzt hast. Ihre Antwort lautet nicht nur "Such mich aus, ich bin der Beste!" Es zeigt uns stattdessen warum . Wie auch immer, das while (--i) do_somethingkönnte auch für andere Dinge funktionieren.
Redwolf Programme

var sum = arr[0]
Noobninja


12

Wer sucht einen funktionierenden Oneliner wie mich? Nimm das:

sum= arr.reduce(function (a, b) {return a + b;}, 0);

Sie können einen Anfangswert für Reduzieren als 2. Parameter hinzufügen:arr.reduce(function(a, b) { return a + b;}, 0);
Ngz

Vielen Dank! Ich werde das einbauen.
Geek-Merlin

12

Lustiger Ansatz:

eval([1,2,3].join("+"))

5
Könnten Sie diese Antwort bitte erweitern, indem Sie erklären, was in diesem Code passiert? Warum funktioniert es? Was macht es genau? Diese Dinge tragen dazu bei, die Qualität der Antwort zu verbessern.
Ortund

@ user40521 hat dies bereits so beantwortet, wie ich denke. Ich habe es nicht gesehen.
Elektron

Dies ist zwar kurz und bündig und sicherlich interessant, aber auch sehr ineffizient. Die Verwendung reduceist in den meisten, wenn nicht allen Fällen definitiv vorzuziehen.
Ninjakannon

Errm,[1,"2;YourProgram.ripToShreds();3",4]
Redwolf Programme

Also bekomme ich NaNbeim Versuch eine eval(['alert("removing your computer")',2,3].join("+"))falsche Antwort 0/10
pie6k

12

OK, stellen Sie sich vor, Sie haben dieses Array unten:

const arr = [1, 2, 3, 4];

Lassen Sie uns viele verschiedene Möglichkeiten untersuchen , da ich hier keine umfassende Antwort finden konnte:

1) Verwenden der integrierten Reduktion ()

function total(arr) {
  if(!Array.isArray(arr)) return;
  return arr.reduce((a, v)=>a + v);
}

2) Verwenden der for-Schleife

function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0;
  for (let i=0,l=arr.length; i<l; i++) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

3) Verwenden der while-Schleife

function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0, i=-1;
  while (++i < arr.length) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

4) Verwenden des Arrays forEach

function total(arr) {
  if(!Array.isArray(arr)) return;
  let sum=0;
  arr.forEach(each => {
    sum+=each;
  });
  return sum;
};

und nenne es so:

total(arr); //return 10

Es wird nicht empfohlen, einen solchen Prototyp für Array zu erstellen ...


10

Eine Standard-JavaScript-Lösung:

var addition = [];
addition.push(2);
addition.push(3);

var total = 0;
for (var i = 0; i < addition.length; i++)
{
    total += addition[i];
}
alert(total);          // Just to output an example
/* console.log(total); // Just to output an example with Firebug */

Das funktioniert bei mir (das Ergebnis sollte 5 sein). Ich hoffe, dass diese Art von Lösung keinen versteckten Nachteil hat.


1
Auch jeder C- oder Java-Programmierer könnte dies verstehen.
Audrius Meskauskas

Für den einfachen Zweck, alle Werte zusammenzufassen, hat die einfache einfache alte for-Schleife keine Rivalen in Bezug auf die Ausführungszeit
am

Das einzige Problem ist, es ist ein bisschen ärgerlich, wenn Sie 20 for-Schleifen haben, die alle ineinander verschachtelt sind
Redwolf Programs

7
var totally = eval(arr.join('+'))

Auf diese Weise können Sie alle Arten von exotischen Dingen in das Array aufnehmen.

var arr = ['(1/3)','Date.now()','foo','bar()',1,2,3,4]

Ich scherze nur halb.


26
Ich bin halb lachend
caub

eval(['alert("removing your computer")',2,3].join("+"))
Pie6k

7

Ich bin ein Anfänger mit JavaScript und Codierung im Allgemeinen, aber ich fand, dass eine einfache und einfache Möglichkeit, die Zahlen in einem Array zu summieren, folgendermaßen ist:

    var myNumbers = [1,2,3,4,5]
    var total = 0;
    for(var i = 0; i < myNumbers.length; i++){
        total += myNumbers[i];
    }

Grundsätzlich wollte ich dazu beitragen, weil ich nicht viele Lösungen gesehen habe, die keine integrierten Funktionen verwenden, und diese Methode ist einfach zu schreiben und zu verstehen.


1
Wie unterscheidet sich das von dieser Antwort von 2012 oder dieser Antwort von 2014 ? Es gibt zwei Lösungen, die Sie nicht gesehen haben.
Dan Dascalescu

5

Ein kurzes Stück JavaScript-Code würde diesen Job erledigen:

var numbers = [1,2,3,4];
var totalAmount = 0;

for (var x = 0; x < numbers.length; x++) {

    totalAmount += numbers[x];
}

console.log(totalAmount); //10 (1+2+3+4)

5

Einige Leute haben vorgeschlagen, eine .sum()Methode zum hinzuzufügen Array.prototype. Dies wird im Allgemeinen als schlechte Praxis angesehen, daher schlage ich nicht vor, dass Sie es tun.

Wenn Sie immer noch darauf bestehen, ist dies eine prägnante Schreibweise:

Array.prototype.sum = function() {return [].reduce.call(this, (a,i) => a+i, 0);}

dann: [1,2].sum(); // 3

Beachten Sie, dass die dem Prototyp hinzugefügte Funktion eine Mischung aus ES5- und ES6-Funktion und Pfeilsyntax verwendet. Das functionwird deklariert, damit die Methode den thisKontext von dem Arrayabrufen kann, mit dem Sie arbeiten. Ich habe das der =>Kürze halber innerhalb des reduceAnrufs verwendet.


5

Verwenden Sie eine forSchleife:

const array = [1, 2, 3, 4];
let result = 0;

for (let i = 0; i < array.length - 1; i++) {
  result += array[i];
}

console.log(result); // Should give 10

Oder sogar eine forEachSchleife:

const array = [1, 2, 3, 4];
let result = 0;

array.forEach(number => {
  result += number;
})

console.log(result); // Should give 10

Verwenden Sie zur Vereinfachung reduce:

const array = [10, 20, 30, 40];
const add = (a, b) => a + b
const result = array.reduce(add);

console.log(result); // Should give 100

4

Keine Notwendigkeit initial value! Denn wenn no übergeben initial valuewird, wird das callback functionnicht für das erste Element der Liste aufgerufen, und das erste Element wird stattdessen als übergeben initial value. Sehr gute Funktion :)

[1, 2, 3, 4].reduce((a, x) => a + x) // 10
[1, 2, 3, 4].reduce((a, x) => a * x) // 24
[1, 2, 3, 4].reduce((a, x) => Math.max(a, x)) // 4
[1, 2, 3, 4].reduce((a, x) => Math.min(a, x)) // 1

4

Hier ist eine elegante Einzeilerlösung, die einen Stapelalgorithmus verwendet . Es kann jedoch einige Zeit dauern, bis Sie die Schönheit dieser Implementierung verstanden haben.

const getSum = arr => (arr.length === 1) ? arr[0] : arr.pop() + getSum(arr);

getSum([1, 2, 3, 4, 5]) //15

Grundsätzlich akzeptiert die Funktion ein Array und prüft, ob das Array genau ein Element enthält. Wenn false, wird das letzte Element aus dem Stapel entfernt und das aktualisierte Array zurückgegeben.

Das Schöne an diesem Snippet ist, dass die Funktion die arr[0]Überprüfung umfasst , um Endlosschleifen zu verhindern. Sobald das letzte Element erreicht ist, wird die gesamte Summe zurückgegeben.


4

Sie können die Methode redu () mit dem Lambda-Ausdruck kombinieren:

[1, 2, 3, 4].reduce((accumulator, currentValue) => accumulator + currentValue);


3

Ich sah alle Antworten für "reduzieren" Lösung gehen

var array = [1,2,3,4]
var total = 0
for (var i = 0; i < array.length; i++) {
    total += array[i]
}
console.log(total)

3

Richtigkeit

Sortieren Sie das Array und die Startsumme aus den kleinsten Zahlen (Snippet zeigt Unterschied zu Nicht-Sortierung)

[...arr].sort((a,b)=>a-b).reduce((a,c)=>a+c,0)

Für mehrdimensionale Zahlenreihen verwenden arr.flat(Infinity)


2

Coole Tricks hier, ich habe eine gute Wahl mit vielen der sicheren traditionellen Antworten, die nicht die Länge des Arrays zwischenspeichern.

function arraySum(array){
  var total = 0,
      len = array.length;

  for (var i = 0; i < len; i++){
    total += array[i];
  }

  return total;
};

var my_array = [1,2,3,4];

// Returns 10
console.log( arraySum( my_array ) );

Ohne die Länge des Arrays zwischenzuspeichern, muss der JS-Compiler das Array bei jeder Iteration der Schleife durchlaufen, um die Länge zu berechnen. In den meisten Fällen ist dies kein unnötiger Overhead. V8 und viele moderne Browser optimieren dies für uns, daher ist dies weniger ein Problem als früher, aber es gibt ältere Geräte, die von diesem einfachen Caching profitieren.

Wenn sich die Länge ändern kann, kann das Zwischenspeichern zu unerwarteten Nebenwirkungen führen, wenn Sie nicht wissen, warum Sie die Länge zwischenspeichern. Bei einer wiederverwendbaren Funktion besteht der einzige Zweck darin, ein Array zu verwenden und die Werte zu addieren tolle Passform.

Hier ist ein CodePen-Link für diese arraySum-Funktion. http://codepen.io/brandonbrule/pen/ZGEJyV

Es ist möglich, dass dies eine veraltete Denkweise ist, die mir am Herzen liegt, aber ich sehe keinen Nachteil darin, sie in diesem Zusammenhang zu verwenden.


Das Problem des Zwischenspeicherns der Länge ist ein roter Hering. JS-Engines optimieren dies für Sie, ohne zu blinken.

2

Das sind wirklich gute Antworten, aber nur für den Fall, dass die Zahlen wie in der Frage (1,2,3,4) aufeinander folgen, können Sie dies leicht tun, indem Sie die Formel (n * (n + 1)) / 2 anwenden, wobei n ist die letzte Zahl


2
Object.defineProperty(Object.prototype, 'sum', {
    enumerable:false,
    value:function() {
        var t=0;for(var i in this)
            if (!isNaN(this[i]))
                t+=this[i];
        return t;
    }
});

[20,25,27.1].sum()                 // 72.1
[10,"forty-two",23].sum()          // 33
[Math.PI,0,-1,1].sum()             // 3.141592653589793
[Math.PI,Math.E,-1000000000].sum() // -999999994.1401255

o = {a:1,b:31,c:"roffelz",someOtherProperty:21.52}
console.log(o.sum());              // 53.519999999999996

Entfernt dieser Code Ihr Betriebssystem? Oder sendet es Ihre persönlichen Daten an mich?

2

Das ist viel einfacher

function sumArray(arr) {
    var total = 0;
    arr.forEach(function(element){
        total += element;
    })
    return total;
}

var sum = sumArray([1,2,3,4])

console.log(sum)

2

Ein einfaches Methodenbeispiel:

function add(array){
    var arraylength = array.length;
    var sum = 0;
    for(var timesToMultiply = 0; timesToMultiply<arraylength; timesToMultiply++){
        sum += array[timesToMultiply];
    }

    return sum;
}

console.log(add([1, 2, 3, 4]));
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.