Skip to content

Instantly share code, notes, and snippets.

@vorg
Last active August 29, 2015 14:06
Show Gist options
  • Save vorg/d251e0ddf0d404b1d34c to your computer and use it in GitHub Desktop.
Save vorg/d251e0ddf0d404b1d34c to your computer and use it in GitHub Desktop.
Split array into pairs of values
How would you partition array into pairs in Ramda? [0, 1, 2, 3, 4, 5] -> [[0,1], [2, 3], [4, 5]]
//@vorg - my solution
var hasEvenIndex = function(n, i) { return i % 2 == 0; };
var hasOddIndex = function(n, i) { return i % 2 == 1; };
function pairs(list) {
var evens = R.filter.idx(hasEvenIndex)(list);
var odds = R.filter.idx(hasOddIndex)(list);
return R.zip(evens, odds);
}
//https://twitter.com/buzzdecafe/status/512242625416409088
var ps = partition(pipe(head, not(modulo(2))), toPairs(arr));
var pairs = zip(pluck(1, head(ps)), pluck(1, last(ps)));
//https://twitter.com/scott_sauyet/status/512245774458290176
mkPairs = pipe(toPairs,partition(pipe(head,not(modulo(2)))),converge(zip,pipe(head,pluck(1)),pipe(last,pluck(1))));
@CrossEye
Copy link

My initial solution, which I didn't tweet in full, but alluded to in the same thread was just this:

var evens = R.filter.idx(function(a, b) {return !(b % 2);};
var odds = R.filter.idx(function(a, b) {return !!(b % 2);};
var makePairs = R.converge(R.zip, evens, odds);

This is much the same as yours, except that it is a little shorter.

The one-liners like the above are mostly just for fun. 😄

@buzzdecafe
Copy link

@vorg, your solution may be the most readable one of the lot

@CrossEye no need for two predicates:

var evenIdx = function(a, b) {return !(b % 2);}
var makePairs = R.converge(R.zip, R.filter.idx(evenIdx), R.filter.idx(not(evenIdx)));

you should've seen some of the nasty foldl-based versions I was playing with.....

@CrossEye
Copy link

One variant of the nasty foldl-based versions is this:

var inGroupsOf = R.curry(function(n, list) {
    return R.foldl.idx(function(a, e, idx) {
        if (idx % n == 0) {
            a.push([e]);
        } else {
            R.last(a).push(e);
        } 
        return a;
    }, [], list);
});

Then

var arr = [2, 3, 5, 7, 11, 13];
inGroupsOf(2, arr); //=> [[2, 3], [5, 7], [11, 13]]
inGroupsOf(3, arr) //=> [[2, 3, 5], [7, 11, 13]]
inGroupsOf(4, arr) //=> [[2, 3, 5, 7], [11, 13]]

If you didn't want that behavior and wanted to cut the last group down to size, you could replace the penultimate line with

   }, [], list.slice(0, list.length - (list.length % n)));

and then

inGroupsOf(4, arr) //=> [[2, 3, 5, 7]]
inGroupsOf(4, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]); //=> [[2, 3, 5, 7], [11, 13, 17, 19]]

And of course you can just write

var makePairs = inGroupsOf(2);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment