Javascript 多维javascript数组中的for循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10021847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:31:37  来源:igfitidea点击:

For loop in multidimensional javascript array

javascriptloopsmultidimensional-array

提问by Saturnix

Since now, I'm using this loop to iterate over the elements of an array, which works fine even if I put objects with various properties inside of it.

从现在开始,我使用这个循环来迭代数组的元素,即使我将具有各种属性的对象放入其中也能正常工作。

var cubes[];

for (i in cubes){
     cubes[i].dimension
     cubes[i].position_x
     ecc..
}

Now, let's suppose cubes[] is declared this way

现在,让我们假设 cubes[] 是这样声明的

var cubes[][];

Can I do this in Javascript? How can I then automatically iterate in

我可以在Javascript 中做到这一点吗?我怎样才能自动迭代

cubes[0][0]
cubes[0][1]
cubes[0][2]
cubes[1][0]
cubes[1][1]
cubes[1][2]
cubes[2][0]
ecc...

As a workaround, I can just declare:

作为一种解决方法,我可以声明:

var cubes[];
var cubes1[];

and work separately with the two arrays. Is this a better solution?

并分别处理两个阵列。这是更好的解决方案吗?

回答by icyrock.com

You can do something like this:

你可以这样做:

var cubes = [
 [1, 2, 3],
 [4, 5, 6],    
 [7, 8, 9],
];

for(var i = 0; i < cubes.length; i++) {
    var cube = cubes[i];
    for(var j = 0; j < cube.length; j++) {
        display("cube[" + i + "][" + j + "] = " + cube[j]);
    }
}

Working jsFiddle:

工作jsFiddle:

The output of the above:

上面的输出:

cube[0][0] = 1
cube[0][1] = 2
cube[0][2] = 3
cube[1][0] = 4
cube[1][1] = 5
cube[1][2] = 6
cube[2][0] = 7
cube[2][1] = 8
cube[2][2] = 9

回答by binarious

var cubes = [["string", "string"], ["string", "string"]];

for(var i = 0; i < cubes.length; i++) {
    for(var j = 0; j < cubes[i].length; j++) {
        console.log(cubes[i][j]);
    }
}

回答by user2197265

An efficient way to loop over an Array is the built-in array method .map()

循环数组的一种有效方法是内置数组方法 .map()

For a 1-dimensional array it would look like this:

对于一维数组,它看起来像这样:

function HandleOneElement( Cuby ) {
   Cuby.dimension
   Cuby.position_x
   ...
}
cubes.map(HandleOneElement) ; // the map function will pass each element

for 2-dimensional array:

对于二维数组:

cubes.map( function( cubeRow ) { cubeRow.map( HandleOneElement ) } )

for an n-dimensional array of any form:

对于任何形式的 n 维数组:

Function.prototype.ArrayFunction = function(param) {
  if (param instanceof Array) {
    return param.map( Function.prototype.ArrayFunction, this ) ;
  }
  else return (this)(param) ;
}
HandleOneElement.ArrayFunction(cubes) ;

回答by WebDeg Brian

A bit too late, but this solution is nice and neat

有点晚了,但是这个解决方案很好很整洁

const arr = [[1,2,3],[4,5,6],[7,8,9,10]]
for (let i of arr) {
  for (let j of i) {
    console.log(j) //Should log numbers from 1 to 10
  }
}

Or in your case:

或者在你的情况下:

const arr = [[1,2,3],[4,5,6],[7,8,9]]
for (let [d1, d2, d3] of arr) {
  console.log(`${d1}, ${d2}, ${d3}`) //Should return numbers from 1 to 9
}

Note:for ... ofloop is standardised in ES6, so only use this if you have an ES5 Javascript Complier (such as Babel)

注意:for ... of循环在 ES6 中是标准化的,所以只有在你有 ES5 Javascript 编译器(例如 Babel)时才使用它

Another note:There are alternatives, but they have some subtle differences and behaviours, such as forEach(), for...in, for...ofand traditional for(). It depends on your case to decide which one to use. (ES6 also has .map(), .filter(), .find(), .reduce())

