diff --git a/build.js b/build.js index 84900eb05..830e027c7 100755 --- a/build.js +++ b/build.js @@ -55,7 +55,8 @@ 'select': 'filter', 'tail': 'rest', 'take': 'first', - 'unique': 'uniq' + 'unique': 'uniq', + 'unzip': 'zip' }; /** Used to associate real names with their aliases */ @@ -74,6 +75,7 @@ 'rest': ['drop', 'tail'], 'some': ['any'], 'uniq': ['unique'], + 'zip': ['unzip'], 'zipObject': ['object'] }; @@ -179,13 +181,12 @@ 'union': ['basicFlatten', 'basicUniq'], 'uniq': ['basicUniq', 'overloadWrapper'], 'uniqueId': [], - 'unzip': ['max', 'pluck'], 'value': ['basicEach', 'forOwn', 'isArray', 'lodash', 'wrapperValueOf', 'lodashWrapper'], 'values': ['keys'], 'where': ['filter'], 'without': ['difference'], 'wrap': [], - 'zip': ['unzip'], + 'zip': ['max', 'pluck'], 'zipObject': [], // private functions @@ -282,7 +283,6 @@ 'sortedIndex', 'union', 'uniq', - 'unzip', 'without', 'zip', 'zipObject' diff --git a/lodash.js b/lodash.js index bed63ef72..e12454bc2 100644 --- a/lodash.js +++ b/lodash.js @@ -4468,32 +4468,6 @@ */ var uniq = overloadWrapper(basicUniq); - /** - * The inverse of `_.zip`, this method splits groups of elements into arrays - * composed of elements from each group at their corresponding indexes. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @returns {Array} Returns a new array of the composed arrays. - * @example - * - * _.unzip([['moe', 30, true], ['larry', 40, false]]); - * // => [['moe', 'larry'], [30, 40], [true, false]]; - */ - function unzip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = array ? max(pluck(array, 'length')) : 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = pluck(array, index); - } - return result; - } - /** * Creates an array with all occurrences of the passed values removed using * strict equality for comparisons, i.e. `===`. @@ -4514,13 +4488,13 @@ } /** - * Groups the elements of each array at their corresponding indexes. Useful for - * separate data sources that are coordinated through matching array indexes. - * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix - * in a similar fashion. + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. * * @static * @memberOf _ + * @alias unzip * @category Arrays * @param {Array} [array1, array2, ...] Arrays to process. * @returns {Array} Returns a new array of grouped elements. @@ -4529,8 +4503,16 @@ * _.zip(['moe', 'larry'], [30, 40], [true, false]); * // => [['moe', 30, true], ['larry', 40, false]] */ - function zip(array) { - return array ? unzip(arguments) : []; + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; } /** @@ -5746,7 +5728,6 @@ lodash.transform = transform; lodash.union = union; lodash.uniq = uniq; - lodash.unzip = unzip; lodash.values = values; lodash.where = where; lodash.without = without; @@ -5764,6 +5745,7 @@ lodash.select = filter; lodash.tail = rest; lodash.unique = uniq; + lodash.unzip = zip; // add functions to `lodash.prototype` mixin(lodash); diff --git a/test/test-build.js b/test/test-build.js index 8ef24e579..f517dbb1e 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -67,7 +67,8 @@ 'select': 'filter', 'tail': 'rest', 'take': 'first', - 'unique': 'uniq' + 'unique': 'uniq', + 'unzip': 'zip' }; /** Used to associate real names with their aliases */ @@ -86,6 +87,7 @@ 'rest': ['drop', 'tail'], 'some': ['any'], 'uniq': ['unique'], + 'zip': ['unzip'], 'zipObject': ['object'] }; @@ -107,7 +109,6 @@ 'sortedIndex', 'union', 'uniq', - 'unzip', 'without', 'zip', 'zipObject' @@ -284,8 +285,7 @@ 'parseInt', 'partialRight', 'runInContext', - 'transform', - 'unzip' + 'transform' ]; /** List of all functions */ @@ -999,9 +999,6 @@ function Foo() {} Foo.prototype = { 'a': 1 }; - actual = lodash.defaults({ 'a': null }, { 'a': 1 }); - strictEqual(actual.a, 1, '_.defaults should overwrite `null` values: ' + basename); - deepEqual(lodash.defaults({}, new Foo), Foo.prototype, '_.defaults should assign inherited `source` properties: ' + basename); deepEqual(lodash.extend({}, new Foo), Foo.prototype, '_.extend should assign inherited `source` properties: ' + basename); @@ -1065,7 +1062,6 @@ actual = lodash.pick(object, function(value) { return value != 3; }); deepEqual(_.keys(actual), [], '_.pick should not accept a `callback`: ' + basename); - strictEqual(lodash.result(), null, '_.result should return `null` for falsey `object` arguments: ' + basename); strictEqual(lodash.some([false, true, false]), true, '_.some: ' + basename); deepEqual(lodash.times(null, function() {}), [null], '_.times should not coerce `n` to a number: ' + basename); equal(lodash.template('${a}', object), '${a}', '_.template should ignore ES6 delimiters: ' + basename); @@ -1581,8 +1577,7 @@ 'uniq', 'uniqueId', 'value', - 'where', - 'zip' + 'where' ]; function strip(value) { @@ -1599,9 +1594,6 @@ if (funcName == 'createCallback') { command += ',where'; } - if (funcName == 'zip') { - command += ',unzip'; - } if (funcName != 'chain' && _.contains(categoryMap.Chaining.concat('mixin'), funcName)) { command += ',chain'; } diff --git a/test/test.js b/test/test.js index e7bf44c13..e6ffabc48 100644 --- a/test/test.js +++ b/test/test.js @@ -3368,58 +3368,6 @@ /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.unzip'); - - (function() { - var object = { - 'an empty array': [ - [], - [] - ], - '0-tuples': [ - [[], []], - [] - ], - '1-tuples': [ - [['moe'], ['larry']], - [['moe', 'larry']] - ], - '2-tuples': [ - [['moe', 30], ['larry', 40]], - [['moe', 'larry'], [30, 40]] - ], - '3-tuples': [ - [['moe', 30, true], ['larry', 40, false]], - [['moe', 'larry'], [30, 40], [true, false]] - ] - }; - - _.forOwn(object, function(pair, key) { - test('should work with ' + key, function() { - var actual = _.unzip(pair[0]); - deepEqual(actual, pair[1]); - deepEqual(_.zip.apply(_, actual), pair[1].length ? pair[0] : pair[1]); - }); - }); - - test('should work with tuples of different lengths', function() { - var pair = [ - [['moe', 30], ['larry', 40, false]], - [['moe', 'larry'], [30, 40], [undefined, false]] - ]; - - var actual = _.unzip(pair[0]); - ok(1 in actual); - deepEqual(actual, pair[1]); - - actual = _.zip.apply(_, actual); - ok(2 in actual[0]); - deepEqual(actual, [['moe', 30, undefined], ['larry', 40, false]]); - }); - }()); - - /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.where'); (function() { @@ -3486,6 +3434,59 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.zip'); + + (function() { + var object = { + 'an empty array': [ + [], + [] + ], + '0-tuples': [ + [[], []], + [] + ], + '2-tuples': [ + [['moe', 'larry'], [30, 40]], + [['moe', 30], ['larry', 40]] + ], + '3-tuples': [ + [['moe', 'larry'], [30, 40], [true, false]], + [['moe', 30, true], ['larry', 40, false]] + ] + }; + + _.forOwn(object, function(pair, key) { + test('should work with ' + key, function() { + var actual = _.zip.apply(_, pair[0]); + deepEqual(actual, pair[1]); + deepEqual(_.zip.apply(_, actual), actual.length ? pair[0] : []); + }); + }); + + test('should work with tuples of different lengths', function() { + var pair = [ + [['moe', 30], ['larry', 40, false]], + [['moe', 'larry'], [30, 40], [undefined, false]] + ]; + + var actual = _.zip(pair[0]); + ok(0 in actual[2]); + deepEqual(actual, pair[1]); + + actual = _.zip.apply(_, actual); + ok(2 in actual[0]); + deepEqual(actual, [['moe', 30, undefined], ['larry', 40, false]]); + }); + + test('should be able to consume the output of `_.unzip`', function() { + var expected = [['moe', 'larry'], [30, 40]]; + deepEqual(_.unzip(_.zip(_.unzip(_.zip(expected)))), expected); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash(...).shift'); (function() {