Wie berechnet man die Summe und den Durchschnitt der Elemente in einem Array?

177

Ich habe Probleme, alle Elemente eines Arrays hinzuzufügen und zu mitteln. Wie würde ich das tun und es mit dem Code implementieren, den ich derzeit habe? Die Elemente sollen so definiert werden, wie ich es unten habe.

<script type="text/javascript">
//<![CDATA[

var i;
var elmt = new Array();

elmt[0] = "0";
elmt[1] = "1";
elmt[2] = "2";
elmt[3] = "3";
elmt[4] = "4";
elmt[5] = "7";
elmt[6] = "8";
elmt[7] = "9";
elmt[8] = "10";
elmt[9] = "11";

// Problem here
for (i = 9; i < 10; i++){
  document.write("The sum of all the elements is: " + /* Problem here */ + " The average of all the elements is: " + /* Problem here */ + "<br/>");
}   

//]]>
</script>
Jonathan Miller
quelle
26
var elmt = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]wäre so viel schöner.
James McLaughlin

Antworten:

134
var sum = 0;
for( var i = 0; i < elmt.length; i++ ){
    sum += parseInt( elmt[i], 10 ); //don't forget to add the base
}

var avg = sum/elmt.length;

document.write( "The sum of all the elements is: " + sum + " The average is: " + avg );

Durchlaufen Sie einfach das Array, da Ihre Werte Zeichenfolgen sind, müssen sie zuerst in eine Ganzzahl konvertiert werden. Und Durchschnitt ist nur die Summe der Werte geteilt durch die Anzahl der Werte.

Marcus Recck
quelle
13
Die einzige Verbesserung, die ich tun würde, wäre zu ersetzen for(var i = 0; i < elmt.length; i++;)durchfor(var i = 0, l = elmt.length; i < l; i++)
Dan D.
5
Nicht dieser Typ zu sein oder nicht zum Thema zu gehören, aber es ist eine gute Praxis, das Radix-Argument in parseInt () aufzunehmen. Damit meine ich die sum += parseInt(elmt[i], 10);Annahme , dass elmt [i] von der Basis 10 ist. Link
Ryder Brooks
9
Achten Sie auf Divisionen durch 0 (elmt.length könnte ich 0)
caulitomaz
2
@BramVanroy Kurzgeschichte: Nein, es wird nicht jedes Mal 'l' gesetzt. Lange Geschichte: Die Lösung von DanD besteht darin, die Leistung / Geschwindigkeit zu verbessern, da das Überprüfen der Länge eines Arrays bei jeder einzelnen Iteration langsamer ist als das Speichern der Länge in einer lokalen Variablen und das Referenzieren bei jeder Iteration.
CatalinBerta
9
@VitoGentile und DanD, die den Code für Leistungssteigerungen, die moderne Browser sowieso kompilieren, hässlich machen, sollten keine bewährte Methode sein.
Nauti
496

Eine Lösung, die ich für eleganter halte:

const sum = times.reduce((a, b) => a + b, 0);
const avg = (sum / times.length) || 0;

console.log(`The sum is: ${sum}. The average is: ${avg}.`);
Sergi Mansilla
quelle
1
Dies funktioniert nicht auf <= IE8, da Array.prototype.reduce () nicht unterstützt wird. Weitere Informationen finden Sie unter developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
aabele
14
Mit einem kumulativen gleitenden Durchschnitt können Sie dies alles innerhalb der Reduktionsfunktion tun (keine Notwendigkeit für den sum/times.lengthSchritt):var avg = times.reduce(function(p,c,i){return p+(c-p)/(i+1)},0);
Zamnuts
6
@zamnuts Ich bin bei dir, ich denke, der Kommentar von Thor84no ist völlig außer Betrieb - ich würde mich freuen, von einem Ort gefeuert zu werden, der array.reduce zu komplex findet. Allerdings würde ich Ihren Code auch nicht verwenden, da er einfach eine Unterteilung und zwei zusätzliche Ergänzungen in jedem Schritt enthält, was am Ende niemals so effizient sein wird wie eine einzelne Unterteilung
gotofritz
12
In ES2015 ist es etwas eleganter. times.reduce((a,b) => (a+b)) / times.length;
Ray Foss
12
@furf 5 Jahre später sieht es so aus, als ob in vielen modernen Browsern das elegantere "redu ()" schneller (oder genauso schnell) ist. In Chrome 65 und den meisten Firefoxen ist Reduzieren bei diesem Test besser.
Sir Robert
116

