【问题标题】:how to iterate through nested array items separately如何分别遍历嵌套数组项
【发布时间】:2019-03-20 10:00:03
【问题描述】:

我有一个三维数组,例如:

var array = [[1,0][3,3][2,1][0,8]]

我想对每个子数组中的第一项做一些事情,但对每个子数组中的第二项做一些别的事情。

例如,我想找到array[0][0], array[1][0], array[2][0] 的总和,以此类推array.length。但是,我想要array[0][1], array[1][1], array[2][1] 等的单独结果。

我仍在学习 javascript(非常缓慢),如果可能的话,我希望指出正确的方向,而不是获得现成的解决方案。我一直在寻找可能的解决方案,我想我可能需要一个嵌套的 for 循环,但我不确定如何构造它来获取所有值。

我一直在尝试以下方式:

for (var i = 0; i < array.length; i++) {
  for (var j = 0; j < array.length; j++) {
    return array[i][j];
  }
}

但我不明白发生了什么足以操纵结果。

如果有人能引导我朝着正确的方向寻找解决方案,我将不胜感激。

提前致谢。

【问题讨论】:

  • 这行写错了:for (var j = 0; j &lt; array.length; j++) {希望我的回答对你有帮助。 :)

标签: javascript arrays for-loop multidimensional-array


【解决方案1】:

您可以考虑使用.reduce - 在每次迭代中,将第一个数组值添加到累加器的属性中,然后对第二个数组值执行任何您需要的操作,将其结果分配给累加器的另一个属性。例如,假设对于第二个项目,您想获得他们的产品:

const input = [[1,0],[3,3],[2,1],[0,8]];
const { sum, product } = input
  .reduce(({ sum=0, product=1 }, [item0, item1]) => ({
    sum: sum + item0,
    product: product * item1
  }), {});
console.log(sum, product);

在上面的代码中,累加器是一个有两个属性的对象,sum(从 0 开始)和product(从 1 开始)。在reduce 内部,返回一个对象,新的sum 是旧的sum 加上数组中的第一项,新的product 是旧的product 乘以数组中的第二项数组。 (当然,结果乘积为0,因为在第一个子数组中,第二项为0)

另请注意,数组总是需要用逗号分隔每个数组项 - 您需要修复输入数组的语法。

当然,如果需要,您也可以使用for 循环,但我认为数组方法更可取,因为它们更实用、具有更好的抽象性,并且不需要手动迭代。带有for 循环的相同代码如下所示:

const input = [[1,0],[3,3],[2,1],[0,8]];
let sum = 0;
let product = 1;
for (let i = 0; i < input.length; i++) {
  const [item0, item1] = input[i];
  sum += item0;
  product *= item1;
}
console.log(sum, product);

【讨论】:

  • 这太好了,谢谢。我可以理解底部的for 循环,但我会听从您关于数组方法的建议,了解更多关于.reduce 方法的信息,并尝试掌握上面的语法。再次感谢您的解释 - 这对初学者真的很有帮助。
  • 也感谢 sum 和 product 的变量(有两个不同的计算帮助我更好地了解发生了什么)
【解决方案2】:

您只需要一个 for 循环,因为您只有一个数组,其中包含您知道要处理的索引的数组。所以它会是这样的:

let sum1 = 0;
let sum2 = 0;
for(let i = 0; i < array.length; i++) {
    sum1 += array[i][0];
    sum2 += array[i][1];     
}
console.log('sum1: ', sum1);
console.log('sum2: ', sum2);

【讨论】:

  • 完美,谢谢!现在这更有意义了。我肯定把它复杂化了。再次感谢
【解决方案3】:

首先,您发布的数组是 2d 数组而不是 3d 数组。

您发布的嵌套 for 循环非常适合您的需求。 您的第一个 for 语句是遍历数组的第一个 deminsion。第二个是获取第二个数组中的每个索引

var array = [[1,0],[3,3],[2,1],[0,8]]
for (var i = 0; i < array.length; i++) {
  //This loop over these [1,0],[3,3],[2,1],[0,8] 
  //So i on the first loop is this object [1,0] so so on
  for (var j = 0; j < array.length; j++) {
    //This will loop over the i object
    //First loop j will be 1
    //Here is where you would do something with the index i,j. 
    //Right now you are just returning 1 on the first loop
    return array[i][j];
  }
}

希望对你的理解有所帮助

【讨论】:

  • 感谢指正,对错误深表歉意。尺寸之间的差异现在对我来说很有意义。
  • 没问题。如果您的问题得到解答,请记得将您的问题标记为已解决
【解决方案4】:

既然您寻求帮助以指明正确的方向,我建议您从简单的console.logs 开始,看看发生了什么(cmets 是内联的):

var array = [[1, 0],[3, 3],[2, 1],[0, 8]];

