จะคำนวณผลรวมและค่าเฉลี่ยขององค์ประกอบในอาร์เรย์ได้อย่างไร?


177

ฉันมีปัญหาในการเพิ่มองค์ประกอบทั้งหมดของอาร์เรย์รวมถึงค่าเฉลี่ยพวกเขาออก ฉันจะทำสิ่งนี้และนำไปใช้กับรหัสที่ฉันมีอยู่ในปัจจุบันได้อย่างไร องค์ประกอบที่ควรจะกำหนดตามที่ฉันมีมันด้านล่าง

<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]จะดีกว่ามาก
James McLaughlin

คำตอบ:


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

เพียงวนซ้ำผ่านอาร์เรย์เนื่องจากค่าของคุณเป็นสตริงพวกเขาจะต้องถูกแปลงเป็นจำนวนเต็มก่อน และค่าเฉลี่ยเป็นเพียงผลรวมของค่าหารด้วยจำนวนของค่า


13
การปรับปรุงเดียวที่ฉันจะทำคือแทนที่for(var i = 0; i < elmt.length; i++;)ด้วยfor(var i = 0, l = elmt.length; i < l; i++)
Dan D.

5
เพื่อไม่ให้เป็นคนนั้นหรือเป็นหัวข้อที่ปิด แต่เป็นการดีที่จะรวมอาร์กิวเมนต์ radix ใน parseInt () โดยที่ฉันหมายถึงsum += parseInt(elmt[i], 10);สมมติว่า elmt [i] เป็นของฐาน 10 link
Ryder Brooks

9
ระวังแผนกโดย 0 (elmt.length อาจ 0)
caulitomaz

2
@BramVanroy เรื่องสั้น: ไม่มันไม่ได้ตั้งค่า 'l' ทุกครั้ง เรื่องยาว: โซลูชันของ DanD คือการปรับปรุงประสิทธิภาพ / ความเร็วเนื่องจากการตรวจสอบความยาวของอาร์เรย์ทุกการวนซ้ำครั้งเดียวช้ากว่าการเก็บความยาวในตัวแปรท้องถิ่นและอ้างอิงแต่ละการวนซ้ำ
CatalinBerta

9
@VitoGentile และ DanD สร้างรหัสเพื่อเพิ่มประสิทธิภาพการทำงานซึ่งเบราว์เซอร์สมัยใหม่รวบรวมออกไปอย่างไรก็ตามไม่ควรใช้วิธีปฏิบัติที่ดีที่สุด
nauti

496

วิธีการแก้ปัญหาที่ฉันคิดว่าสวยงามมากขึ้น:

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
สิ่งนี้จะไม่ทำงานใน <= IE8 เนื่องจากไม่รองรับ Array.prototype.reduce () ดูเพิ่มเติมได้ที่developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

14
ด้วยค่าเฉลี่ยเคลื่อนที่สะสมคุณสามารถทำได้ทั้งหมดภายในฟังก์ชั่นลด (ไม่จำเป็นต้องมีsum/times.lengthขั้นตอน):var avg = times.reduce(function(p,c,i){return p+(c-p)/(i+1)},0);
zamnuts

6
@ zamnuts ฉันอยู่กับคุณฉันคิดว่าความคิดเห็นของ Thor84no ไม่เป็นระเบียบ - ฉันยินดีที่จะถูกไล่ออกจากสถานที่ซึ่งพบว่าอาร์เรย์ลดความซับซ้อนเกินไป อย่างไรก็ตามฉันจะไม่ใช้รหัสของคุณอย่างใดอย่างหนึ่งเนื่องจากมีการแบ่งและการเพิ่มเติมสองอย่างในขั้นตอนเดียวซึ่งจะไม่มีประสิทธิภาพเท่าการหารเดียวในตอนท้าย
gotofritz

12
ใน ES2015 มันดูหรูหรากว่านี้นิดหน่อย times.reduce((a,b) => (a+b)) / times.length;
Ray Foss

12
@furf 5 ปีต่อมาดูเหมือนว่าในเบราว์เซอร์ที่ทันสมัยหลายแห่งยิ่งลด "" () ได้เร็วขึ้น (หรือเร็ว) ใน Chrome 65 และการลด Firefox ส่วนใหญ่ดีกว่าในการทดสอบนั้น
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);