ES6

const average = arr => arr.reduce( ( p, c ) => p + c, 0 ) / arr.length;
    
const result = average( [ 4, 4, 5, 6, 6 ] ); // 5
    
console.log(result);

Abdennour TOUMI
quelle
3
Verbessert:Array.prototype.average = function () { var sum = 0, j = 0; for (var i = 0; i < this.length, isFinite(this[i]); i++) { sum += parseFloat(this[i]); ++j; } return j ? sum / j : 0; };
Gilad Peleg
42
Bitte erweitern Sie keine Objekte, die nicht von Ihrem Code erstellt wurden.
Brad
1
UPDATE funktioniert nicht für: ["RER", "4", "3re", 5, neues Objekt ()]. ​​Average (); gibt 0 statt erwartet 4.5 zurück
Luckylooke
4
Und dies wird episch abstürzen, wenn es keine Länge gibt
Jimmy Kane
2
@ JimmyKane Nein, es wird zurückkehren NaN.
Bzeaman
37

Berechnung des Durchschnitts (Mittelwerts) mit Reduce und ES6:

const average = list => list.reduce((prev, curr) => prev + curr) / list.length;

const list = [0, 10, 20, 30]
average(list) // 15
Tomasz Mularczyk
quelle
sehr sehr langsam im Vergleich zu einer einfachen for-Schleifen-basierten Addition mit einer Summenvariablen jsben.ch/0xUus
PirateApp
Hier ist es ein Unterschied von 25%. Nicht so schlimm, denke ich.
Michael
20

Im Allgemeinen ist die durchschnittliche Verwendung einer Einzeiler-Reduzierung so

elements.reduce(function(sum, a,i,ar) { sum += a;  return i==ar.length-1?(ar.length==0?0:sum/ar.length):sum},0);

speziell auf die gestellte Frage

elements.reduce(function(sum, a,i,ar) { sum += parseFloat(a);  return i==ar.length-1?(ar.length==0?0:sum/ar.length):sum},0);

Eine effiziente Version ist wie

elements.reduce(function(sum, a) { return sum + a },0)/(elements.length||1);

Verstehen Sie die Reduzierung von Javascript-Arrays in 1 Minute http://www.airpair.com/javascript/javascript-array-reduce

Wie gotofritz hervorhob, überspringt Array.reduce undefinierte Werte. Also hier ist ein Fix:

(function average(arr){var finalstate=arr.reduce(function(state,a) { state.sum+=a;state.count+=1; return state },{sum:0,count:0}); return finalstate.sum/finalstate.count})([2,,,6])
Shimon Doodkin
quelle
2
elements.length!=0?elements.length:1 kann auch so geschrieben werden: elements.length || 1 das ist kürzer und leichter zu lesen.
4rzael
2
Denken Sie daran, dass dies nur für Arrays ohne leere Lücken
funktioniert
1
Vorschlag: Fügen Sie nicht minimierte (eigentlich nur hübsch gedruckte) Versionen Ihrer Codefragmente hinzu, damit die Benutzer sie lesen können. Ich würde sie in mir selbst bearbeiten, aber ich mag es nicht, die Antworten der Leute in diesem Ausmaß zu ändern.
Justin Morgan
16

Stellen wir uns vor, wir haben eine Reihe solcher Ganzzahlen:

var values = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];

Der Durchschnitt wird mit der folgenden Formel erhalten

A = (1 / n) Σxi (mit i = 1 bis n) ... Also: x1 / n + x2 / n + ... + xn / n