另注:还有其他选择,但他们有一些细微的差别和行为,如forEach()for...infor...of和传统for()。决定使用哪一种取决于您的情况。(ES6 也有.map(), .filter(), .find(), .reduce()

回答by Michael Rice

Try this:

尝试这个:

var i, j;

for (i = 0; i < cubes.length; i++) {
    for (j = 0; j < cubes[i].length; j++) {
       do whatever with cubes[i][j];
    }
}

回答by Galen Long

If you're using ES2015 and you want to define your own object that iterates like a 2-D array, you can implement the iterator protocolby:

如果你使用 ES2015 并且你想定义你自己的像二维数组一样迭代的对象,你可以通过以下方式实现迭代器协议

  1. Defining an @@iteratorfunction called Symbol.iteratorwhich returns...
  2. ...an object with a next()function that returns...
  3. ...an object with one or two properties: an optional valuewith the next value (if there is one) and a boolean donewhich is true if we're done iterating.
  1. 定义一个@@iterator函数调用Symbol.iterator它返回...
  2. ...一个带有next()返回函数的对象...
  3. ...一个具有一两个属性的对象:一个value带有下一个值的可选值(如果有)和一个布尔值done,如果我们完成迭代,则为真。

A one-dimensionalarray iterator function would look like this:

一个一维数组迭代函数应该是这样的:

// our custom Cubes object which implements the iterable protocol
function Cubes() {
    this.cubes = [1, 2, 3, 4];
    this.numVals = this.cubes.length;

    // assign a function to the property Symbol.iterator
    // which is a special property that the spread operator
    // and for..of construct both search for
    this[Symbol.iterator] = function () { // can't take args

        var index = -1; // keep an internal count of our index
        var self = this; // access vars/methods in object scope

        // the @@iterator method must return an object
        // with a "next()" property, which will be called
        // implicitly to get the next value
        return {
            // next() must return an object with a "done" 
            // (and optionally also a "value") property
            next: function() {
                index++;
                // if there's still some values, return next one
                if (index < self.numVals) {
                    return {
                        value: self.cubes[index],
                        done: false
                    };
                }
                // else there's no more values left, so we're done
                // IF YOU FORGET THIS YOU WILL LOOP FOREVER!
                return {done: true}
            }
        };
    };
}

Now, we can treat our Cubesobject like an iterable:

现在,我们可以将我们的Cubes对象视为可迭代对象:

var cube = new Cubes(); // construct our cube object

// both call Symbol.iterator function implicitly:
console.log([...cube]); // spread operator
for (var value of cube) { // for..of construct
    console.log(value);
}

To create our own 2-Diterable, instead of returning a value in our next()function, we can return another iterable:

要创建我们自己的二维迭代next(),我们可以返回另一个迭代,而不是在我们的函数中返回一个值:

function Cubes() {
    this.cubes = [
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12],
    ];
    this.numRows = this.cubes.length;
    this.numCols = this.cubes[0].length; // assumes all rows have same length

    this[Symbol.iterator] = function () {
        var row = -1;
        var self = this;

        // create a closure that returns an iterator
        // on the captured row index
        function createColIterator(currentRow) {
            var col = -1;
            var colIterator = {}
            // column iterator implements iterable protocol
            colIterator[Symbol.iterator] = function() {
                return {next: function() {
                    col++;
                    if (col < self.numCols) {
                        // return raw value
                        return {
                            value: self.cubes[currentRow][col],
                            done: false
                        };
                    }
                    return {done: true};
                }};
            }
            return colIterator;
        }

        return {next: function() {
            row++;
            if (row < self.numRows) {
                // instead of a value, return another iterator
                return {
                    value: createColIterator(row),
                    done: false
                };
            }
            return {done: true}
        }};
    };
}

Now, we can use nested iteration:

现在,我们可以使用嵌套迭代:

var cube = new Cubes();

// spread operator returns list of iterators, 
// each of which can be spread to get values
var rows = [...cube];
console.log([...rows[0]]);
console.log([...rows[1]]);
console.log([...rows[2]]);

// use map to apply spread operator to each iterable
console.log([...cube].map(function(iterator) { 
    return [...iterator];
}));

for (var row of cube) {
    for (var value of row) {
        console.log(value);
    }
}

Note that our custom iterable won't behave like a 2-D array in all cases; for example, we haven't implemented a map()function. This answershows how you could implement a generator map function (see herefor the difference between iterators and generators; also, generators are an ES2016 feature, not ES2015, so you'll need to change your babel presetsif you're compiling with babel).

请注意,我们的自定义迭代不会在所有情况下都表现得像一个二维数组;例如,我们还没有实现一个map()功能。此答案显示了如何实现生成器映射函数(有关迭代器和生成器之间的区别,请参见此处;此外,生成器是 ES2016 功能,而不是 ES2015,因此如果您使用 babel 进行编译,则需要更改 babel 预设)。

回答by Masa S-AiYa

Or you can do this alternatively with "forEach()":

或者你也可以用“forEach()”来替代:

var cubes = [
 [1, 2, 3],
 [4, 5, 6],    
 [7, 8, 9],
];

cubes.forEach(function each(item) {
  if (Array.isArray(item)) {
    // If is array, continue repeat loop
    item.forEach(each);
  } else {
    console.log(item);
  }
});

If you need array's index, please try this code:

如果您需要数组的索引,请尝试以下代码:

var i = 0; j = 0;

cubes.forEach(function each(item) {
  if (Array.isArray(item)) {
    // If is array, continue repeat loop
    item.forEach(each);
    i++;
    j = 0;
  } else {
    console.log("[" + i + "][" + j + "] = " + item);
    j++;
  }
});

And the result will look like this:

结果将如下所示:

[0][0] = 1
[0][1] = 2
[0][2] = 3
[1][0] = 4
[1][1] = 5
[1][2] = 6
[2][0] = 7
[2][1] = 8
[2][2] = 9

回答by Matthew Flaschen

JavaScript does not have such declarations. It would be:

JavaScript 没有这样的声明。这将是:

var cubes = ...

regardless

不管

But you can do:

但你可以这样做:

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

  }
}

Note that JavaScript allows jagged arrays, like:

请注意,JavaScript 允许使用锯齿状数组,例如:

[
  [1, 2, 3],
  [1, 2, 3, 4]
]

since arrays can contain any type of object, including an array of arbitrary length.

因为数组可以包含任何类型的对象,包括任意长度的数组。

As noted by MDC:

正如MDC所指出的:

"for..in should not be used to iterate over an Array where index order is important"

“for..in 不应用于迭代索引顺序很重要的数组”

If you use your original syntax, there is no guarantee the elements will be visited in numeric order.

如果您使用原始语法,则不能保证元素会按数字顺序访问。