Làm thế nào để tính tổng và trung bình của các phần tử trong một mảng?


177

Tôi gặp vấn đề khi thêm tất cả các yếu tố của một mảng cũng như tính trung bình cho chúng. Làm thế nào tôi có thể làm điều này và thực hiện nó với mã tôi hiện có? Các yếu tố được cho là được định nghĩa như tôi có nó dưới đây.

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

26
var elmt = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]sẽ đẹp hơn rất nhiều
James McLaughlin

Câu trả lời:


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

Chỉ cần lặp qua mảng, vì các giá trị của bạn là các chuỗi, trước tiên chúng phải được chuyển đổi thành một số nguyên. Và trung bình chỉ là tổng các giá trị chia cho số lượng giá trị.


13
Cải tiến duy nhất tôi sẽ làm là thay thế for(var i = 0; i < elmt.length; i++;)bằngfor(var i = 0, l = elmt.length; i < l; i++)
Dan D.

5
không phải là anh chàng đó hoặc lạc đề nhưng đó là một cách thực hành tốt để đưa đối số cơ số vào parseInt (). Điều đó có nghĩa là tôi sum += parseInt(elmt[i], 10);giả sử elmt [i] là liên kết
Ryder Brooks

9
Coi chừng sự phân chia bằng 0 (elmt.length có thể là tôi 0)
caulitomaz

2
@BramVanroy Truyện ngắn: Không, nó không đặt 'l' mỗi lần. Câu chuyện dài: Giải pháp của DanD là cải thiện hiệu suất / tốc độ, bởi vì việc kiểm tra độ dài của một mảng mỗi lần lặp lại chậm hơn so với việc thực sự lưu trữ độ dài trong một biến cục bộ và tham chiếu nó mỗi lần lặp.
CatalinBerta

9
@VitoGentile và DanD làm xấu mã hóa để tăng hiệu suất mà các Trình duyệt hiện đại biên dịch đi dù sao cũng không phải là cách thực hành tốt nhất.
nauti

496

Một giải pháp tôi cho là thanh lịch hơn:

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

1
Điều này sẽ không hoạt động trên <= IE8, vì nó không hỗ trợ Array.prototype.reduce () Xem thêm tại developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
trộm

14
với trung bình di chuyển tích lũy, bạn có thể thực hiện tất cả điều này trong hàm giảm (không cần sum/times.lengthbước):var avg = times.reduce(function(p,c,i){return p+(c-p)/(i+1)},0);
zamnuts

6
@zamnuts Tôi với bạn, tôi nghĩ rằng bình luận của Thor84no hoàn toàn không phù hợp - Tôi rất vui khi bị sa thải khỏi một nơi tìm thấy mảng.reduce quá phức tạp. Tuy nhiên, tôi cũng sẽ không sử dụng mã của bạn, vì thực tế đơn giản nó có một bộ phận và hai bổ sung bổ sung ở mọi bước, sẽ không bao giờ hiệu quả như một bộ phận duy nhất ở cuối
gotofritz

12
Trong ES2015, nó thanh lịch hơn một chút. times.reduce((a,b) => (a+b)) / times.length;
Ray Foss

12
@furf 5 năm sau, có vẻ như trong nhiều trình duyệt hiện đại, "less ()" thanh lịch hơn sẽ nhanh hơn (hoặc nhanh hơn). Trong Chrome 65 và hầu hết firefox giảm đều tốt hơn trong bài kiểm tra đó.
Ngài 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);


3
Cải thiện: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
Xin vui lòng, không mở rộng các đối tượng không được tạo bởi mã của bạn.
Brad

1
CẬP NHẬT không hoạt động cho: ["RER", "4", "3re", 5, đối tượng mới ()]. ​​Average (); trả về 0 thay vì dự kiến ​​4,5
Luckylooke

4
Và điều này sẽ sụp đổ về mặt lịch sử khi không có chiều dài
Jimmy Kane

2
@JimmyKane Không, nó sẽ trở lại NaN.
bzeaman

37

Tính trung bình (trung bình) bằng cách sử dụng giảm và ES6:

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