Wir teilen den aktuellen Wert durch die Anzahl der Werte und addieren das vorherige Ergebnis zum zurückgegebenen Wert.

Die Signatur der Reduzierungsmethode lautet

reduce(callback[,default_previous_value])

Die Rückruffunktion reduziert die folgenden Parameter:

  • p : Ergebnis der vorherigen Berechnung
  • c : Aktueller Wert (aus dem aktuellen Index)
  • i : Indexwert des aktuellen Array-Elements
  • a : Das stromreduzierte Array

Der Parameter der zweiten Reduzierung ist der Standardwert ... (Wird verwendet, wenn das Array leer ist ).

Die durchschnittliche Reduktionsmethode lautet also:

var avg = values.reduce(function(p,c,i,a){return p + (c/a.length)},0);

Wenn Sie möchten, können Sie eine separate Funktion erstellen

function average(p,c,i,a){return p + (c/a.length)};
function sum(p,c){return p + c)};

Und dann beziehen Sie sich einfach auf die Signatur der Rückrufmethode

var avg = values.reduce(average,0);
var sum= values.reduce(sum,0);

Oder erweitern Sie den Array-Prototyp direkt.

Array.prototype.sum = Array.prototype.sum || function (){
  return this.reduce(function(p,c){return p+c},0);
};

Es ist möglich, den Wert bei jedem Aufruf der Reduktionsmethode zu teilen.

Array.prototype.avg = Array.prototype.avg || function () {
  return this.reduce(function(p,c,i,a){return p+(c/a.length)},0);
};

Oder noch besser mit dem zuvor definierten Array.protoype.sum ()

Methode, optimieren Sie den Prozess, indem Sie die Division nur einmal aufrufen :)

Array.prototype.avg = Array.prototype.avg || function () {
  return this.sum()/this.length; 
};

Dann auf jedem Array-Objekt des Bereichs:

[2, 6].avg();// -> 4
[2, 6].sum();// -> 8

NB: Ein leeres Array mit der Rückgabe eines NaN-Wunsches ist aus meiner Sicht korrekter als 0 und kann in bestimmten Anwendungsfällen nützlich sein.

Ludovic Frérot
quelle
13

Sie können auch lodash , _.sum (Array) und _.mean (Array) im Math-Teil verwenden (haben auch andere praktische Dinge).

_.sum([4, 2, 8, 6]);
// => 20
_.mean([4, 2, 8, 6]);
// => 5
Geng Jiawen
quelle
6

Nicht der schnellste, aber der kürzeste und in einer Zeile verwendete map () & redu ():

var average = [7,14,21].map(function(x,i,arr){return x/arr.length}).reduce(function(a,b){return a + b})
Johann Echavarria
quelle
1
vielleicht kürzer, [7,14,21].reduce((avg,e,i,arr)=>avg+e/arr.length,0);aber mit unterschiedlichem Verhalten auf leerem Array. Wenn Sie möchten, dass das Ergebnis auf einem leeren Array leer ist:[].reduce((a,e,i,arr)=>(a?a:0)+e/arr.length,"")
Valen
@Tobiq Map & Reduce sind seit ES5 (2009 standardisiert) ziemlich Standard
Johann Echavarria
for (var avg = 0, length = i = arr.length; i--;) avg += arr[i] / lengthViel klarer, kürzer und viel schneller
Tobiq
2
@Tobiq, dein Code ist alles andere als klar. Diese Art von Schleife ist auf den ersten Blick unverständlich.
Porkopek
5

Ein hinterhältiger Weg, wie Sie es tun könnten, obwohl es die Verwendung von (dem viel gehassten) eval () erfordert.

var sum = eval(elmt.join('+')), avg = sum / elmt.length;
document.write("The sum of all the elements is: " + sum + " The average of all the elements is: " + avg + "<br/>");

Ich dachte nur, ich würde dies als eine dieser "außerhalb der Box" -Optionen posten. Du weißt nie, die List könnte dir einen Punkt geben (oder wegnehmen).

