I'm implementing a javascript ray-casting point-in-polygon algorithm in a purely functional fashion (no particular reason behind it).
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
.
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?
(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.
Your unzip is just a zip but with multiple arguments. 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.
In Dojo, the library I am using, they implement zip and unzip as
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.
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). 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With