JavaScript 数组从索引开始减少

问题描述 投票:0回答:5

这个问题已经困扰我一段时间了,我似乎无法在网络上找到答案。

是否可以使用从某个索引开始的数组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 ...
}

但是假设我需要得到一个平均成绩,它是所有整数的总和除以整数计数。如果数组只包含整数,那么使用 reduce 就没有问题。

var onlyIntegersArr = [5,2,3,4];
var averageGrade = onlyIntegersArr.reduce(function(a,b){
  return a + b;
}) / onlyIntegersArr.length;

但是,如果我知道出于某种原因,我需要跳过前两个数组元素并从索引 Array[2] 开始。

例如,我会将 reduce 应用于 studentGrades,但仅从索引 StudentGrades[2] 开始。

reduce可以吗?

谢谢您的解决方案,我喜欢slice方法,但我不喜欢在这种情况下使用新方法。

例如

var average = studentGrades.reduce(function(a,b,i){
  return i >= 2 ? a+b : 0;
}) / (studentGrades.length - 2);
javascript arrays reduce
5个回答
20
投票

reduce的第三个参数是一个索引,这是fiddle

var averageGrade = onlyIntegersArr.reduce(function (a, b, c) {
    if (c >= 2) {
        return a + b;
    } else {
        return 0;
    }
});

如果数组在第二个索引之后有更多非数字项,则检查此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);

11
投票

如果您知道要跳过第一个

n
元素,您可以使用
Array#slice

使用ES2015 箭头函数

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;


0
投票

如果您确定始终只需要索引 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;

0
投票

为什么你把事情搞得太复杂了?为什么不:

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

也许您需要考虑将数据保存在对象中,其中所有成绩都位于单独的数组中。其他数据位于属性中。您可以从拥有的数组中序列化它,然后使用该对象。


0
投票

谢谢大家的回复。 我已经重新编写了代码,因此我有了一个完整的工作版本,以实现我想要实现的目标。

我的代码看起来有点冗长,只是想知道是否有一个更干净、更快的版本来标记它。

student         = [];
student[0]  = {};
student[0].grades   = [2,8,10,12,14,5];
student[0].total    = 0;

student[1]  = {};
student[1].grades   = [0,11,4,3,9];
student[1].total    = 0;

student[2]  = {};
student[2].grades   = [3,15,1,5,9];
student[2].total    = 0;

student[3]  = {};
student[3].grades = [2,10, 12, 1];
student[3].total    = 0;

for(n=0; n<student.length; n++){
  totalGrades = 0;
  /* Check if .grades matches the criteria */
  if(student[n].grades[0]!=0 && student[n].grades[0]<10){
    totalGrades = totalGrades + student[n].grades[0];
  };
  
    a1 = student[n].grades.slice(1);
  
  for(a=0; a<a1.length; a++){
    if(a1[a]<10){
        /* Add grades less than 10 */
        totalGrades = totalGrades + a1[a];
    };
  };
  
  console.log("Student: "+n+"] "+a1+"   :: Total "+totalGrades+" Original in tact: "+student[n].grades+"<br/>");
  
};

© www.soinside.com 2019 - 2024. All rights reserved.