Phil Cooper
quelle
+1 Schöner effizienter Einzeiler! Wenn es sich um clientseitiges In-Browser-Javascript handelt, ist das einzig mögliche eval()Problem, das ich sehen kann, dass Sie sicherstellen müssen, dass das Array nur Zahlen enthält (was natürlich auch für alle anderen Antworten hier gilt). Nicht numerische Einträge stürzen mit einem ReferenceErroroder ab SyntaxError, except nested arrays of numbers which introduce und verursachen eine falsche numerische Summe. Und natürlich kann in serverseitiger JS, z. B. node.js, natürlich eval()Sicherheitsprobleme auftreten. Dies sieht jedoch perfekt für alle gut strukturierten clientseitigen Anwendungen aus.
user56reinstatemonica8
1
Tatsächlich gibt es möglicherweise ein Leistungsproblem bei der Aufnahme eval()wie folgt
user56reinstatemonica8
5

Ich verwende diese Methoden in meiner persönlichen Bibliothek:

Array.prototype.sum = Array.prototype.sum || function() {
  return this.reduce(function(sum, a) { return sum + Number(a) }, 0);
}

Array.prototype.average = Array.prototype.average || function() {
  return this.sum() / (this.length || 1);
}

BEARBEITEN: Um sie zu verwenden, fragen Sie einfach das Array nach seiner Summe oder seinem Durchschnitt, wie zum Beispiel:

[1,2,3].sum() // = 6
[1,2,3].average() // = 2
Keith
quelle
Ordentliche Implementierung, obwohl ich sum implementiert hätte, um eine for-Schleife zu verwenden, anstatt zu reduzieren. Trotzdem sehr sauber codiert.
XDS
5

In ES6-fähigen Browsern kann diese Polyfüllung hilfreich sein.

Math.sum = (...a) => Array.prototype.reduce.call(a,(a,b) => a+b)

Math.avg = (...a) => this.sum(...a)/a.length;

Sie können gleiche Call - Methode teilen zwischen Math.sum, Math.avg und Math.max, wie

var maxOne = Math.max(1,2,3,4) // 4;

Sie können Math.sum als verwenden

var sumNum = Math.sum(1,2,3,4) // 10

oder wenn Sie ein Array zum Zusammenfassen haben, können Sie verwenden

var sumNum = Math.sum.apply(null,[1,2,3,4]) // 10

so wie

var maxOne = Math.max.apply(null,[1,2,3,4]) // 4
Oboo Cheng
quelle
Anstatt Methoden hinzuzufügen Array.prototype, halte ich das Hinzufügen eines Themas zum MathObjekt für eine bessere Wahl - sie sind alle "Zahlenhandler".
Oboo Cheng
3

Hier ist eine schnelle Ergänzung zum "Math" -Objekt in Javascript, um einen "Durchschnitts" -Befehl hinzuzufügen !!

Math.average = function(input) {
  this.output = 0;
  for (this.i = 0; this.i < input.length; this.i++) {
    this.output+=Number(input[this.i]);
  }
  return this.output/input.length;
}

Dann habe ich diesen Zusatz zum "Math" -Objekt, um die Summe zu erhalten!

Math.sum = function(input) {
  this.output = 0;
  for (this.i = 0; this.i < input.length; this.i++) {
    this.output+=Number(input[this.i]);
  }
  return this.output;
}

Also ist alles was du tust

alert(Math.sum([5,5,5])); //alerts “15”
alert(Math.average([10,0,5])); //alerts “5”

Und wo ich das Platzhalter-Array platziere, übergeben Sie einfach Ihre Variable (Die Eingabe, wenn es sich um Zahlen handelt, kann eine Zeichenfolge sein, da sie auf eine Zahl analysiert wird!)

Jacob Morris
quelle
1

Setzen Sie Ihren for-Schleifenzähler auf 0 ... Sie erhalten Element 9 und dann sind Sie fertig, wie Sie es jetzt haben. Die anderen Antworten sind grundlegende Mathematik. Verwenden Sie eine Variable, um Ihre Summe zu speichern (die Zeichenfolgen müssen in Ints umgewandelt werden) und durch Ihre Array-Länge zu dividieren.

Volvox
quelle
1

Definieren Sie zunächst alle Variablen, die wir verwenden möchten. Sie werden feststellen, dass ich für das numbersArray []im Gegensatz zur Konstruktormethode die Literalschreibweise von verwende array(). Außerdem verwende ich eine kürzere Methode, um mehrere Variablen auf 0 zu setzen.

var numbers = [], count = sum = avg = 0;

Als nächstes fülle ich mein leeres Zahlenarray mit den Werten 0 bis 11. Dies bringt mich zu Ihrem ursprünglichen Ausgangspunkt. Beachten Sie, wie ich auf das Array drücke count++. Dadurch wird der aktuelle Wert von count verschoben und dann für das nächste Mal erhöht.

while ( count < 12 )
    numbers.push( count++ );

Zuletzt führe ich eine Funktion "für jede" der Zahlen im Zahlenarray aus. Diese Funktion verarbeitet jeweils eine Nummer, die ich im Funktionskörper als "n" identifiziere.

numbers.forEach(function(n){
  sum += n; 
  avg = sum / numbers.length;
});

Am Ende können wir sowohl den sumWert als auch den avgWert an unsere Konsole ausgeben , um das Ergebnis zu sehen:

// Sum: 66, Avg: 5.5
console.log( 'Sum: ' + sum + ', Avg: ' + avg );

Sehen Sie es online in Aktion unter http://jsbin.com/unukoj/3/edit

Sampson
quelle
1

Ich baue nur auf Abdennour TOUMIs Antwort auf. Hier sind die Gründe warum:

1.) Ich stimme Brad zu, ich halte es nicht für eine gute Idee, ein Objekt zu erweitern, das wir nicht erstellt haben.

2.) array.lengthist in Javascript genau zuverlässig, ich bevorzuge Array.reduceweila=[1,3];a[1000]=5; , a.lengthwürde jetzt zurückkehren 1001.

function getAverage(arry){
    // check if array
    if(!(Object.prototype.toString.call(arry) === '[object Array]')){
        return 0;
    }
    var sum = 0, count = 0; 
    sum = arry.reduce(function(previousValue, currentValue, index, array) {
        if(isFinite(currentValue)){
            count++;
            return previousValue+ parseFloat(currentValue);
        }
        return previousValue;
    }, sum);
    return count ? sum / count : 0; 
};
mido
quelle
1
Array.prototype.avg=function(fn){
    fn =fn || function(e,i){return e};
    return (this.map(fn).reduce(function(a,b){return parseFloat(a)+parseFloat(b)},0) / this.length ) ; 
};

Dann :

[ 1 , 2 , 3].avg() ;  //-> OUT : 2

[{age:25},{age:26},{age:27}].avg(function(e){return e.age}); // OUT : 26
Abdennour TOUMI
quelle
1

