简体   繁体   English

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

[英]Is it possible to implement a js version of Haskell's unzip in a purely functional fashion?

I'm implementing a javascript ray-casting point-in-polygon algorithm in a purely functional fashion (no particular reason behind it). 我正在以纯粹的功能方式实现javascript光线投射点多边形算法(背后没有特别的原因)。

I got stuck as i needed to get two arrays from a 2-dimentional array (replicating a list of tuples); 我被卡住了,因为我需要从一个二维数组中获取两个数组(复制一个元组列表); something akin to Haskell's unzip . 类似于Haskell unzip东西。

Is it possible, starting from something like [[a,b],[c,d],[e,f]] to obtain [[a,c,e],[b,d,f]] without using procedural-style iterators? 是否有可能从[[a,b],[c,d],[e,f]]这样的事情开始,以获得[[a,c,e],[b,d,f]]而不使用程序 -风格迭代器?

(I know it's a trivial question, and I could just implement the function procedurally and then forget about it, but I was curious to know if there was a solution) (我知道这是一个微不足道的问题,我可以在程序上实现这个功能,然后忘记它,但我很想知道是否有解决方案)


EDIT: To clarify, I know how to implement zip and unzip : I was wondering wether it might be possible to implement them without for loops and variable reassignments. 编辑:为了澄清,我知道如何实现zip unzip :我想知道是否有可能在没有for循环和可变重新分配的情况下实现它们。

Your unzip is just a zip but with multiple arguments. 你的解压缩只是一个zip,但有多个参数。 The only reason most people don't just use the same function is that most of the time zip receives a variadic list of arguments instead of a array so you need to unpack things with apply in the unzip function. 大多数人不只是使用相同功能的唯一原因是,大多数时候zip接收一个可变参数列表而不是数组,所以你需要使用unzip函数中的apply来解包。

In Dojo, the library I am using, they implement zip and unzip as 在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;
},

Note that zip receives multiple arguments so it is more like the Python zip and less like the Haskell one. 请注意,zip接收多个参数,因此它更像是Python zip,而不像Haskell。


It should not be hard to conver this code to a "purely functional" style without variable assignments. 在没有变量赋值的情况下,将此代码转换为“纯函数”样式应该不难。 Your existing code should already be handling the job of the first two fors in the example I posted (truncating the zip at the minimum length and iterating through the indices of one of the lists). 您现有的代码应该已经处理了我发布的示例中前两个fors的工作(以最小长度截断zip并迭代其中一个列表的索引)。 All that is left is doing a similar thing for the third for - collecting the i-th value from a list of lists instead of collecting two values from two lists. 剩下的就是为第三个做类似的事情 - 从列表列表中收集第i个值而不是从两个列表中收集两个值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM