多维javascript数组中的for循环
Posted
技术标签:
【中文标题】多维javascript数组中的for循环【英文标题】:For loop in multidimensional javascript array 【发布时间】:2012-04-18 19:03:48 【问题描述】:从现在开始,我使用这个循环来迭代数组的元素,即使我在其中放入具有各种属性的对象,它也能正常工作。
var cubes[];
for (i in cubes)
cubes[i].dimension
cubes[i].position_x
ecc..
现在,假设 cubes[] 是这样声明的
var cubes[][];
我可以在 javascript 中做到这一点吗?然后我怎样才能自动迭代
cubes[0][0]
cubes[0][1]
cubes[0][2]
cubes[1][0]
cubes[1][1]
cubes[1][2]
cubes[2][0]
ecc...
作为一种解决方法,我可以声明:
var cubes[];
var cubes1[];
并分别使用这两个数组。这是更好的解决方案吗?
【问题讨论】:
【参考方案1】:你可以这样做:
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]);
工作 jsFiddle:
http://jsfiddle.net/TRR4n/上面的输出:
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
【讨论】:
您的解决方案仅适用于 2D 数组,但我找到了一种循环遍历任意维数数组的方法:***.com/a/15854485/975097 @AndersonGreen OP 专门寻找二维数组,因此得到了上述答案。不过感谢您提供的链接 - 希望它对将来寻找类似解决方案的人有所帮助! @Bharadwaj 这是一个全新的问题 - 看看这个:***.com/questions/4331092/… 谢谢@icyrock.com。它帮助了我。【参考方案2】: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]);
【讨论】:
然后他问“我可以用 javascript 做这个吗?” 您在我发表评论后编辑了您的答案。您的原始帖子与迭代无关。【参考方案3】:有点晚了,但是这个解决方案很好很简洁
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
或者在你的情况下:
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
注意: for ... of
循环在 ES6 中是标准化的,所以只有在你有 ES5 Javascript 编译器(例如 Babel)时才使用它
另一个注意事项:有替代品,但它们有一些细微的区别和行为,例如forEach()
、for...in
、for...of
和传统的for()
。这取决于您的情况来决定使用哪一个。 (ES6还有.map()
、.filter()
、.find()
、.reduce()
)
【讨论】:
【参考方案4】:循环遍历数组的一种有效方法是built-in array method .map()
对于一维数组,它看起来像这样:
function HandleOneElement( Cuby )
Cuby.dimension
Cuby.position_x
...
cubes.map(HandleOneElement) ; // the map function will pass each element
对于二维数组:
cubes.map( function( cubeRow ) cubeRow.map( HandleOneElement ) )
对于任意形式的 n 维数组:
Function.prototype.ArrayFunction = function(param)
if (param instanceof Array)
return param.map( Function.prototype.ArrayFunction, this ) ;
else return (this)(param) ;
HandleOneElement.ArrayFunction(cubes) ;
【讨论】:
【参考方案5】:试试这个:
var i, j;
for (i = 0; i < cubes.length; i++)
for (j = 0; j < cubes[i].length; j++)
do whatever with cubes[i][j];
【讨论】:
这将创建全局变量。 添加了 var i, j;公平地说,他没有说“不要创建全局变量”。 ;-) 为什么要在新行上声明 i 和 j 而你可以在循环中这样做?for(var i = 0; ...)
【参考方案6】:
或者您也可以使用“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);
);
如果您需要数组的索引,请尝试以下代码:
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++;
);
结果将如下所示:
[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
【讨论】:
【参考方案7】:如果您使用的是 ES2015,并且想要定义自己的对象,该对象像二维数组一样进行迭代,您可以通过以下方式实现 iterator protocol:
-
定义一个名为
Symbol.iterator
的@@iterator 函数,它返回...
...带有next()
函数的对象返回...
...一个具有一个或两个属性的对象:一个可选的value
具有下一个值(如果有的话)和一个布尔值done
,如果我们完成了迭代,则为真。
一维数组迭代器函数如下所示:
// 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
;
;
现在,我们可以将 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);
要创建我们自己的 2-D 可迭代对象,我们可以返回另一个可迭代对象,而不是在 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
;
;
现在,我们可以使用嵌套迭代:
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);
请注意,我们的自定义迭代不会在所有情况下都表现得像二维数组;例如,我们还没有实现map()
函数。 This answer 展示了如何实现生成器映射函数(see here 用于迭代器和生成器之间的区别;此外,生成器是 ES2016 功能,而不是 ES2015,因此如果您正在编译,则需要 change your babel presets通天塔)。
【讨论】:
【参考方案8】:JavaScript 没有这样的声明。应该是:
var cubes = ...
不管
但你可以这样做:
for(var i = 0; i < cubes.length; i++)
for(var j = 0; j < cubes[i].length; j++)
请注意,JavaScript 允许使用锯齿状数组,例如:
[
[1, 2, 3],
[1, 2, 3, 4]
]
因为数组可以包含任何类型的对象,包括任意长度的数组。
正如MDC所指出的:
"for..in 不应该用于遍历索引顺序的数组 很重要”
如果您使用原始语法,则无法保证将按数字顺序访问元素。
【讨论】:
以上是关于多维javascript数组中的for循环的主要内容,如果未能解决你的问题,请参考以下文章