In immergrünen Browsern können Sie Pfeilfunktionen verwenden avg = [1,2,3].reduce((a,b) => (a+b);

Wenn es 100.000 Mal ausgeführt wird, ist der Zeitunterschied zwischen dem for-Loop-Ansatz und dem Reduzieren vernachlässigbar.

s=Date.now();for(i=0;i<100000;i++){ n=[1,2,3]; a=n.reduce((a,b) => (a+b)) / n.length };
console.log("100k reduce took " + (Date.now()-s) + "ms.");

s=Date.now();for(i=0;i<100000;i++){n=[1,2,3]; nl=n.length; a=0; for(j=nl-1;j>0;j--){a=a+n[j];} a/nl };
console.log("100k for loop took " + (Date.now()-s) + "ms.");

s=Date.now();for(i=0;i<1000000;i++){n=[1,2,3]; nl=n.length; a=0; for(j=nl-1;j>0;j--){a=a+n[j];} a/nl };
console.log("1M for loop took " + (Date.now()-s) + "ms.");

s=Date.now();for(i=0;i<1000000;i++){ n=[1,2,3]; a=n.reduce((a,b) => (a+b)) / n.length };
console.log("1M reduce took " + (Date.now()-s) + "ms.");

/* 
 * RESULT on Chrome 51
 * 100k reduce took 26ms.
 * 100k for loop took 35ms.
 * 10M for loop took 126ms.
 * 10M reduce took 209ms.
 */

Ray Foss
quelle
1
Sie müssen mehr über console.time&console.timeEnd
Abdennour TOUMI
@AbdennourTOUMI Danke für den Tipp, ich werde es mir merken ... aber es ist nicht Standard und nicht auf Standard-Spur. developer.mozilla.org/en-US/docs/Web/API/Console/timeEnd
Ray Foss
1
Ich weiß, dass ich von den ursprünglichen Fragen abweiche, aber wie wäre es mit der Verwendung von performance.now () für Leistungsmessungen?
Deejbee
@deejbee Das bietet Gleitkomma-Genauigkeit ... aber es ist auch ein bisschen ausführlicher und weniger kompatibel. Das Setzen von Markierungen damit wäre im Code der realen Welt nützlich
Ray Foss
1

Durchschnittlich kürzester Einzeiler:

let avg = [1,2,3].reduce((a,v,i)=>(a*i+v)/(i+1));

Summe kürzester Einzeiler:

let sum = [1,2,3].reduce((a,b)=>a+b);
Hühner
quelle
0

Nur zum Spaß:

var elmt = [0, 1, 2,3, 4, 7, 8, 9, 10, 11], l = elmt.length, i = -1, sum = 0;
for (; ++i < l; sum += elmt[i])
    ;
document.body.appendChild(document.createTextNode('The sum of all the elements is: ' + sum + ' The average of all the elements is: ' + (sum / l)));

quelle
0

Ich denke wir können es mögen

var k=elmt.reduce(function(a,b){return parseFloat(a+parseFloat(b));})
var avg=k/elmt.length; 
console.log(avg);

Ich benutze parseFloat zweimal, denn wenn 1) Sie (a) 9 + b ("1") hinzufügen, ist das Ergebnis "91", aber wir möchten eine Addition. Also habe ich parseFloat benutzt

2) Wenn (a) 9 + parseFloat ("1") hinzugefügt wird, obwohl das Ergebnis "10" ist, aber es wird in einer Zeichenfolge sein, die wir nicht wollen, also habe ich parseFloat verwendet.

Ich hoffe ich bin klar. Vorschläge sind willkommen

Roli Agrawal
quelle
0

Hier ist meine Anfängermethode, um einfach den Durchschnitt zu finden. Hoffe das hilft jemandem.

function numAvg(num){
    var total = 0;
    for(var i = 0;i < num.length; i++) { 
        total+=num[i];
    }
    return total/num.length;
}
Jeremiah
quelle
0

Hier ist dein einziger Liner:

var average = arr.reduce((sum,item,index,arr)=>index !== arr.length-1?sum+item:sum+item/arr.length,0)
Alex C.
quelle
0

Ich denke, dies kann eine direkte Lösung sein, um den Durchschnitt mit einer for-Schleife und einer Funktion zu berechnen.

var elmts = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];

function average(arr) {
    var total = 0;
    for (var i = 0; i < arr.length; i++) {
        total += arr[i];
    }
        console.log(Math.round(total/arr.length));
}

average(elmts);
Redcoder
quelle
0

Es scheint unendlich viele Lösungen dafür zu geben, aber ich fand das prägnant und elegant.

const numbers = [1,2,3,4];
const count = numbers.length;
const reducer = (adder, value) => (adder + value);
const average = numbers.map(x => x/count).reduce(reducer);
console.log(average); // 2.5

Oder genauer:

