我有问题添加一个数组的所有元素以及平均它们。我将如何做到这一点,并实现它与我目前的代码?元素的定义如下所示。
<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>
在阅读了其他选项之后,我将尝试为未来的观众创建一个更简单的版本,详细说明现有的代码,而不是创建一个更优雅的代码。首先,您将数字声明为字符串。除了.parseInt,我们还可以做:
const numberConverter = elmt.map(Number);
map所做的就是“返回原始数组的副本”。但是我把它的值转换成数字。然后我们可以使用reduce方法(它也可以更简单,但我写的是易于阅读的版本,我也有2个平均方法)reduce方法所做的是,它有一个累加器,当它遍历数组并添加(在这种情况下)currentValue时,如果你向它添加值,它会变得越来越大。
var i;
const 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';
console.log(elmt);
const numberConverter = elmt.map(Number);
const sum = numberConverter.reduce((accumulator, currentValue) => {
return accumulator + currentValue;
}, 0);
const average = numberConverter.reduce(
(accumulator, currentvalue, index, numArray) => {
return accumulator + currentvalue / numArray.length;
},
0
);
const average2 =
numberConverter.reduce(
(accumulator, currentValue) => accumulator + currentValue,
0
) / numberConverter.length;
for (i = 9; i < 10; i++) {
console.log(
`The sum of all the elements is: ${sum}. <br> The average of all the elements is: ${average2}`
);}
在常绿浏览器上,你可以使用箭头函数
Avg = [1,2,3].reduce((a,b) => (a+b);
运行10万次,for循环方法和reduce方法之间的时间差可以忽略不计。
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.
*/
除非我遗漏了什么,否则到目前为止的每个解都使用列表的长度来计算求和后的平均值。
这种方法有一个缺点,稍微修改一下,但仍然简单的算法可以解决这个缺点。
它的缺点是,通过对所有数字求和,假设不会出现溢出。如果您有很多非常大的数字,并且将它们全部加起来,它们可能会超过数据类型可以容纳的最大大小。
一个更好的方法是简单地计算平均值,而不是把它加起来,然后除以最后的长度:
function getAvg(values) {
return values.reduce((m, x, i) => m + (x - m) / (i + 1), 0)
}
道具Knuth的“计算机编程的艺术”卷2。
如果你需要平均值并且可以跳过计算和的要求,你可以通过调用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