是否有可能以纯粹的功能方式实现js版本的Haskell解压缩?

时间:2011-12-15 11:39:51

标签: javascript haskell functional-programming

我正在以纯粹的功能方式实现javascript光线投射点多边形算法(背后没有特别的原因)。

我卡住了,因为我需要从一个二维数组中获取两个数组(复制一个元组列表);类似于Haskell的unzip

是否有可能,从[[a,b],[c,d],[e,f]]之类的东西开始获取[[a,c,e],[b,d,f]]而不使用过程式迭代器?

(我知道这是一个微不足道的问题,我可以在程序上实现该功能,然后忘记它,但我很想知道是否有解决方案)


编辑:为了澄清,我知道如何实施zipunzip:我想知道在没有for循环和变量重新分配的情况下实现它们是否可行。

1 个答案:

答案 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个值而不是从两个列表中收集两个值。