const numbers = [1,2,3,4];
const average = numbers.map(x => x/numbers.length).reduce((adder, value) => (adder + value));
console.log(average); // 2.5

Abhängig von Ihrem Browser müssen Sie möglicherweise explizite Funktionsaufrufe ausführen, da Pfeilfunktionen nicht unterstützt werden:

const r = function (adder, value) {
        return adder + value;
};
const m = function (x) {
        return x/count;
};
const average = numbers.map(m).reduce(r);
console.log(average); // 2.5

Oder:

const average1 = numbers
    .map(function (x) {
        return x/count;
     })
    .reduce(function (adder, value) {
        return adder + value;
});
console.log(average1);
Charles Owen
quelle
Sie machen N Unterteilungen in der Kartenfunktion. Es ist besser, zuerst alle Zahlen auf einen Gesamtwert zu reduzieren und dann nur eine Division zu machen
Eugenio
0

Wenn Sie den Durchschnitt benötigen und die Berechnung der Summe überspringen können, können Sie den Durchschnitt mit einem einzigen Aufruf zum Reduzieren berechnen:

// Assumes an array with only values that can be parsed to a Float
var reducer = function(cumulativeAverage, currentValue, currentIndex) {
  // 1. multiply average by currentIndex to find cumulative sum of previous elements
  // 2. add currentValue to get cumulative sum, including current element
  // 3. divide by total number of elements, including current element (zero-based index + 1)
  return (cumulativeAverage * currentIndex + parseFloat(currentValue))/(currentIndex + 1)
}
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce(reducer, 0)); // => 5.5
console.log([].reduce(reducer, 0)); // => 0
console.log([0].reduce(reducer, 0)); // => 0
console.log([].reduce(reducer, 0)); // => 0
console.log([,,,].reduce(reducer, 0)); // => 0
console.log([].reduce(reducer, 0)); // => 0
Sealocal
quelle
0

Wenn jemand es jemals braucht - Hier ist ein rekursiver Durchschnitt.

Im Kontext der ursprünglichen Frage möchten Sie möglicherweise den rekursiven Durchschnitt verwenden, wenn Sie dem Benutzer das Einfügen zusätzlicher Werte gestattet haben und den vorhandenen Durchschnitt "aktualisieren" möchten, ohne die Kosten für den erneuten Besuch jedes Elements zu verursachen.

/**
 * Computes the recursive average of an indefinite set
 * @param {Iterable<number>} set iterable sequence to average
 * @param {number} initAvg initial average value
 * @param {number} initCount initial average count
 */
function average(set, initAvg, initCount) {
  if (!set || !set[Symbol.iterator])
    throw Error("must pass an iterable sequence");

  let avg = initAvg || 0;
  let avgCnt = initCount || 0;
  for (let x of set) {
    avgCnt += 1;
    avg = avg * ((avgCnt - 1) / avgCnt) + x / avgCnt;
  }
  return avg; // or {avg: avg, count: avgCnt};
}

average([2, 4, 6]);    //returns 4
average([4, 6], 2, 1); //returns 4
average([6], 3, 2);    //returns 4
average({
  *[Symbol.iterator]() {
    yield 2; yield 4; yield 6;
  }
});                    //returns 4

Wie:

Dies funktioniert, indem der aktuelle Durchschnitt und die Anzahl der Elemente beibehalten werden. Wenn ein neuer Wert aufgenommen werden soll, erhöhen Sie die Anzahl um 1, skalieren den vorhandenen Durchschnitt um (count-1) / countund addierennewValue / count zum Durchschnitt.

Leistungen:

  • Sie summieren nicht alle Elemente, was zu einer großen Anzahl führen kann, die nicht in einem 64-Bit-Float gespeichert werden kann.
  • Sie können einen vorhandenen Durchschnitt "aktualisieren", wenn zusätzliche Werte verfügbar werden.
  • Sie können einen gleitenden Durchschnitt durchführen, ohne die Sequenzlänge zu kennen.