var results = [0, 0]; // this array is to store the results of our computation

for (var i = 0; i < array.length; i++) { // for each subarray in array
  console.log('examining subarray ', array[i]); 
  for (var j = 0; j < array[i].length; j++) { // for each element in subarray
    if (j === 0) {
      console.log('...  do something with the first element of this array, which is: ' + array[i][j]);
      results[j] += array[i][j]
    } else if (j === 1) {
      console.log('...  do something with the second element of this array, which is: ' + array[i][j]);
      // do some other computation and store it in results
    }
  }
}

console.log('Final results are ', results);

【讨论】:

  • 这真的很有用 - 谢谢。我应该让这更像是一种习惯,这样我才能更好地看到发生了什么,而不是试图在心理上存储值(!)它确实有助于将这些字符串也放在控制台中,所以谢谢
【解决方案5】:

你在第二行犯了一个错误。您需要遍历嵌套数组,然后从主数组中获取值。

const mainArray = [[1, 0], [3, 3], [2, 1], [0, 8]];

for (let i = 0; i < mainArray.length; i++) {
  const nestedArray = mainArray[i]
  for (let j = 0; j < nestedArray.length; j++) {
    const value = mainArray[i][j]
    switch(j) {
      case 0:
        console.log(`first item of array number ${i+1} has value: ${value}`)
        break;
      case 1:
        console.log(`second item of array number ${i+1} has value: ${value}`)
        break;
    }
  }
}

【讨论】:

    【解决方案6】:

    您可以像这样使用for...of 循环和解构:

    for(let [a, b] of array) {
       // a will be the first item from the subarrays: array[0][0], array[1][0], ...
       // b will be the second: : array[0][1], array[1][1], ...
    }
    

    演示:

    let array = [[1, 0], [3, 3], [2, 1], [0, 8]];
    
    for(let [a, b] of array) {
       console.log("a: " + a);
       console.log("b: " + b);
    }

    【讨论】:

      【解决方案7】:
      • 在循环中使用调试器是观察和理解循环每个步骤的好方法

      • 使用 forEach 方法将是循环遍历数组及其子项的更清晰的方法

      const items = [[1, 0],[3, 3],[2, 1],[0, 8]]
      let results = {}
      
      items.forEach((item, index) => {
        // debugger;
        item.forEach((subItem, subIndex) => {
          // debugger;
          if (results[subIndex]) {
            results[subIndex] = results[subIndex] + subItem
          } else {
            results[subIndex] = subItem
          }
        })
      })
      
      console.log(results) // { 0: 6, 1: 12 }
      
      // *********EXPLANATION BELOW ************

      const items = [[1, 0],[3, 3],[2, 1],[0, 8]]
      
      // store results in its own key:value pair
      const results = {}
      
      // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
      // forEach is a more readable way to loop through an array
      items.forEach((item, index) => {
        // use console.log(item, index) to see the values in each loop e.g first loop contains `item = [1,0]`
        // you can also use a debugger here which would be the easiest way to understand the iteration
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger
        // debugger;
      
        // loop over item (e.g [1,0]) to get subItems and their index
        item.forEach((subItem, subIndex) => {
      
          // get the result from previous sums from `result` 
          // and add them to the current subItem values
          // if there was no previous sum(i.e for first entry) 
          // use subItem as the first value.
          if (results[subIndex]) {
            results[subIndex] = results[subIndex] + subItem
          } else {
            results[subIndex] = subItem
          }
      
          // Below is a oneliner way to do line 16 to 20 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
          // results[subIndex] = results[subIndex] ? results[subIndex] + subItem : subItem
        })
      })
      
      console.log(results) // { 0: 6, 1: 12 } the results of `array[0][0],array[1][0]...` are in 0 and the result of `array[0][1], array[1][1]...` are in 1 and so on.

      【讨论】:

      • 感谢所有有用且解释清楚的 cmets。还有关于使用调试器的全局要点-我会尝试养成这种习惯。我还将阅读更多关于forEach 方法的信息,现在我可以了解它的使用方式。再次感谢!
      【解决方案8】:

      强制性的单线烤面条。

      console.log([[1, 0], [3, 3], [2, 1], [0, 8]].reduce((p, c) =&gt; [p[0] += c[0], p[1] += c[1]]));

      【讨论】:

      • 与其烤面条不如解释一下代码为 JS 初学者做了什么?
      • 对于初学者,当我提交我的示例时,答案不少于 4 个。我只是表明它可以以不同的方式完成。 @CertainPerformance 已经在他的回答中解释了 reduce 方法。
      猜你喜欢
      • 2021-08-18
      • 2010-12-06
      • 1970-01-01
      • 2021-06-16
      • 2017-05-13
      • 2017-09-08
      • 1970-01-01
      • 1970-01-01
      • 2018-07-12
      相关资源
      最近更新 更多