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
For loop in multidimensional javascript 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 ... of
loop 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...of
and traditional for()
. It depends on your case to decide which one to use. (ES6 also has .map()
, .filter()
, .find()
, .reduce()
)
另注:还有其他选择,但他们有一些细微的差别和行为,如forEach()
,for...in
,for...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 并且你想定义你自己的像二维数组一样迭代的对象,你可以通过以下方式实现迭代器协议:
- Defining an @@iteratorfunction called
Symbol.iterator
which returns... - ...an object with a
next()
function that returns... - ...an object with one or two properties: an optional
value
with the next value (if there is one) and a booleandone
which is true if we're done iterating.
- 定义一个@@iterator函数调用
Symbol.iterator
它返回... - ...一个带有
next()
返回函数的对象... - ...一个具有一两个属性的对象:一个
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 Cubes
object 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.
如果您使用原始语法,则不能保证元素会按数字顺序访问。