为什么这不适用于数组编号?

时间:2017-09-20 13:25:46

标签: javascript arrays loops multidimensional-array

我正在玩数组只是学习javascript基础知识,每当我将传递参数更改为console.log(arr[i][j][k])给我未定义的数字时,我在这里得到了一个基本函数,但是如果它是一个字符串则记录数字。< / p>

function array(arr) {
    for(var i=0;i < arr.length;i++){
      for(var j=0; j < arr[i].length; j++){
            for(var k=0; k < arr[i][j].length; k++){
              console.log(arr[i][j][k])
            }
      }
    }
}

array(['1','2',['3','4'],['5','6','7']]); // change to a number and will give undefined.

3 个答案:

答案 0 :(得分:4)

问题是因为你在循环中调用.length。数字不具有.length方法,因此返回undefined。但是,字符串确实有这种方法。

作为可行的示例,您可以检查数组中的索引是否为数字,然后console.logcontinue(数组中的下一个索引)。

&#13;
&#13;
function array(arr) {
  for(var i=0;i < arr.length;i++){
    for(var j=0; j < arr[i].length; j++){    
      if (typeof arr[i][j] === 'number') {
        console.log(arr[i][j]);
        continue;
      }
      
      for(var k=0; k < arr[i][j].length; k++){
        console.log(arr[i][j][k])
      }
    }
  }
}

array(['1','2',['3','4'],['5','6', 7]]);
&#13;
&#13;
&#13;

您需要在每个循环中执行此检查,以便考虑数组中任何位置的数字。

建立@chazsolo的答案,这里是非ES6做同样事情的方式,以防万一将混乱的ES6语法投入混乱

&#13;
&#13;
var allItems = function (array) {
  var i = 0;
  // Loop through all items
  for (i; i < array.length; ++i) {
    // If this item is an array
    // You could also use typeof or Array.isArray as below
    if (toString.call(array[i]) === '[object Array]') {
      allItems(array[i]); // run this function again with this array
      continue; // move to next item
    }
    
    console.log(array[i]);
  }
}

allItems([1, 2, [3, 4], [5, 6, 7]]);

allItems(['1', '2', ['3', '4'], ['5', '6', '7']]);

allItems(['a', ['b', ['c', ['d', ['e', ['f', ['g']]]]]]]);
&#13;
&#13;
&#13;

首先,我们遍历数组中的所有项目。我们检查项目本身是否是一个数组(我在这里调用toString,如果它是一个数组则返回[object Array]。如果它是一个数组,那么我们为这个数组运行相同的函数(递归),然后跳到下一个项目,因为我们不需要对此进行任何其他操作。

如果它不是一个数组,那么我们就可以控制它的记录(这里我们假设它是一个数字或字符串,注意投入到混合中的对象)。

答案 1 :(得分:3)

建立@ CarlMarkham的答案,这解释了为什么你不应该在数组的每个项目上调用.length(你没有进行类型检查,所以.length未定义数字)。

您不满意自己将自己限制在3级嵌套数组中。这是递归有助于使这更加灵活的一个很好的例子。请考虑以下使用ES6:

const allItems = (array) => {
  for (let i of array) {
    Array.isArray(i) ? allItems(i) : console.log(i);
  }
}

allItems([1, 2, [3, 4], [5, 6, 7]]);

allItems(['1', '2', ['3', '4'], ['5', '6', '7']]);

allItems(['a', ['b', ['c', ['d', ['e', ['f', ['g']]]]]]]);

答案 2 :(得分:0)

请注意,上述两种解决方案都使用递归函数,这意味着函数会一遍又一遍地调用自身,直到满足“基本情况”为止。在这些情况下,它们会调用函数allItems()。

这指出了为复杂数据结构使用递归函数的优点。也就是说,递归函数可以根据需要多次执行函数或操作,无论数据结构有多复杂,无论嵌套的方式如何,是否知道有多少维度。

因此,如果您知道您的数据结构是双嵌套的,那么循环是一个很好的解决方案,因为您知道访问这些维度中的所有元素需要多少循环。

但是,如果你有一个非常多维的数据结构,它有许多你可能不知道的嵌套结构和元素,你将不知道要使用多少个循环,并且递归函数会照顾基于条件“基本案例”的复杂性。正如之前所说的那样,递归将在执行每个循环之前检查一个条件,这与标准循环不同。

希望在将来处理复杂的数据结构时能帮助您。