A zip function in javascript using .reduce
.
See Tom MacWright's post making juice with reduce
/ foldl
.
See also _.zip
and d3.zip
for alternative implementations and sample usage.
'use strict'; | |
var assert = require('assert'); | |
// zip | |
// | |
function zip(arrays) { | |
return arrays.reduce(function (acc, arr, i) { | |
while (acc.length < arr.length) { | |
acc.push([]); | |
} | |
for (var j = 0; j < arr.length; ++j) { | |
acc[j][i] = arr[j]; | |
} | |
return acc; | |
}, []); | |
} | |
var result = zip([ ['foo', 'bar'], ['apples', 'grapes'] ]); | |
var expected = [ ['foo', 'apples'], ['bar', 'grapes'] ]; | |
assert.deepEqual(result, expected); | |
var result = zip([ ['foo', 'bar'], ['apples', 'grapes'], ['a', 'b', 'c'] ]); | |
var expected = [ | |
['foo', 'apples', 'a'], | |
['bar', 'grapes', 'b'], | |
[] // [ , , 'c'] | |
]; | |
expected[2][2] = 'c'; | |
assert.deepEqual(result, expected); | |
// following D3's implementation | |
// https://github.com/mbostock/d3/blob/master/src/arrays/zip.js | |
// | |
var zip = function (arrays) { | |
var n = arrays.length; | |
if (!n) { return []; } | |
var max = maxArray(arrays); | |
for (var i = -1, zips = new Array(max); ++i < max;) { | |
for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n;) { | |
zip[j] = arrays[j][i]; | |
} | |
} | |
return zips; | |
}; | |
function maxArray(arrays) { | |
return arrays.reduce(function (max, arr) { | |
var len = arr.length; | |
return len > max ? len : max; | |
}, 0); | |
} | |
var result = zip([ ['foo', 'bar'], ['apples', 'grapes'] ]); | |
var expected = [ ['foo', 'apples'], ['bar', 'grapes'] ]; | |
assert.deepEqual(result, expected); | |
var result = zip([ ['foo', 'bar'], ['apples', 'grapes'], ['a', 'b', 'c'] ]); | |
var expect = [ | |
['foo', 'apples', 'a'], | |
['bar', 'grapes', 'b'], | |
[undefined, undefined, 'c'] | |
]; | |
assert.deepEqual(result, expect); |