const list = [0, 10, 20, 30]
average(list) // 15

rất rất chậm so với một phép cộng dựa trên vòng lặp đơn giản với biến tổng jsben.ch/0xUus
PirateApp

Đây là một sự khác biệt 25%. Không tệ lắm, tôi nghĩ vậy.
Michael

20

nói chung trung bình sử dụng giảm một lớp lót là như thế này

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

cụ thể để hỏi

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

một phiên bản hiệu quả giống như

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

Hiểu được mảng Javascript giảm trong 1 phút http: //www.air Pair.com/javascript/javascript-array-reduce

như gotofritz đã chỉ ra dường như Array.reduce bỏ qua các giá trị không xác định. Vì vậy, đây là một sửa chữa:

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

2
elements.length!=0?elements.length:1 cũng có thể được viết như thế này: elements.length || 1 ngắn hơn và dễ đọc hơn.
4rzael

2
Hãy nhớ rằng điều này chỉ hoạt động cho các mảng không có khoảng trống
gotofritz

1
Gợi ý: Thêm các phiên bản chưa được chỉnh sửa (thực sự chỉ là bản in đẹp) của đoạn mã của bạn để mọi người có thể đọc chúng. Tôi tự chỉnh sửa chúng, nhưng tôi không muốn thay đổi câu trả lời của mọi người đến mức đó.
Justin Morgan

16

Hãy tưởng tượng chúng ta có một loạt các số nguyên như thế này:

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

Trung bình thu được với công thức sau

A = (1 / n) Σxi (với i = 1 đến n) ... Vậy: x1 / n + x2 / n + ... + xn / n

Chúng tôi chia giá trị hiện tại cho số lượng giá trị và thêm kết quả trước đó vào giá trị được trả về.

Chữ ký phương thức rút gọn là

reduce(callback[,default_previous_value])

Hàm gọi lại giảm có các tham số sau:

  • p : Kết quả tính toán trước
  • c : Giá trị hiện tại (từ chỉ mục hiện tại)
  • i : Giá trị chỉ mục của phần tử mảng hiện tại
  • a : Mảng giảm hiện tại

Tham số giảm thứ hai là giá trị mặc định ... (Được sử dụng trong trường hợp mảng trống ).

Vì vậy, phương pháp giảm trung bình sẽ là:

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

Nếu bạn thích bạn có thể tạo một chức năng riêng biệt

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

Và sau đó chỉ cần tham khảo chữ ký phương thức gọi lại

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

Hoặc Augment nguyên mẫu Array trực tiếp ..

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

Có thể chia giá trị mỗi lần phương thức rút gọn được gọi là ..

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

Hoặc thậm chí tốt hơn , bằng cách sử dụng Array.protoype.sum () được xác định trước đó

phương pháp, tối ưu hóa quá trình tôi gọi bộ phận chỉ một lần :)

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

Sau đó, trên bất kỳ đối tượng Array nào của phạm vi:

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

NB: một mảng trống có trả về một điều ước NaN đúng hơn 0 theo quan điểm của tôi và có thể hữu ích trong các trường hợp sử dụng cụ thể.


13

Bạn cũng có thể sử dụng lodash , _.sum (mảng) và _.mean (mảng) trong phần Toán học (cũng có những thứ tiện lợi khác).

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

6

Không phải là nhanh nhất, nhưng ngắn nhất và trong một dòng đang sử dụng map () & less ():

var average = [7,14,21].map(function(x,i,arr){return x/arr.length}).reduce(function(a,b){return a + b})

1
có thể ngắn hơn [7,14,21].reduce((avg,e,i,arr)=>avg+e/arr.length,0);nhưng với hành vi khác nhau trên mảng trống. Nếu bạn muốn kết quả trống ở mảng trống:[].reduce((a,e,i,arr)=>(a?a:0)+e/arr.length,"")
Valen

Bản đồ & thu nhỏ @Tobiq khá chuẩn kể từ ES5 (được chuẩn hóa vào năm 2009)
Johann Echavarria

for (var avg = 0, length = i = arr.length; i--;) avg += arr[i] / length

2
@Tobiq, mã của bạn là bất cứ điều gì nhưng rõ ràng. Kiểu vòng lặp này không thể hiểu được ngay từ cái nhìn đầu tiên.
Porkopek

5

Một cách lén lút bạn có thể làm điều đó mặc dù nó yêu cầu sử dụng eval (rất ghét).

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

Chỉ cần nghĩ rằng tôi sẽ đăng bài này như một trong những tùy chọn 'bên ngoài hộp'. Bạn không bao giờ biết, sự ranh mãnh có thể cho bạn (hoặc lấy đi) một điểm.


+1 Một lớp lót hiệu quả đẹp! Nếu đó là Javascript trên trình duyệt phía máy khách, eval()vấn đề duy nhất tôi có thể thấy là bạn cần chắc chắn rằng mảng chỉ chứa các số (tất nhiên điều này cũng đúng với tất cả các câu trả lời khác ở đây). Các mục không phải là số bị sập với một ReferenceErrorhoặc SyntaxError, except nested arrays of numbers which introduce , `gây ra tổng số không chính xác. Và tất nhiên trong JS phía máy chủ, ví dụ: node.js, sau đó tự nhiên eval()có thể đưa ra các vấn đề bảo mật. Nhưng điều này có vẻ hoàn hảo cho bất kỳ sử dụng phía khách hàng có cấu trúc tốt.
user56reinstatemonica8

1
Trên thực tế có thể có một vấn đề về hiệu suất bao gồm eval()như thế này - xem phần hiệu suất của nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunder Hiểu
user56reinstatemonica8

5

Tôi sử dụng các phương pháp này trong thư viện cá nhân của mình:

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

EDIT: Để sử dụng chúng, chỉ cần hỏi mảng cho tổng hoặc trung bình của nó, như:

[1,2,3].sum() // = 6
[1,2,3].average() // = 2

Việc thực hiện gọn gàng mặc dù tôi đã thực hiện tổng để sử dụng vòng lặp for thay vì giảm. Vẫn rất sạch sẽ mã hóa mặc dù.
XDS

5

Trong các trình duyệt sẵn sàng ES6, polyfill này có thể hữu ích.

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

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

Bạn có thể chia sẻ phương pháp gọi giống nhau giữa Math.sum, Math.avgMath.max, như

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

bạn có thể sử dụng Math.sum như

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

hoặc nếu bạn có một mảng để tổng hợp, bạn có thể sử dụng

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

giống như

var maxOne = Math.max.apply(null,[1,2,3,4]) // 4

Thay vì thêm các phương thức vào Array.prototype, tôi nghĩ rằng thêm chủ đề vào Mathđối tượng là một lựa chọn tốt hơn - tất cả chúng đều là "trình xử lý số".
Oboo Cheng

3

Dưới đây là một bổ sung nhanh chóng cho đối tượng Toán Toán trong javascript để thêm lệnh trung bình của YouTube vào nó !!

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

Sau đó, tôi có sự bổ sung này vào đối tượng Toán Toán để nhận tổng!

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

Vì vậy, tất cả những gì bạn làm là

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

Và nơi tôi đặt mảng giữ chỗ chỉ cần truyền vào biến của bạn (Đầu vào nếu chúng là số có thể là một chuỗi vì nó phân tích cú pháp thành một số!)


1

đặt bộ đếm vòng lặp for của bạn thành 0 .... bạn đang nhận phần tử 9 và sau đó bạn đã hoàn thành như bạn có bây giờ. Các câu trả lời khác là toán cơ bản. Sử dụng một biến để lưu trữ tổng của bạn (cần truyền chuỗi thành ints) và chia cho chiều dài mảng của bạn.


1

Bắt đầu bằng cách xác định tất cả các biến chúng tôi dự định sử dụng. Bạn sẽ lưu ý rằng đối với numbersmảng, tôi đang sử dụng ký hiệu theo nghĩa đen []trái ngược với phương thức xây dựng array(). Ngoài ra, tôi đang sử dụng một phương pháp ngắn hơn để đặt nhiều biến thành 0.

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

Tiếp theo, tôi điền vào mảng số trống của mình với các giá trị 0 đến 11. Điều này là để đưa tôi đến điểm bắt đầu ban đầu của bạn. Lưu ý cách tôi đang đẩy lên mảng count++. Điều này đẩy giá trị hiện tại của số đếm, và sau đó tăng nó cho lần tiếp theo.

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

Cuối cùng, tôi đang thực hiện một chức năng "cho mỗi" số trong mảng số. Hàm này sẽ xử lý một số tại một thời điểm mà tôi xác định là "n" trong thân hàm.

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

Cuối cùng, chúng ta có thể xuất cả sumgiá trị và avggiá trị cho bảng điều khiển của mình để xem kết quả:

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

Xem nó trong hành động trực tuyến tại http://jsbin.com/unukoj/3/edit


1

Tôi chỉ đang xây dựng dựa trên câu trả lời của Abdennour TOUMI. Dưới đây là những lý do tại sao:

1.) Tôi đồng ý với Brad, tôi không nghĩ nên mở rộng đối tượng mà chúng tôi không tạo ra.

2.) array.lengthlà chính xác đáng tin cậy trong javascript, tôi thích Array.reducebeacuse a=[1,3];a[1000]=5;, bây giờ a.lengthsẽ trở lại 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; 
};

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

Sau đó :

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

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

1

Trên các trình duyệt thường xanh, bạn có thể sử dụng các chức năng mũi tên avg = [1,2,3].reduce((a,b) => (a+b);

Chạy nó 100.000 lần, chênh lệch thời gian giữa cách tiếp cận vòng lặp for và giảm là không đáng kể.

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


1
Bạn cần tìm hiểu thêm về console.time&console.timeEnd
Abdennour TOUMI

@AbdennourTOUMI Cảm ơn vì tiền boa, tôi sẽ ghi nhớ ... tuy nhiên nó không chuẩn và không theo dõi tiêu chuẩn. developer.mozilla.org/en-US/docs/Web/API/Console/timeEnd
Ray Foss

1
Tôi biết tôi đang bỏ qua các câu hỏi ban đầu nhưng làm thế nào về việc sử dụng Performance.now () cho các phép đo hiệu suất?
deejbee

@deejbee Điều đó mang lại độ chính xác của dấu phẩy động ... nhưng nó cũng dài dòng hơn và ít tương thích hơn. Đặt điểm đánh dấu với nó sẽ hữu ích trong mã thế giới thực
Ray Foss

1

Trung bình ngắn nhất một lót:

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

Sum ngắn nhất một lót:

let sum = [1,2,3].reduce((a,b)=>a+b);

0

Chỉ để đá:

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

0

Tôi nghĩ rằng chúng ta có thể làm như

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

Tôi đang sử dụng parseFloat hai lần vì khi 1) bạn thêm số (a) 9 + b ("1") thì kết quả sẽ là "91" nhưng chúng tôi muốn thêm. vì vậy tôi đã sử dụng parseFloat

2) Khi thêm (a) 9 + parseFloat ("1") xảy ra mặc dù kết quả sẽ là "10" nhưng nó sẽ nằm trong chuỗi mà chúng tôi không muốn nữa nên tôi đã sử dụng parseFloat.

Tôi hy vọng tôi rõ ràng. Đề nghị được chào đón


0

Đây là cách tân binh của tôi chỉ đơn giản là tìm avg. Hy vọng điều này sẽ giúp ai đó.

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

0

đây là một lớp lót của bạn:

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

0

Tôi nghĩ rằng đây có thể là một giải pháp trực tiếp để tính trung bình với một vòng lặp for và hàm.

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

0

Dường như có vô số giải pháp cho việc này nhưng tôi thấy điều này thật súc tích và thanh lịch.

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

Hoặc chính xác hơn:

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

Tùy thuộc vào trình duyệt của bạn, bạn có thể cần thực hiện các cuộc gọi chức năng rõ ràng vì các chức năng mũi tên không được hỗ trợ:

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

Hoặc là:

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

Bạn đang thực hiện N phân chia trong chức năng bản đồ. Trước tiên, tốt hơn là giảm tất cả các số thành tổng giá trị và sau đó chỉ thực hiện một bộ phận
Eugenio

0

Nếu bạn đang cần trung bình và có thể bỏ qua yêu cầu tính tổng, bạn có thể tính trung bình với một lệnh giảm:

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

0

Nếu bất cứ ai cần nó - Đây là một trung bình đệ quy.

Trong ngữ cảnh của câu hỏi ban đầu, bạn có thể muốn sử dụng mức trung bình đệ quy nếu bạn cho phép người dùng chèn các giá trị bổ sung và không phải chịu chi phí truy cập lại từng yếu tố, muốn "cập nhật" mức trung bình hiện có.

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

Làm sao:

điều này hoạt động bằng cách duy trì mức trung bình và yếu tố hiện tại. Khi bao gồm một giá trị mới, bạn tăng số đếm lên 1, chia tỷ lệ trung bình hiện có theo (count-1) / countvà thêm newValue / countvào trung bình.

Những lợi ích:

  • bạn không tổng hợp tất cả các yếu tố, có thể dẫn đến số lượng lớn không thể được lưu trữ trong một float 64 bit.
  • bạn có thể "cập nhật" mức trung bình hiện có nếu các giá trị bổ sung có sẵn.
  • bạn có thể thực hiện trung bình cán mà không cần biết chiều dài chuỗi.

Nhược điểm:

  • phát sinh nhiều bộ phận hơn
  • không vô hạn - giới hạn ở các mục Number.MAX_SAFE_INTEGER trừ khi bạn sử dụng BigNumber

-1

Trung bình nội dung HTML itens

Với jQuery hoặc Javascript, querySelectorbạn có thể truy cập trực tiếp vào dữ liệu được tạo thành ... Ví dụ:

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

Vì vậy, với jQuery bạn có

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

Xem thêm 4 cách khác (!) Để truy cập itens và tính trung bình: http://jsfiddle.net/4fLWB/


2
Downvote vì OP yêu cầu làm X và bạn đã nói với anh ấy cách làm Y rồi X. Ngoài ra, ý tưởng lấy dữ liệu từ DOM thay vì tạo DOM từ dữ liệu có vẻ như là điều gì đó bạn có thể muốn tránh.
eremzeit

Xin chào @eremzeit, cảm ơn sự chú ý. Tôi sử dụng tiêu đề in đậm để nói "đó là trường hợp khác, với nội dung thành HTML", vui lòng xem xét nó ... Về mức độ liên quan, loại sử dụng này (truy cập trực tiếp dữ liệu từ HTML mà người dùng thấy) không phải là một trò chơi hàn lâm ... Đó là về "sự thật có thể nghe được", đó là HTML (!), Không phải "ẩn với con người" tại javascript ... Không chỉ tại Wikipedia, hãy xem các trường hợp điển hình: 3,7 triệu bài báo khoa học tại PMC , 6,6 TRIỆU tài liệu lập pháp tại LexML . Một số người không chỉ thiết kế và trò chơi với js, làm công cụ để kiểm toán.
Peter Krauss

-1

var mảng = [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 (mảng) ====== >>>> 3

Điều này hoạt động với các chuỗi như số hoặc số trong mảng.


Một số giải thích về câu trả lời của bạn là theo thứ tự.
David Hoelzer

Bạn đã đúng: định nghĩa tổng là một số để điều này hoạt động ngay bây giờ. Cung cấp cho hàm một mảng và nó phun ra mức trung bình của mảng.
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);

1
Chào mừng bạn đến với Stack Overflow. Câu trả lời của bạn nên giải thích chi tiết tại sao và làm thế nào nó trả lời câu hỏi. Trong khi các đoạn mã được khuyến khích, bạn nên giải thích mã để khách truy cập có thể hiểu nó. Có một cách trả lời hướng dẫn tại đây: stackoverflow.com/help/how-to-answer
ChrisM

-3

Tôi muốn giới thiệu D3 trong trường hợp này. Nó là dễ đọc nhất (và cung cấp 2 loại trung bình khác nhau)

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

4
Gosh thêm toàn bộ D3 chỉ để làm việc trung bình là vô lý
gotofritz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.