diff --git a/lodash.js b/lodash.js index a2743dafe..722606da2 100644 --- a/lodash.js +++ b/lodash.js @@ -4073,6 +4073,35 @@ return baseUniq(array, isSorted, iterator); } + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre `_.zip` + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + var index = -1, + length = isObject(length = max(array, 'length')) && length.length || 0, + result = Array(length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + /** * Creates an array excluding all provided values using strict equality for * comparisons, i.e. `===`. @@ -4128,33 +4157,20 @@ /** * 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. If a zipped value is provided its corresponding - * unzipped value is returned. + * of the given arrays, and so on. * * @static * @memberOf _ - * @alias unzip * @category Array * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the array of grouped elements. + * @returns {Array} Returns the new array of grouped elements. * @example * * _.zip(['fred', 'barney'], [30, 40], [true, false]); * // => [['fred', 30, true], ['barney', 40, false]] - * - * _.unzip([['fred', 30, true], ['barney', 40, false]]); - * // => [['fred', 'barney'], [30, 40], [true, false]] */ function zip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = isObject(length = max(array, 'length')) && length.length || 0, - result = Array(length); - - while (++index < length) { - result[index] = pluck(array, index); - } - return result; + return unzip(arguments); } /** @@ -8980,6 +8996,7 @@ lodash.transform = transform; lodash.union = union; lodash.uniq = uniq; + lodash.unzip = unzip; lodash.values = values; lodash.valuesIn = valuesIn; lodash.where = where; @@ -8999,7 +9016,6 @@ lodash.select = filter; lodash.tail = rest; lodash.unique = uniq; - lodash.unzip = zip; // add functions to `lodash.prototype` mixin(lodash, baseAssign({}, lodash)); diff --git a/test/test.js b/test/test.js index 260aedc34..39e7c3277 100644 --- a/test/test.js +++ b/test/test.js @@ -10807,9 +10807,12 @@ /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.zip'); + QUnit.module('lodash.unzip and lodash.zip'); + + _.each(['unzip', 'zip'], function(methodName) { + var func = _[methodName]; + func = _.bind(methodName == 'zip' ? func.apply : func.call, func, null); - (function() { var object = { 'an empty array': [ [], @@ -10830,52 +10833,43 @@ }; _.forOwn(object, function(pair, key) { - test('should work with ' + key, 2, function() { - var actual = _.zip.apply(_, pair[0]); + test('`_.' + methodName + '` should work with ' + key, 2, function() { + var actual = func(pair[0]); deepEqual(actual, pair[1]); - deepEqual(_.zip.apply(_, actual), actual.length ? pair[0] : []); + deepEqual(func(actual), actual.length ? pair[0] : []); }); }); - test('should work with tuples of different lengths', 4, function() { + test('`_.' + methodName + '` should work with tuples of different lengths', 4, function() { var pair = [ [['barney', 36], ['fred', 40, false]], [['barney', 'fred'], [36, 40], [undefined, false]] ]; - var actual = _.zip(pair[0]); + var actual = func(pair[0]); ok('0' in actual[2]); deepEqual(actual, pair[1]); - actual = _.zip.apply(_, actual); + actual = func(actual); ok('2' in actual[0]); deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]); }); - test('should treat falsey values as empty arrays', 1, function() { + test('`_.' + methodName + '` should treat falsey values as empty arrays', 1, function() { var expected = _.map(falsey, _.constant([])); var actual = _.map(falsey, function(value) { - return _.zip(value, value, value); + return func([value, value, value]); }); deepEqual(actual, expected); }); - test('should support consuming its return value', 1, function() { + test('`_.' + methodName + '` should support consuming its return value', 1, function() { var expected = [['barney', 'fred'], [36, 40]]; - deepEqual(_.zip(_.zip(_.zip(_.zip(expected)))), expected); + deepEqual(func(func(func(func(expected)))), expected); }); - - test('should support consuming its return value', 1, function() { - var expected = [['barney', 'fred'], [36, 40]]; - deepEqual(_.zip(_.zip(_.zip(_.zip(expected)))), expected); - }); - - test('should be aliased', 1, function() { - strictEqual(_.unzip, _.zip); - }); - }()); + }); /*--------------------------------------------------------------------------*/