编辑:由于任何递归解决方案都会限制您可以创建的数组的大小......我在
PJs @ GitHub 库中制作了另一个解决方案。这个以伪即时速度运行,可以创建和管理任何大小、任何结构、在任何分支上具有任何维度的多维数组。它还可以模拟预填充和/或使用定制设计的节点对象。在这里查看:https://github.com/PimpTrizkit/PJs/wiki/14.-Complex-Multidimensional-Object--(pCMO.js)
使用jfabrizio的修改版解决方案:
function createNDimArray(dimensions) {
var t, i = 0, s = dimensions[0], arr = new Array(s);
if ( dimensions.length < 3 ) for ( t = dimensions[1] ; i < s ; ) arr[i++] = new Array(t);
else for ( t = dimensions.slice(1) ; i < s ; ) arr[i++] = createNDimArray(t);
return arr;
}
用法:
var arr = createNDimArray([3, 2, 3]);
// arr = [[[,,],[,,]],[[,,],[,,]],[[,,],[,,]]]
console.log(arr[2][1]); // in FF: Array [ <3 empty slots> ]
console.log("Falsy = " + (arr[2][1][0]?true:false) ); // Falsy = false
我发现这要快得多。我可能会说,这可能是在 Javascript 中生成 N 维数组的最快方法。上面的这种重构有一些很好的速度提升。但是,最好的速度提升当然来自不预填充。此版本不预填充数组。它只返回一个完全创建的 Ns 长度的 N 维数组,其中最后一级只是一个空数组。如果您真的需要 null 值,我希望 arr[x][y][z]?arr[x][y][z]:null 就足够了。它是供我使用的。 :)
如果您需要预填充,请使用他的原始版本。
而且,如果你真的不在乎我做了什么;然后停止阅读。
想要更多极客谈话吗?对于那些在那里学习的人来说,关于递归的一些事情。好了,攻略就到这里。在进行深度递归时,请记住最终级别。它是完成大部分工作的地方。在这种情况下,从字面上看,它是第 N 维。这是你的“有效载荷”,剩下的就是物流。在 jfab 的函数中,当dimensions.length 到达1 时,它的最后一维,它在第 N 维并执行有效载荷。这是创建空数组,或者在我的情况下,创建一个空数组。由于递归变得如此之深,每个维度都是最后一个维度的一个因素。当你到达第 N 维时,你将有很多函数调用,并且后勤对计算机来说变得很麻烦。在第 N 维,您将调用基本递归函数(在我们的例子中为createNDimArray)的有效负载次数比调用物流的次数要多。现在,就像在 jfab 的原始解决方案中一样,将有效负载的执行作为您在递归中做的第一件事(如果可能的话)通常是一件好事,特别是如果它很简单。在这里,通过将有效负载构建为最终的二维数组(而不仅仅是一个一维数组,只需返回一个new Array())。那么现在不必在这个级别上发生过多的函数调用。现在,当然,如果你想预填充数组,那么这个快捷方式并不总是有帮助。但更重要的是,预填充数组将是适当的有效负载。通过不访问第 N 维上的每个项目,我们有效地删除了它。这样就少了一层函数调用,基本上第 N 维的有效负载实际上是在第 N-1 维上完成的。而且我们再也不会为了传递new Array() 而再次调用递归函数。不幸的是,对new Array(x)(通常)的调用并没有这样看。它的执行时间确实会随着x 的增大而增加。这实际上仍在访问第 N 维中的每个项目,但现在我们只使用本机代码执行一次,并包裹在一个紧凑而轻巧的循环中。现在我们要求createNDimArray 只能在N > 1 时调用,即从不用于创建一维数组。从理论上讲,您可能需要更大的 N,并在最后展开更多维度。基本上,带有if ( dimensions.length < 3 ) 的行将读取类似< 4 或< 5 的内容,并且您必须将更多的for 循环环绕在那里,并且它们都需要自己的一组@987654340 @s ---所以我不确定这一切的效率有多高,因为您正在用类似的想法交易过多的函数调用和堆栈空间/操作,但在嵌入式 for 循环中 --- 但我想它可以加速如果您知道 N 始终高于某个水平,或者它仅适用于最终尺寸,则可以提升一些环境。就像这里一样,我在最后两个维度上做了。但是如果你展开太多,那么你的有效载荷本身就是一只熊。只有测试才能证明这是否值得。似乎堆栈空间是有限的,我想我记得我能够通过更多的展开来制作更大的数组。你可以制作一个数组的大小是有限制的。如果我这样做的话,在第 N 级为每个项目调用自己的递归解决方案具有最低限制.. 记得.. 正确.. 低得多。
修改他的解决方案的下一部分只是物流,它只是一个简单的重构,以摆脱过多的块和代码。加入所有var 一起工作,就是这样。由于您需要一个arr 来返回,一旦循环结束,不妨先在一行上完成所有var 工作,幸运的是,四个vars 中的三个具有相同的初始化。请记住,如果可能,Javascript 可以在加入 , 时优化代码。这也使得代码更小。
PT