3
ปรับปรุงแล้ว: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
โปรดอย่าขยายวัตถุที่ไม่ได้สร้างโดยรหัสของคุณ
แบรด

1
การอัปเดตไม่ทำงานสำหรับ: ["RER", "4", "3re", 5, วัตถุใหม่ ()]. ​​ปานกลาง (); ผลตอบแทน 0 แทนการคาดหวัง 4.5
Luckylooke

4
และสิ่งนี้จะผิดพลาดอย่างใหญ่หลวงเมื่อไม่มีความยาว
Jimmy Kane

2
@JimmyKane NaNไม่มีก็จะกลับมา
bzeaman

37

การคำนวณค่าเฉลี่ย (หมายถึง) โดยใช้การลดและ ES6:

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

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

ช้ามากมากเมื่อเทียบกับการเพิ่มลูปพื้นฐานแบบง่ายกับตัวแปรผลรวมjsben.ch/0xUus
PirateApp

นี่คือความแตกต่าง 25% ไม่เลวฉันคิดว่า
Michael

20

โดยทั่วไปแล้วการใช้การลดลงหนึ่งบรรทัดก็เป็นเช่นนี้

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

เฉพาะคำถามที่ถาม

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

รุ่นที่มีประสิทธิภาพเป็นเหมือน

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

ทำความเข้าใจกับการลดอาร์เรย์ Javascript ใน 1 นาที http://www.airpair.com/javascript/javascript-array-reduce

เมื่อ gotofritz ชี้ให้เห็นว่า Array.reduce ข้ามค่าที่ไม่ได้กำหนด ดังนั้นนี่คือการแก้ไข:

(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 สามารถเขียนได้เช่นนี้ elements.length || 1 ซึ่งสั้นกว่าและอ่านง่ายกว่า
4rzael

2
โปรดจำไว้ว่านี่ใช้งานได้กับอาร์เรย์ที่ไม่มีช่องว่างเท่านั้น
gotofritz

1
คำแนะนำ: เพิ่มตัวอย่างโค้ดของคุณในเวอร์ชันที่ไม่รู้จัก (จริง ๆ แล้วสวย) เพื่อให้ผู้คนสามารถอ่านได้ ฉันจะแก้ไขด้วยตัวเอง แต่ฉันไม่ต้องการเปลี่ยนคำตอบของผู้คนในระดับนั้น
Justin Morgan

16

ลองจินตนาการว่าเรามีจำนวนเต็มเช่นนี้:

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

ค่าเฉลี่ยจะได้รับด้วยสูตรต่อไปนี้

A = (1 / n) Σxi (กับ i = 1 ถึง n) ... ดังนั้น: x1 / n + x2 / n + ... + xn / n

เราหารค่าปัจจุบันตามจำนวนของค่าและเพิ่มผลลัพธ์ก่อนหน้านี้เป็นค่าที่ส่งคืน

ลายเซ็นวิธีการลดคือ

reduce(callback[,default_previous_value])

ฟังก์ชันลดการเรียกกลับใช้พารามิเตอร์ต่อไปนี้:

  • p : ผลลัพธ์ของการคำนวณก่อนหน้า
  • c : ค่าปัจจุบัน (จากดัชนีปัจจุบัน)
  • i : ค่าดัชนีขององค์ประกอบอาร์เรย์ปัจจุบัน
  • a : Array ลดลงในปัจจุบัน

พารามิเตอร์การลดที่สองคือค่าเริ่มต้น ... (ใช้ในกรณีที่อาร์เรย์ว่างเปล่า )

ดังนั้นวิธีลดค่าเฉลี่ยจะเป็น:

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

หากคุณต้องการคุณสามารถสร้างฟังก์ชั่นแยกต่างหาก

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

และจากนั้นก็อ้างถึงลายเซ็นวิธีการโทรกลับ

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

หรือเพิ่มต้นแบบ Array โดยตรง ..

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

เป็นไปได้ที่จะแบ่งค่าแต่ละครั้งที่เรียกว่าลด

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

หรือดียิ่งขึ้นโดยใช้Array.protoype.sum ที่กำหนดไว้ก่อนหน้า

วิธีการเพิ่มประสิทธิภาพกระบวนการของฉันโทรหารเพียงครั้งเดียว :)

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

