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); |