我正在以纯粹的功能方式实现javascript光线投射点多边形算法(背后没有特别的原因)。
我卡住了,因为我需要从一个二维数组中获取两个数组(复制一个元组列表);类似于Haskell的unzip
。
是否有可能,从[[a,b],[c,d],[e,f]]
之类的东西开始获取[[a,c,e],[b,d,f]]
而不使用过程式迭代器?
(我知道这是一个微不足道的问题,我可以在程序上实现该功能,然后忘记它,但我很想知道是否有解决方案)
编辑:为了澄清,我知道如何实施zip
和unzip
:我想知道在没有for
循环和变量重新分配的情况下实现它们是否可行。
答案 0 :(得分:6)
你的解压缩只是一个zip,但有多个参数。大多数人不仅使用相同函数的唯一原因是大多数时候zip
接收可变参数列表而不是数组,因此您需要在解压缩函数中使用apply
解包事物
在Dojo,我正在使用的库中,它们实现了zip并解压缩为
unzip: function(/*Array*/ a){
// summary: similar to dojox.lang.functional.zip(), but takes
// a single array of arrays as the input.
// description: This function is similar to dojox.lang.functional.zip()
// and can be used to unzip objects packed by
// dojox.lang.functional.zip(). It is here mostly to provide
// a short-cut for the different method signature.
return df.zip.apply(null, a);
}
zip: function(){
// summary: returns an array of arrays, where the i-th array
// contains the i-th element from each of the argument arrays.
// description: This is the venerable zip combiner (for example,
// see Python documentation for general details). The returned
// array is truncated to match the length of the shortest input
// array.
var n = arguments[0].length,
m = arguments.length,
i = 1,
t = new Array(n),
j,
p;
for(; i < m; n = Math.min(n, arguments[i++].length));
for(i = 0; i < n; ++i){
p = new Array(m);
for(j = 0; j < m; p[j] = arguments[j][i], ++j);
t[i] = p;
}
return t;
},
请注意,zip接收多个参数,因此它更像是Python zip,而不像Haskell那样。
在没有变量赋值的情况下,将此代码转换为“纯函数”样式应该不难。您现有的代码应该已经处理了我发布的示例中前两个fors的工作(以最小长度截断zip并迭代其中一个列表的索引)。剩下的就是为第三个做类似的事情 - 从列表列表中收集第i个值而不是从两个列表中收集两个值。