JavaScript array reduce 从索引开始
JavaScript array reduce start from index
这个问题已经困扰我一段时间了,我似乎无法在网上找到答案。
是否可以从某个索引开始使用Array reduce方法?
简单的例子
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
如果我只需要遍历 studentGrades 中的整数,我可以用一个简单的 for 循环来做到这一点
for(var i = 2; i < studentGrades.length; i++) {
// do stuff here ...
}
但是假设我需要得到一个平均成绩,即所有整数的总和除以整数计数。如果 Array 只包含整数,那么使用 reduce 就没有问题。
var onlyIntegersArr = [5,2,3,4];
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
但是,如果我知道出于某种原因我需要跳过前两个数组元素并从索引数组 [2] 开始。
例如,我会将 reduce 应用于 studentGrades,但仅从索引 studentGrades[2].
开始
reduce 有可能吗?
感谢您提供解决方案,我喜欢 slice 方法,但我不希望在这种情况下使用新方法。
例如
var average = studentGrades.reduce(function(a,b,i){
return i >= 2 ? a+b : 0;
}) / (studentGrades.length - 2);
reduce's 3rd argument is an index, here is the fiddle
var averageGrade = onlyIntegersArr.reduce(function (a, b, c) {
if (c >= 2) {
return a + b;
} else {
return 0;
}
});
如果数组在第二个索引后有更多 non-numeric 项,则检查此 fiddle
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9, "Some School"];
var averageGrade = studentGrades.reduce(function (a, b, c) {
if (c >= 2 && !isNaN(b)) {
return a + b;
} else if (c >= 2) {
return a + 0;
} else {
return 0;
}
})
alert(averageGrade);
如果您知道要跳过前 n
个元素,您可以使用 Array#slice
使用 ES2015 Arrow Function
var sum = array.slice(n).reduce((a, b) => a + b);
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.slice(2).reduce((a, b) => a + b);
document.body.innerHTML = 'SUM is = ' + sum;
在ES5中,同样的代码可以使用匿名函数来编写。
var sum = array.slice(n).reduce(function(a, b) {
return a + b;
});
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.slice(2).reduce(function(a, b) {
return a + b;
});
document.body.innerHTML = 'SUM is = ' + sum;
对于您提到的情况,仅将数值相加,而不管它们在数组中的位置 - 您可以执行类似
的操作
var sum = array.reduce(function(result, v) {
return result + (parseFloat(v) || 0);
}, 0);
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.reduce(function(result, v) {
return result + (parseFloat(v) || 0);
}, 0);
document.body.innerHTML = 'SUM is = ' + sum;
如果您确定始终只需要从索引 2 开始,那么这就足够了
var onlyIntegersArr = studentGrades.slice(2);
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
但是,如果你想得到所有的整数,那么你需要过滤数组
var onlyIntegersArr = studentGrades.filter(function(val) {
return (val === parseInt(val, 10));
});
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
你为什么要把事情复杂化?为什么不呢:
function avg(arr)
{
var sum = 0;
var l = 0;
for(var i = 0; i < arr.length; i++)
{
if(isNaN(1*arr[i])) continue;
sum += arr[i];
l++;
}
return sum/l;
}
也许您需要考虑将数据保存在对象中,其中所有成绩都在一个单独的数组中。其他数据在属性中。您可以从您拥有的数组中序列化它,然后使用该对象。
这个问题已经困扰我一段时间了,我似乎无法在网上找到答案。
是否可以从某个索引开始使用Array reduce方法?
简单的例子
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
如果我只需要遍历 studentGrades 中的整数,我可以用一个简单的 for 循环来做到这一点
for(var i = 2; i < studentGrades.length; i++) {
// do stuff here ...
}
但是假设我需要得到一个平均成绩,即所有整数的总和除以整数计数。如果 Array 只包含整数,那么使用 reduce 就没有问题。
var onlyIntegersArr = [5,2,3,4];
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
但是,如果我知道出于某种原因我需要跳过前两个数组元素并从索引数组 [2] 开始。
例如,我会将 reduce 应用于 studentGrades,但仅从索引 studentGrades[2].
开始reduce 有可能吗?
感谢您提供解决方案,我喜欢 slice 方法,但我不希望在这种情况下使用新方法。
例如
var average = studentGrades.reduce(function(a,b,i){
return i >= 2 ? a+b : 0;
}) / (studentGrades.length - 2);
reduce's 3rd argument is an index, here is the fiddle
var averageGrade = onlyIntegersArr.reduce(function (a, b, c) {
if (c >= 2) {
return a + b;
} else {
return 0;
}
});
如果数组在第二个索引后有更多 non-numeric 项,则检查此 fiddle
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9, "Some School"];
var averageGrade = studentGrades.reduce(function (a, b, c) {
if (c >= 2 && !isNaN(b)) {
return a + b;
} else if (c >= 2) {
return a + 0;
} else {
return 0;
}
})
alert(averageGrade);
如果您知道要跳过前 n
个元素,您可以使用 Array#slice
使用 ES2015 Arrow Function
var sum = array.slice(n).reduce((a, b) => a + b);
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.slice(2).reduce((a, b) => a + b);
document.body.innerHTML = 'SUM is = ' + sum;
在ES5中,同样的代码可以使用匿名函数来编写。
var sum = array.slice(n).reduce(function(a, b) {
return a + b;
});
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.slice(2).reduce(function(a, b) {
return a + b;
});
document.body.innerHTML = 'SUM is = ' + sum;
对于您提到的情况,仅将数值相加,而不管它们在数组中的位置 - 您可以执行类似
的操作var sum = array.reduce(function(result, v) {
return result + (parseFloat(v) || 0);
}, 0);
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.reduce(function(result, v) {
return result + (parseFloat(v) || 0);
}, 0);
document.body.innerHTML = 'SUM is = ' + sum;
如果您确定始终只需要从索引 2 开始,那么这就足够了
var onlyIntegersArr = studentGrades.slice(2);
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
但是,如果你想得到所有的整数,那么你需要过滤数组
var onlyIntegersArr = studentGrades.filter(function(val) {
return (val === parseInt(val, 10));
});
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
你为什么要把事情复杂化?为什么不呢:
function avg(arr)
{
var sum = 0;
var l = 0;
for(var i = 0; i < arr.length; i++)
{
if(isNaN(1*arr[i])) continue;
sum += arr[i];
l++;
}
return sum/l;
}
也许您需要考虑将数据保存在对象中,其中所有成绩都在一个单独的数组中。其他数据在属性中。您可以从您拥有的数组中序列化它,然后使用该对象。