จากนั้นบนวัตถุ Array ใด ๆ ของขอบเขต:

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

NB: อาร์เรย์ว่างเปล่าที่มีการส่งคืนความต้องการของ NaN นั้นถูกต้องมากกว่า 0 ในมุมมองของฉันและสามารถเป็นประโยชน์ในกรณีการใช้งานเฉพาะ


13

นอกจากนี้คุณยังสามารถใช้lodash , _.sum (array) และ _.mean (array) ในส่วน Math (ยังมีสิ่งอำนวยความสะดวกอื่น ๆ )

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

6

ไม่ใช่เร็วที่สุด แต่สั้นที่สุดและในหนึ่งบรรทัดกำลังใช้แผนที่ () & ลด ():

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

1
อาจจะสั้นลง[7,14,21].reduce((avg,e,i,arr)=>avg+e/arr.length,0);แต่มีพฤติกรรมที่แตกต่างกันในอาเรย์ที่ว่างเปล่า หากคุณต้องการให้ผลลัพธ์ว่างเปล่าในอาเรย์ที่ว่างเปล่า:[].reduce((a,e,i,arr)=>(a?a:0)+e/arr.length,"")
Valen

แผนที่ @Tobiq & ลดเป็นมาตรฐานตั้งแต่ ES5 (มาตรฐานในปี 2009)
โยฮันน์ Echavarria

for (var avg = 0, length = i = arr.length; i--;) avg += arr[i] / lengthชัดเจนสั้นและเร็วกว่ามาก
Tobiq

2
@Tobiq รหัสของคุณคืออะไร แต่ชัดเจน การวนซ้ำประเภทนี้ไม่สามารถเข้าใจได้อย่างรวดเร็วในตอนแรก
Porkopek

5

วิธีการลับๆล่อๆอย่างหนึ่งที่คุณสามารถทำได้แม้ว่าจะต้องใช้ 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/>");

แค่คิดว่าฉันโพสต์สิ่งนี้เป็นหนึ่งในตัวเลือก 'นอกกรอบ' คุณไม่เคยรู้เลยความเขินอายอาจทำให้คุณ (หรือเอาไป)


+1 ดีมีประสิทธิภาพหนึ่งซับ! หากเป็นจาวาสคริปต์ในเบราว์เซอร์ฝั่งไคลเอ็นต์eval()ปัญหาที่เป็นไปได้เพียงอย่างเดียวที่ฉันเห็นคือคุณต้องแน่ใจว่าอาเรย์นั้นมีตัวเลขเท่านั้น (ซึ่งแน่นอนว่าเป็นจริงสำหรับคำตอบอื่น ๆ รายการที่ไม่ใช่ตัวเลขขัดข้องด้วยReferenceErrorหรือSyntaxError, except nested arrays of numbers which introduce , `ก่อให้เกิดผลรวมตัวเลขที่ไม่ถูกต้อง และแน่นอนในฝั่งเซิร์ฟเวอร์ JS เช่น node.js โดยธรรมชาติแล้วeval()อาจมีปัญหาด้านความปลอดภัย แต่สิ่งนี้ดูสมบูรณ์แบบสำหรับการใช้งานที่มีโครงสร้างของลูกค้า
user56reinstatemonica8

1
ที่จริงมีอาจจะเป็นปัญหารวมทั้งประสิทธิภาพการทำงานให้eval()เช่นนี้ - ดูที่ส่วนประสิทธิภาพการทำงานของnczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood
user56reinstatemonica8

5

ฉันใช้วิธีการเหล่านี้ในห้องสมุดส่วนตัวของฉัน:

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

แก้ไข: หากต้องการใช้พวกเขาเพียงขอผลรวมหรือค่าเฉลี่ยของอาร์เรย์เช่น:

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

การนำไปปฏิบัติที่เรียบร้อยแม้ว่าฉันจะใช้ผลรวมเพื่อใช้สำหรับลูปแทนการลด ยังคงเขียนรหัสอย่างสะอาดหมดจด
XDS

5

ในเบราว์เซอร์ที่พร้อมใช้ ES6 polyfill นี้อาจมีประโยชน์

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

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

คุณสามารถแบ่งปันวิธีการโทรระหว่างเดียวกันMath.sum, Math.avg และMath.maxเช่น

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

คุณสามารถใช้ Math.sum เป็น

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

หรือถ้าคุณมีอาร์เรย์ที่จะสรุปคุณสามารถใช้

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

เหมือนกับ

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

แทนที่จะเพิ่มวิธีการArray.prototypeฉันคิดว่าการเพิ่มชุดรูปแบบไปยังMathวัตถุเป็นตัวเลือกที่ดีกว่า - ทั้งหมดเป็น "ตัวจัดการหมายเลข"
Oboo Cheng

3

นี่คือการเพิ่มอย่างรวดเร็วไปยังวัตถุ "คณิตศาสตร์" ในจาวาสคริปต์เพื่อเพิ่มคำสั่ง "เฉลี่ย" ไป !!

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

จากนั้นฉันก็เพิ่มส่วนนี้ลงในวัตถุ“ คณิตศาสตร์” เพื่อให้ได้ผลรวม!

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

ดังนั้นสิ่งที่คุณต้องทำก็คือ

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

และที่ฉันใส่อาร์เรย์ตัวยึดเพียงผ่านในตัวแปรของคุณ (การป้อนถ้าพวกเขาเป็นตัวเลขสามารถสตริงเพราะมันแยกเป็นตัวเลข!)


1

ตั้งค่าของคุณสำหรับการวนรอบเคาน์เตอร์เป็น 0 ... คุณจะได้รับองค์ประกอบที่ 9 จากนั้นทำตามที่คุณมีในตอนนี้ คำตอบอื่น ๆ คือคณิตศาสตร์ขั้นพื้นฐาน ใช้ตัวแปรเพื่อเก็บผลรวมของคุณ (จำเป็นต้องใช้สตริงเพื่อ ints) และหารด้วยความยาวอาร์เรย์ของคุณ


1

เริ่มต้นด้วยการกำหนดตัวแปรทั้งหมดที่เราวางแผนที่จะใช้ คุณจะได้ทราบว่าสำหรับnumbersอาร์เรย์ฉันใช้สัญกรณ์ที่แท้จริงของเมื่อเทียบกับวิธีการสร้าง[] array()นอกจากนี้ฉันใช้วิธีที่สั้นกว่าเพื่อตั้งค่าตัวแปรหลายตัวเป็น 0

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

ต่อไปฉันจะเติมอาเรย์ตัวเลขที่ว่างเปล่าด้วยค่า 0 ถึง 11 นี่คือการพาฉันไปที่จุดเริ่มต้นดั้งเดิมของคุณ สังเกตว่าฉันจะผลักไปยังอาร์เรย์count++อย่างไร การกดค่าปัจจุบันของการนับแล้วจะเพิ่มขึ้นในครั้งถัดไป

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

สุดท้ายฉันกำลังทำฟังก์ชั่น "สำหรับแต่ละ" ของตัวเลขในอาร์เรย์ตัวเลข ฟังก์ชั่นนี้จะจัดการหมายเลขหนึ่งครั้งซึ่งฉันระบุเป็น "n" ภายในร่างกายฟังก์ชั่น

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

ในที่สุดเราสามารถส่งออกทั้งsumค่าและavgค่าไปยังคอนโซลของเราเพื่อดูผลลัพธ์:

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

ดูการทำงานออนไลน์ได้ที่http://jsbin.com/unukoj/3/edit


1

ฉันแค่สร้างคำตอบของ Abdennour TOUMI นี่คือเหตุผลว่าทำไม:

1. ) ฉันเห็นด้วยกับแบรดฉันไม่คิดว่ามันเป็นความคิดที่ดีที่จะขยายวัตถุที่เราไม่ได้สร้าง

2. ) array.lengthเป็นสิ่งที่เชื่อถือได้ใน javascript, ฉันชอบArray.reduceเพราะว่าa=[1,3];a[1000]=5;ตอนนี้จะกลับมาa.length1001

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

จากนั้น:

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

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

1

ในเบราว์เซอร์เอเวอร์กรีนคุณสามารถใช้ฟังก์ชั่นลูกศร avg = [1,2,3].reduce((a,b) => (a+b);

เรียกใช้ 100,000 ครั้งความแตกต่างของเวลาระหว่าง for วนเข้าใกล้และลดจะน้อยมาก

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
คุณต้องเรียนรู้เพิ่มเติมเกี่ยวกับconsole.time&console.timeEnd
Abdennour TOUMI

@AbdennourTOUMI ขอบคุณสำหรับเคล็ดลับฉันจะเก็บไว้ในใจ ... แต่มันไม่ได้มาตรฐานและไม่ได้อยู่ในการติดตามมาตรฐาน developer.mozilla.org/en-US/docs/Web/API/Console/timeEnd
Ray Foss

1
ฉันรู้ว่าฉันไม่สนใจคำถามเดิม แต่ใช้การวัดประสิทธิภาพ () เพื่อวัดประสิทธิภาพได้อย่างไร
deejbee

@deejbee นั่นให้ความแม่นยำของจุดลอยตัว ... แต่มันก็มีความละเอียดมากกว่าและเข้ากันได้น้อยกว่า การตั้งเครื่องหมายด้วยมันจะมีประโยชน์ในรหัสโลกแห่งความจริง
Ray Foss

1

ซับที่สั้นที่สุดโดยเฉลี่ย:

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

0

เพียงเพื่อเตะ:

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

ฉันคิดว่าเราทำได้

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

ฉันใช้ parseFloat สองครั้งเพราะเมื่อ 1) คุณเพิ่ม (a) 9 + b ("1") จำนวนผลลัพธ์จะเป็น "91" แต่เราต้องการการเพิ่ม ดังนั้นฉันใช้ parseFloat

2) เมื่อมีการเพิ่ม (a) 9 + parseFloat ("1") แม้ว่าผลลัพธ์จะเป็น "10" แต่มันจะเป็นสตริงซึ่งเราไม่ต้องการอีกเลยฉันใช้ parseFloat อีกครั้ง

ฉันหวังว่าฉันชัดเจน ข้อเสนอแนะยินดีต้อนรับ


0

นี่คือวิธีการใหม่ของฉันในการหาค่าเฉลี่ย หวังว่านี่จะช่วยใครซักคน

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


0

ฉันคิดว่านี่อาจเป็นคำตอบโดยตรงในการคำนวณค่าเฉลี่ยด้วยลูปและฟังก์ชั่น

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

ดูเหมือนจะมีวิธีการแก้ปัญหาที่ไม่มีที่สิ้นสุดสำหรับเรื่องนี้ แต่ฉันพบว่ามันกระชับและสง่างาม

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

หรือมากกว่ารัดกุม:

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

ขึ้นอยู่กับเบราว์เซอร์ของคุณคุณอาจต้องทำการเรียกใช้ฟังก์ชั่นอย่างชัดเจนเนื่องจากไม่รองรับฟังก์ชั่นลูกศร:

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

หรือ:

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

คุณกำลังสร้างส่วน N ในฟังก์ชันแผนที่ เป็นการดีกว่าถ้าคุณลดจำนวนทั้งหมดเป็นค่ารวมก่อนแล้วจึงทำการหารเพียงส่วนเดียว
Eugenio

0

หากคุณต้องการค่าเฉลี่ยและสามารถข้ามข้อกำหนดในการคำนวณผลรวมคุณสามารถคำนวณค่าเฉลี่ยด้วยการลดจำนวนครั้งเดียว:

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

ถ้าใครต้องการมัน - นี่คือค่าเฉลี่ยแบบเรียกซ้ำ

ในบริบทของคำถามเดิมคุณอาจต้องการใช้ค่าเฉลี่ยแบบเรียกซ้ำถ้าคุณอนุญาตให้ผู้ใช้ใส่ค่าเพิ่มเติมและโดยไม่ต้องเสียค่าใช้จ่ายในการเยี่ยมชมแต่ละองค์ประกอบอีกครั้งต้องการที่จะ "อัพเดท" ค่าเฉลี่ยที่มีอยู่

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

วิธี:

ทำงานได้โดยการรักษาค่าเฉลี่ยและจำนวนองค์ประกอบปัจจุบัน เมื่อมีการรวมค่าใหม่ให้คุณนับการเพิ่มขึ้น 1 ให้ไต่ระดับค่าเฉลี่ยที่มีอยู่ด้วย(count-1) / countและเพิ่มnewValue / countในค่าเฉลี่ย

ประโยชน์ที่ได้รับ:

  • คุณไม่ได้รวมองค์ประกอบทั้งหมดซึ่งอาจส่งผลให้มีจำนวนมากที่ไม่สามารถเก็บไว้ในการลอย 64 บิต
  • คุณสามารถ "อัปเดต" ค่าเฉลี่ยที่มีอยู่หากมีค่าเพิ่มเติมพร้อมใช้งาน
  • คุณสามารถทำการหมุนเฉลี่ยโดยไม่ทราบความยาวของลำดับ

ข้อเสีย:

  • เพิ่มจำนวนมากขึ้น
  • ไม่ใช่อนันต์ - จำกัด เฉพาะที่ Number.MAX_SAFE_INTEGER รายการเว้นแต่คุณจะจ้าง BigNumber

-1

ค่าเฉลี่ยของเนื้อหา HTML itens

ด้วย jQuery หรือ Javascript querySelectorคุณมี acess โดยตรงไปยังข้อมูลที่จัดรูปแบบ ... ตัวอย่าง:

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

ดังนั้นด้วย jQuery คุณมี

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

ดูวิธีอื่น ๆ อีก 4 วิธี (!) เพื่อเข้าถึง itens และหาค่าเฉลี่ย: http://jsfiddle.net/4fLWB/


2
Downvote เนื่องจาก OP ขอให้ทำ X และคุณบอกเขาว่าให้ทำอย่างไรกับ Y แล้ว X นอกจากนี้แนวคิดในการดึงข้อมูลจาก DOM แทนที่จะสร้าง DOM จากข้อมูลดูเหมือนจะเป็นสิ่งที่คุณอาจต้องการหลีกเลี่ยง
eremzeit

สวัสดี @eremzeit ขอบคุณความสนใจ ฉันใช้ชื่อตัวหนาเพื่อพูดว่า "เป็นกรณีอื่นที่มีเนื้อหาเป็น HTML" โปรดพิจารณา ... เกี่ยวกับที่เกี่ยวข้องการใช้งานประเภทนี้ (การเข้าถึงข้อมูลโดยตรงจาก HTML ที่ผู้ใช้เห็น) ไม่ใช่เกมวิชาการ ... มันเป็นเรื่องเกี่ยวกับ "ความจริงที่ตรวจสอบได้" ซึ่งเป็น HTML (!) ไม่ใช่ "ซ่อนเร้นจากมนุษย์" ที่จาวาสคริปต์ ... ไม่เพียง แต่ในวิกิพีเดียดูกรณีทั่วไป: 3.7 ล้านบทความทางวิทยาศาสตร์ที่ PMC , 6.6 ล้านเอกสารทางกฎหมาย LexML บางคนไม่เพียง แต่ออกแบบและเล่นเกมกับ js ทำเครื่องมือสำหรับการตรวจสอบ
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;
}

เฉลี่ย (arr) ====== >>>> 3

ใช้งานได้กับสตริงเป็นตัวเลขหรือตัวเลขในอาเรย์


คำอธิบายบางคำตอบของคุณเป็นไปตามลำดับ
David Hoelzer

คุณพูดถูก: กำหนดผลรวมเป็นตัวเลขเพื่อให้ใช้งานได้ในขณะนี้ ฟีดอาร์เรย์และแยกค่าเฉลี่ยของอาร์เรย์
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
ยินดีต้อนรับสู่ Stack Overflow คำตอบของคุณควรอธิบายโดยละเอียดว่าทำไมและอย่างไรที่ตอบคำถาม ในขณะที่มีการสนับสนุนข้อมูลโค้ดคุณควรอธิบายโค้ดเพื่อให้ผู้เข้าชมสามารถเข้าใจได้ มีวิธีตอบคำแนะนำได้ที่นี่: stackoverflow.com/help/how-to-answer
ChrisM

-3

ฉันจะแนะนำ D3 ในกรณีนี้ มันสามารถอ่านได้มากที่สุด (และมีค่าเฉลี่ย 2 แบบ)

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 การเพิ่ม D3 ทั้งหมดเพื่อการออกกำลังกายโดยเฉลี่ยนั้นไร้สาระ
gotofritz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.