使用JS求取数组的平均值

97
我在stackoverflow上搜索,但没有找到一个简单的问题和答案来寻找数组平均值。
这是我拥有的数组。
const grades = [80, 77, 88, 95, 68];

起初,我认为解决这个问题的答案会像这样:

let avg = (grades / grades.length) * grades.length
console.log(avg)

然而,这给了我一个NaN的输出。

于是我尝试了这个:

for (let grade of grades)
    avg = (grade / grades.length) * grades.length
console.log(avg)

这给了我一个输出值为68(我不确定为什么)。

所以我有两个问题。1. 为什么我的输出是68?2. 能否有人帮我实际找到数组的平均值?

9个回答

161
ES6的语法可以将Andy的解决方案简化成一行代码:

const average = array => array.reduce((a, b) => a + b) / array.length;
console.log(average([1,2,3,4,5]));


4
不需要 (array) => 部分。 - TheTechGuy
(array) => 这部分对我来说是必需的,才能使它正常工作! - Caleb
2
如果你想让这个函数独立存在,那么你需要使用(array) =>;否则它只是一个数值(假设你已经有了一个现有的array值,并使用average而不是average(...)进行调用)。 - Nixinova
有人可以详细解释一下这是如何工作的吗? - John-Henry
我无法解释它,因为它涉及到JavaScript语法的工作方式等,这很难解释...但是我可以重新编写它,让您更清楚地了解它在做什么。myArray = [1,2,3,4]; myArray.reduce((total, current) => total + current) / myArray.length 关键在于reduce函数将遍历myArray并将值相加并存储在total中,然后返回total - vinhboy
轻微改进:https://dev59.com/T2kv5IYBdhLWcg3wxjrQ#72565782 - zumalifeguard

72

计算平均数的方法是将所有元素相加,然后除以元素的数量。

var total = 0;
for(var i = 0; i < grades.length; i++) {
    total += grades[i];
}
var avg = total / grades.length;

你得到结果68的原因是在循环中,你一直在覆盖你的平均值,所以最终的值将是你最后一次计算的结果。而且你通过grades.length除法和乘法会互相抵消。


我想指出 JavaScript 中的一个陷阱。如果你将变量 total 定义为 undefined,那么你将得到 NaN。for (let i = 0; i < grades.length; i++) { total += grades[i]; } let avg = total / grades.length; console.log(avg) ``` - pixel 67
我的 代码 没有被格式化吗? - pixel 67
一些人建议编辑此帖以使代码更简洁/更优美。我的意图不是提供在javascript中找到数组平均值的最佳方法,而是尽可能接近op的代码以指出他们做错了什么。 - bwroga

39
对于您问题的第二部分,您可以在此处很好地使用reduce:reduce

const grades = [80, 77, 88, 95, 68];

function getAvg(grades) {
  const total = grades.reduce((acc, c) => acc + c, 0);
  return total / grades.length;
}

const average = getAvg(grades);
console.log(average);

其他答案已经很好地解释了为什么你得到了68分,所以我在这里不会重复。


我可以建议使用ES7语法:const getAvg = grades => grades.reduce((p,c) => p+c) / grades.length - TOPKAT
7
如果您要使用 reduce,那么应该充分利用它的功能。array.reduce((all, one, _, src) => all += one / src.length, 0) - Braains

22

MacGyver方式,只是为了好玩

var a = [80, 77, 88, 95, 68];

console.log(eval(a.join('+'))/a.length)


5
虽然很有趣,但我认为有人可能会使用它或者说“哦!这个eval函数看起来非常强大!”因此我仍会投反对票 :) - Adam Pietrasiak
6
为什么使用eval是不好的?没有明显的安全问题=>点赞。 - Daniel W.
5
由于 eval 函数被视为不良实践,因为一些基本经验的开发者可能会滥用它,所以总是会受到反对。这种情况下,我们通常都不鼓励使用 eval 函数。请注意,这只是一种风险,并且可能会导致代码质量下降。 - alistair
1
@DanielW。这是一个糟糕的用法,因为如果程序没有仔细检查数组输入,有人可能会插入字符串并轻松执行任意代码。尝试:var a = ["alert('Some evil code.')", 77, 88, 95, 68]; console.log(eval(a.join('+'))/a.length); - Ben Zelnick

10

使用单个 reduce 操作就可以轻松完成,如下所示:

var avg = [1,2,3,4].reduce((p,c,_,a) => p + c/a.length,0);
console.log(avg)


2
就像 Vlad 的回答一样,这种方法会产生舍入误差。如果你尝试对 [1,1,1,1,1,1] 求平均值,你得到的不会是 1。 - antun
1
这是唯一一个正确处理数组为空的情况的解决方案,其他答案会因为除以0而导致“NaN”。 - Niles Tanner

9

没有内置函数,但您可以使用以下方法获取总和:

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

然后除以数组的长度,例如:

var arr = [1, 2, 3, 4, 5];
console.log(arr.sum() / arr.length)

5
var total = 0
grades.forEach(function (grade) {
    total += grade        
});
console.log(total / grades.length)

5

你可以使用的平均函数是:

const getAverage = (arr) => arr.reduce((p, c) => p + c, 0) / arr.length

此外,我建议使用流行的开源工具,例如Lodash
const _ = require('lodash')
const getAverage = (arr) => _.chain(arr)
 .sum()
 .divide(arr.length)
 .round(1)
 .value()

2
Lodash非常好...但是如果你要使用Lodash,请使用Lodash:_.mean([4, 2, 8, 6]);(另请参阅:_.meanBy https://lodash.com/docs/4.17.15#meanBy) - Marshall

1
你可以使用JavaScript的map/reduce函数来计算平均值。Reduce将它们相加,而map将找到平均值。
var avg = grades.map((c, i, arr) => c / arr.length).reduce((p, c) => c + p);

很不幸,这种方法会产生舍入误差。例如,[ 1, 1, 1, 1, 1, 1 ].map((c, i, arr) => c / arr.length).reduce((p, c) => c + p)的结果将为0.9999999999999999,而不是1。 - antun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接