我有问题添加一个数组的所有元素以及平均它们。我将如何做到这一点,并实现它与我目前的代码?元素的定义如下所示。
<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>
如果你需要平均值并且可以跳过计算和的要求,你可以通过调用reduce来计算平均值:
// 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
如果有人需要的话-这是递归平均。
在原始问题的上下文中,如果您允许用户插入额外的值,并且希望“更新”现有的平均值,而不需要再次访问每个元素,则可能需要使用递归平均值。
/**
* 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
怎样去:
这是通过维持当前的平均值和元素计数来工作的。当要包含一个新值时,将count增加1,将现有平均值按(count-1) / count缩放,并将newValue / count添加到平均值中。
好处:
您没有对所有元素求和,这可能会导致大量的元素无法存储在64位浮点数中。
如果有其他值可用,您可以“更新”现有平均值。
您可以在不知道序列长度的情况下执行滚动平均。
缺点:
导致更多的分裂
不是无限的——仅限于数量。MAX_SAFE_INTEGER项,除非使用BigNumber
除非我遗漏了什么,否则到目前为止的每个解都使用列表的长度来计算求和后的平均值。
这种方法有一个缺点,稍微修改一下,但仍然简单的算法可以解决这个缺点。
它的缺点是,通过对所有数字求和,假设不会出现溢出。如果您有很多非常大的数字,并且将它们全部加起来,它们可能会超过数据类型可以容纳的最大大小。
一个更好的方法是简单地计算平均值,而不是把它加起来,然后除以最后的长度:
function getAvg(values) {
return values.reduce((m, x, i) => m + (x - m) / (i + 1), 0)
}
道具Knuth的“计算机编程的艺术”卷2。