Jak obliczyć sumę i średnią elementów w tablicy?

177

Mam problemy z dodaniem wszystkich elementów tablicy, a także ich uśrednieniem. Jak mam to zrobić i zaimplementować za pomocą kodu, który mam obecnie? Elementy mają być zdefiniowane tak, jak mam to poniżej.

<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
źródło
26
var elmt = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]byłoby o wiele ładniejsze.
James McLaughlin

Odpowiedzi:

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

Po prostu przeprowadź iterację przez tablicę, ponieważ twoje wartości są łańcuchami, muszą najpierw zostać przekonwertowane na liczbę całkowitą. A średnia to po prostu suma wartości podzielona przez liczbę wartości.

Marcus Recck
źródło
13
Jedyna poprawa zrobiłbym byłoby wymienić for(var i = 0; i < elmt.length; i++;)zfor(var i = 0, l = elmt.length; i < l; i++)
Dan D.
5
nie być tym facetem lub być poza tematem, ale dobrą praktyką jest włączenie argumentu radix do parseInt (). Rozumiem przez to sum += parseInt(elmt[i], 10);zakładając, że wiąz [i] jest z podstawowego 10. link
Ryder Brooks
9
Uważaj na podziałów przez 0 (elmt.length może mi 0)
caulitomaz
2
@BramVanroy Krótka historia: Nie, nie ustawia „l” za każdym razem. Długa historia: rozwiązaniem DanD jest poprawa wydajności / szybkości, ponieważ sprawdzanie długości tablicy w każdej pojedynczej iteracji jest wolniejsze niż faktyczne przechowywanie długości w zmiennej lokalnej i odwoływanie się do niej w każdej iteracji.
CatalinBerta
9
@VitoGentile i DanD uszlachetnianie kodu w celu zwiększenia wydajności, który i tak kompilują nowoczesne przeglądarki, nie powinno być najlepszą praktyką.
nauti
496

Rozwiązanie, które uważam za bardziej eleganckie:

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
źródło
1
To nie zadziała na <= IE8, ponieważ nie obsługuje Array.prototype.reduce () Więcej informacji na developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ...
aabele
14
ze skumulowaną średnią kroczącą, możesz to wszystko zrobić w ramach funkcji redukuj (nie ma potrzeby wykonywania sum/times.lengthkroku):var avg = times.reduce(function(p,c,i){return p+(c-p)/(i+1)},0);
zamnuts
6
@zamnuts Jestem z tobą, myślę, że komentarz Thor84 nie jest całkowicie nieczynny - byłbym szczęśliwy, gdyby został zwolniony z miejsca, w którym array.reduce jest zbyt skomplikowana. Jednak nie użyłbym również twojego kodu, z prostego powodu, że ma on podział i dwa dodatkowe dodatki na każdym kroku, co nigdy nie będzie tak wydajne jak pojedynczy podział na końcu
gotofritz
12
W ES2015 jest nieco bardziej elegancko. times.reduce((a,b) => (a+b)) / times.length;
Ray Foss
12
@furf 5 lat później wygląda na to, że w wielu współczesnych przeglądarkach bardziej elegancka funkcja „redukuj ()” jest szybsza (lub równie szybka). W Chrome 65 i większości Firefoksa Redukcja jest lepsza w tym teście.
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
źródło
3
Ulepszono: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
Proszę, nie rozszerzaj obiektów, które nie są tworzone przez Twój kod.
Brad
1
UPDATE nie działa dla: ["RER", "4", "3re", 5, new Object ()]. ​​Average (); zwraca 0 zamiast oczekiwanego 4,5
Luckylooke
4
A to epicko się załamie, gdy nie będzie długości
Jimmy Kane
2
@JimmyKane Nie, to wróci NaN.
bzeaman
37

Obliczanie średniej (średniej) za pomocą funkcji redukuj i ES6:

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

const list = [0, 10, 20, 30]
average(list) // 15
Tomasz Mularczyk
źródło
bardzo, bardzo powolne w porównaniu do prostego dodawania opartego na pętli for ze zmienną sumy jsben.ch/0xUus
PirateApp
Tutaj różnica 25%. Myślę, że nie tak źle.
Michael
20

generalnie średnia przy użyciu jednej linijki jest taka

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

specjalnie na zadane pytanie

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

wydajna wersja jest jak

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

Zrozumienie tablicy Javascript Redukcja w 1 minutę http://www.airpair.com/javascript/javascript-array-reduce

jak wskazał gotofritz, wydaje się, że Array.reduce pomija niezdefiniowane wartości. więc tutaj jest poprawka:

(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
źródło
2
elements.length!=0?elements.length:1 można również napisać w ten sposób: elements.length || 1 który jest krótszy i łatwiejszy do odczytania.
4rzael
2
Pamiętaj, że to działa tylko dla tablic bez pustych przerw
gotofritz
1
Sugestia: dodaj niezminifikowane (właściwie tylko ładnie wydrukowane) wersje fragmentów kodu, aby ludzie mogli je przeczytać. Sam bym je edytował, ale nie lubię zmieniać odpowiedzi ludzi w takim stopniu.
Justin Morgan,
16

Wyobraźmy sobie, że mamy taką tablicę liczb całkowitych:

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

Średnią uzyskuje się za pomocą następującego wzoru

A = (1 / n) Σxi (gdzie i = 1 do n) ... Więc: x1 / n + x2 / n + ... + xn / n

Bieżącą wartość dzielimy przez liczbę wartości i dodajemy poprzedni wynik do zwracanej wartości.

Sygnatura metody to

reduce(callback[,default_previous_value])

Funkcja redukcji wywołania zwrotnego przyjmuje następujące parametry:

  • p : Wynik poprzedniego obliczenia
  • do : Bieżąca wartość (z aktualnego indeksu)
  • ja : wartość indeksu bieżącego elementu tablicy
  • za : Bieżąca zredukowana tablica

Drugi parametr redukcji jest wartością domyślną ... (używana w przypadku, gdy tablica jest pusta ).

Zatem średnia metoda redukcji będzie:

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

Jeśli wolisz, możesz utworzyć oddzielną funkcję

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

Następnie wystarczy odwołać się do sygnatury metody wywołania zwrotnego

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

Lub bezpośrednio rozszerz prototyp macierzy.

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

Wartość można podzielić za każdym razem, gdy wywoływana jest metoda redukcji.

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

Lub jeszcze lepiej , używając wcześniej zdefiniowanej Array.protoype.sum ()

metoda, zoptymalizuj proces moje wywołanie podziału tylko raz :)

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

Następnie na dowolnym obiekcie Array z zakresu:

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

NB: pusta tablica ze zwrotem życzenia NaN jest z mojego punktu widzenia bardziej poprawna niż 0 i może być przydatna w określonych przypadkach użycia.

Ludovic Frérot
źródło
13

Możesz także użyć lodash , _.sum (tablica) i _.mean (tablica) w części Math (masz też inne przydatne rzeczy).

_.sum([4, 2, 8, 6]);
// => 20
_.mean([4, 2, 8, 6]);
// => 5
Geng Jiawen
źródło
6

Nie najszybszy, ale najkrótszy i w jednej linii używa map () i redukuj ():

var average = [7,14,21].map(function(x,i,arr){return x/arr.length}).reduce(function(a,b){return a + b})
Johann Echavarria
źródło
1
może krócej [7,14,21].reduce((avg,e,i,arr)=>avg+e/arr.length,0); ale z innym zachowaniem na pustej tablicy. Jeśli chcesz, aby wynik był pusty w pustej tablicy:[].reduce((a,e,i,arr)=>(a?a:0)+e/arr.length,"")
Valen
@Tobiq map i redukuj są dość standardowe od ES5 (znormalizowane w 2009)
Johann Echavarria
for (var avg = 0, length = i = arr.length; i--;) avg += arr[i] / lengthDużo wyraźniej, krócej i znacznie szybciej
Tobiq
2
@Tobiq, Twój kod nie jest jasny. Ten rodzaj pętli jest na pierwszy rzut oka niezrozumiały.
Porkopek
5

Jeden podstępny sposób, w jaki możesz to zrobić, chociaż wymaga użycia (bardzo znienawidzonego) eval ().

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/>");

Pomyślałem, że opublikuję to jako jedną z tych opcji „nieszablonowych”. Nigdy nie wiadomo, chytrość może przyznać ci (lub odebrać) punkt.

Phil Cooper
źródło
+1 Niezła, wydajna jednolinijka! Jeśli jest to JavaScript w przeglądarce po stronie klienta, jedynym możliwym eval()problemem, jaki widzę, jest to, że musisz mieć pewność, że tablica zawiera tylko liczby (co oczywiście dotyczy również wszystkich innych odpowiedzi tutaj). Wpisy nieliczbowe powodują awarię z ReferenceErrorlub SyntaxError, except nested arrays of numbers which introduce , powodując niepoprawną sumę liczbową. I oczywiście w JS po stronie serwera, np. Node.js, eval()może to oczywiście spowodować problemy z bezpieczeństwem. Ale wygląda to idealnie w przypadku dobrze zorganizowanych zastosowań po stronie klienta.
user56reinstatemonica8
1
Właściwie może być problem z wydajnością, aby to uwzględnić eval()- zobacz sekcję dotyczącą wydajności na stronie nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood
user56reinstatemonica8
5

Używam tych metod w mojej osobistej bibliotece:

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

EDYCJA: Aby z nich skorzystać, po prostu poproś tablicę o jej sumę lub średnią, na przykład:

[1,2,3].sum() // = 6
[1,2,3].average() // = 2
Keith
źródło
Zgrabna implementacja, chociaż zaimplementowałbym sumę, aby użyć pętli for zamiast redukować. Nadal jednak bardzo czysto zakodowane.
XDS
5

W przeglądarkach obsługujących ES6 ten polyfill może być pomocny.

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

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

Możesz dzielić tę samą metodę połączenia pomiędzy Math.sum, Math.avg i Math.max, jak

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

możesz użyć Math.sum jako

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

lub jeśli masz tablicę do podsumowania, możesz użyć

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

tak jak

var maxOne = Math.max.apply(null,[1,2,3,4]) // 4
Oboo Cheng
źródło
Zamiast dodawać metody do Array.prototype, myślę, że dodanie motywu do Mathobiektu jest lepszym wyborem - wszystkie są „programami obsługi liczb”.
Oboo Cheng
3

Oto krótki dodatek do obiektu „Math” w javascript, aby dodać do niego polecenie „średnia” !!

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;
}

Następnie mam ten dodatek do obiektu „Math”, aby uzyskać sumę!

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;
}

Więc wszystko, co robisz, to

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

I gdzie umieściłem tablicę symboli zastępczych, po prostu przekaż ją do swojej zmiennej (dane wejściowe, jeśli są liczbami, mogą być ciągiem, ponieważ analizuje je na liczbę!)

Jacob Morris
źródło
1

ustaw swój licznik pętli for na 0 .... otrzymujesz element 9 i gotowe, tak jak masz teraz. Pozostałe odpowiedzi to podstawowa matematyka. Użyj zmiennej do przechowywania sumy (musisz rzucić ciągi na liczby int) i podziel przez długość tablicy.

Volvox
źródło
1

Zacznij od zdefiniowania wszystkich zmiennych, których planujemy używać. Zauważysz, że w przypadku numberstablicy używam notacji dosłownej w []przeciwieństwie do metody konstruktora array(). Ponadto używam krótszej metody, aby ustawić wiele zmiennych na 0.

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

Następnie wypełniam moją pustą tablicę liczb wartościami od 0 do 11. Ma to na celu doprowadzenie mnie do pierwotnego punktu początkowego. Zwróć uwagę, jak naciskam na tablicę count++. Spowoduje to przesunięcie bieżącej wartości count, a następnie zwiększenie jej przy następnym razem.

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

Na koniec wykonuję funkcję „dla każdego” z liczb w tablicy liczb. Ta funkcja będzie obsługiwać jedną liczbę naraz, którą identyfikuję jako „n” w treści funkcji.

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

Na koniec możemy przesłać zarówno sumwartość, jak i avgwartość do naszej konsoli, aby zobaczyć wynik:

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

Zobacz to w akcji online pod adresem http://jsbin.com/unukoj/3/edit

Sampson
źródło
1

Opieram się tylko na odpowiedzi Abdennour TOUMI. oto powody, dla których:

1.) Zgadzam się z Bradem, uważam, że nie jest dobrym pomysłem przedłużanie obiektu, którego nie stworzyliśmy.

2.) array.lengthjest dokładnie niezawodny w javascript, wolę, Array.reduceponieważ a=[1,3];a[1000]=5;teraz a.lengthwróci 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
źródło
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 ) ; 
};

Następnie :

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

[{age:25},{age:26},{age:27}].avg(function(e){return e.age}); // OUT : 26
Abdennour TOUMI
źródło
1

W wiecznie zielonych przeglądarkach możesz używać funkcji strzałek avg = [1,2,3].reduce((a,b) => (a+b);

Po uruchomieniu go 100 000 razy różnica czasu między podejściem pętli for i redukcją jest pomijalna.

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
źródło
1
Musisz dowiedzieć się więcej o console.time&console.timeEnd
Abdennour TOUMI
@AbdennourTOUMI Dzięki za wskazówkę, będę o tym pamiętać ... jednak jest to niestandardowe i nie na standardowym torze. developer.mozilla.org/en-US/docs/Web/API/Console/timeEnd
Ray Foss
1
Wiem, że odwracam się od oryginalnych pytań, ale co powiesz na użycie performance.now () do pomiaru wydajności?
deejbee
@deejbee To zapewnia dokładność zmiennoprzecinkową ... ale jest też odrobinę bardziej rozwlekłe i mniej kompatybilne. Ustawienie markerów przydałoby się w prawdziwym kodzie
Ray Foss
1

Średnia najkrótsza jedna wkładka:

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

Sum Shortest One Liner:

let sum = [1,2,3].reduce((a,b)=>a+b);
kurczaki
źródło
0

Tylko dla kopnięć:

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

źródło
0

Myślę, że możemy to zrobić

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

Używam parseFloat dwa razy, ponieważ jeśli 1) dodasz (a) 9 + b ("1") liczba, to wynik będzie "91", ale chcemy dodać. więc użyłem parseFloat

2) Gdy nastąpi dodanie (a) 9 + parseFloat ("1"), chociaż wynik będzie wynosił "10", ale będzie to łańcuch, którego nie chcemy, więc ponownie użyłem parseFloat.

Mam nadzieję, że wszystko jasne. Sugestie są mile widziane

Roli Agrawal
źródło
0

Oto mój nowicjusz, aby po prostu znaleźć średni. Mam nadzieję, że to komuś pomoże.

function numAvg(num){
    var total = 0;
    for(var i = 0;i < num.length; i++) { 
        total+=num[i];
    }
    return total/num.length;
}
Jeremiasz
źródło
0

oto twoja jedna wkładka:

var average = arr.reduce((sum,item,index,arr)=>index !== arr.length-1?sum+item:sum+item/arr.length,0)
Alex C.
źródło
0

Myślę, że może to być bezpośrednie rozwiązanie do obliczenia średniej za pomocą pętli for i funkcji.

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
źródło
0

Wydaje się, że istnieje nieskończona liczba rozwiązań, ale uznałem, że jest to zwięzłe i eleganckie.

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

Lub bardziej konsekwentnie:

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

W zależności od przeglądarki może być konieczne wykonanie jawnych wywołań funkcji, ponieważ funkcje strzałek nie są obsługiwane:

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

Lub:

const average1 = numbers
    .map(function (x) {
        return x/count;
     })
    .reduce(function (adder, value) {
        return adder + value;
});
console.log(average1);
Charles Owen
źródło
Tworzysz N działek w funkcji mapy. Lepiej najpierw zredukować wszystkie liczby do całkowitej wartości, a następnie zrobić tylko jeden podział
Eugenio
0

Jeśli potrzebujesz średniej i możesz pominąć obliczanie sumy, możesz obliczyć średnią jednym wywołaniem redukcji:

// 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
źródło
0

Jeśli ktoś kiedykolwiek tego potrzebuje - oto średnia rekurencyjna.

W kontekście pierwotnego pytania możesz chcieć użyć średniej rekurencyjnej, jeśli pozwoliłeś użytkownikowi wstawić dodatkowe wartości i bez ponoszenia kosztów ponownego odwiedzenia każdego elementu, chciałeś „zaktualizować” istniejącą średnią.

/**
 * 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

W jaki sposób:

działa to poprzez utrzymanie bieżącej średniej i liczby elementów. Gdy ma zostać uwzględniona nowa wartość, należy zwiększyć liczbę o 1, skalować istniejącą średnią o (count-1) / counti dodaćnewValue / count do średniej.

Korzyści:

  • nie sumujesz wszystkich elementów, co może skutkować dużą liczbą, której nie można zapisać w 64-bitowej zmiennej zmiennoprzecinkowej.
  • można „zaktualizować” istniejącą średnią, jeśli dodatkowe wartości staną się dostępne.
  • można wykonać średnią kroczącą bez znajomości długości sekwencji.

Wady:

  • powoduje o wiele więcej podziałów
  • nie nieskończone - ograniczone do pozycji Number.MAX_SAFE_INTEGER, chyba że zatrudniasz BigNumber
Meirion Hughes
źródło
-1

Średnia zawartość HTML itens

Dzięki jQuery lub Javascriptowi querySelectormasz bezpośredni dostęp do sformatowanych danych ... Przykład:

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

Tak więc z jQuery masz

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

Zobacz inne 4 sposoby (!), Aby uzyskać dostęp do itens i uśrednić: http://jsfiddle.net/4fLWB/

Peter Krauss
źródło
2
Głosuj przeciw, ponieważ OP poprosił o zrobienie X, a ty powiedziałeś mu, jak zrobić Y, a potem X. Ponadto pomysł pobierania danych z DOM zamiast tworzenia DOM z danych wydaje się być czymś, czego i tak prawdopodobnie chciałbyś uniknąć.
eremzeit
Cześć @eremzeit, dzięki uwaga. Używam pogrubionego tytułu, aby powiedzieć "to jest inny przypadek, z zawartością do HTML", proszę to przemyśleć ... Jeśli chodzi o istotne, tego rodzaju użycie (bezpośredni dostęp do danych z HTML, które widzi użytkownik) nie jest grą akademicką ... Chodzi o "prawdę podlegającą audytowi", czyli w HTML (!), A nie "ukrytą przed ludźmi" w javascript ... Nie tylko w Wikipedii, zobacz typowe przypadki: 3,7 miliona artykułów naukowych w PMC , 6,6 MILIONA dokumentów legislacyjnych w LexML . Niektórzy ludzie nie tylko projektują i grają w js, ale robią narzędzia do audytu.
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;
}

avg (arr) ====== >>>> 3

Działa to z łańcuchami jako liczbami lub liczbami w tablicy.

dan chow
źródło
Oto pewne wyjaśnienie twojej odpowiedzi.
David Hoelzer
Masz rację: zdefiniuj sumę jako liczbę, aby to działało teraz. Podaj funkcję tablicę, a wypluwa średnią z tablicy.
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
źródło
1
Witamy w Stack Overflow. Twoja odpowiedź powinna szczegółowo wyjaśniać, dlaczego i jak odpowiada na pytanie. Chociaż zachęcamy do umieszczania fragmentów kodu, należy objaśnić kod, aby odwiedzający mogli go zrozumieć. Oto przewodnik, jak odpowiedzieć na to pytanie: stackoverflow.com/help/how-to-answer
ChrisM
-3

Poleciłbym w tym przypadku D3. Jest najbardziej czytelny (i zapewnia 2 różne rodzaje średnich)

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); 
Zaklinacz kodów
źródło
4
Boże, dodawanie całego D3 tylko po to, aby
wyliczyć