Nachteile:

  • entsteht viel mehr Abteilungen
  • nicht unendlich - beschränkt auf Number.MAX_SAFE_INTEGER-Elemente, sofern Sie nicht beschäftigen BigNumber
Meirion Hughes
quelle
-1

Durchschnitt der HTML-Inhalte

Mit jQuery oder Javascript haben querySelectorSie direkten Zugriff auf formatierte Daten ... Beispiel:

<p>Elements for an average: <span class="m">2</span>, <span class="m">4</span>,
   <span class="m">2</span>, <span class="m">3</span>.
</p>

Mit jQuery haben Sie also

var A = $('.m')
  .map(function(idx) { return  parseInt($(this).html()) })
  .get();
var AVG = A.reduce(function(a,b){return a+b}) / A5.length;

Weitere weitere 4 Möglichkeiten (!), Auf itens zuzugreifen und es zu mitteln: http://jsfiddle.net/4fLWB/

Peter Krauss
quelle
2
Downvote, weil das OP darum gebeten hat, X zu machen, und Sie ihm gesagt haben, wie man Y und dann X macht. Außerdem scheint die Idee, Daten aus dem DOM zu ziehen, anstatt das DOM aus Daten zu erstellen, etwas zu sein, das Sie wahrscheinlich sowieso vermeiden möchten.
Eremzeit
Hallo @eremzeit, danke Aufmerksamkeit. Ich benutze einen fetten Titel, um zu sagen "es ist ein anderer Fall, mit Inhalten in HTML", bitte bedenken Sie es ... Über relevante, diese Art der Verwendung (direkter Zugriff auf Daten aus HTML, die der Benutzer sieht) ist kein akademisches Spiel ... Es geht um die "überprüfbare Wahrheit", das heißt in HTML (!), Nicht "vor Menschen verborgen" bei Javascript ... Nicht nur bei Wikipedia, siehe typische Fälle: 3,7 Millionen wissenschaftliche Artikel bei PMC , 6,6 MILLIONEN von Legislativdokumenten bei LexML . Einige Leute machen nicht nur Design und Spiele mit js, sondern machen auch Tools für die Prüfung.
Peter Krauss
-1

var arr = [1,2,3,4,5]

function avg(arr){
  var sum = 0;
  for (var i = 0; i < arr.length; i++) {
    sum += parseFloat(arr[i])
  }
  return sum / i;
}

Durchschnitt (arr) ====== >>>> 3

Dies funktioniert mit Zeichenfolgen als Zahlen oder Zahlen im Array.

Dan Chow
quelle
Eine Erklärung Ihrer Antwort ist angebracht.
David Hoelzer
Sie haben Recht: Definieren Sie die Summe als Zahl, damit dies jetzt funktioniert. Geben Sie der Funktion ein Array und spucken Sie den Durchschnitt des Arrays aus.
Dan Chow
-2
    var scores =[90, 98, 89, 100, 100, 86, 94];
        var sum = 0;
        var avg = 0;
        for(var i = 0; i < scores.length;i++){
  //Taking sum of all the arraylist
            sum = sum + scores[i];   
                }
  //Taking average     
             avg = sum/scores.length;        
  //this is the function to round a decimal no    
             var round = avg.toFixed();
             console.log(round);
Hannan Saleem
quelle
1
Willkommen bei Stack Overflow. Ihre Antwort sollte im Detail erklären, warum und wie sie die Frage beantwortet. Während Code-Schnipsel empfohlen werden, sollten Sie den Code erklären, damit die Besucher ihn verstehen können. Hier finden Sie eine Anleitung zur Beantwortung: stackoverflow.com/help/how-to-answer
ChrisM
-3

Ich würde D3 in diesem Fall empfehlen. Es ist am besten lesbar (und bietet 2 verschiedene Arten von Durchschnittswerten)

let d3 = require('d3');
let array = [1,2,3,4];
let sum = d3.sum(array); //10
let mean = d3.mean(array); //2.5
let median = d3.median(array); 
Code Whisperer
quelle
4
Meine Güte