From 4d6e57a5e698b7b9c69ac9a16b472bce795ab981 Mon Sep 17 00:00:00 2001 From: jdalton Date: Sun, 19 Apr 2015 10:32:27 -0700 Subject: [PATCH] Make `_.zipWith` act like `_.zip` when no `iteratee` is provided and make `_.unzip` ignore non array or `arguments` object values. --- lodash.src.js | 31 ++++++++++++++++++++++--------- test/test.js | 9 +++++++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lodash.src.js b/lodash.src.js index 8452b8617..760ee3116 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -5940,12 +5940,21 @@ * // => [['fred', 'barney'], [30, 40], [true, false]] */ function unzip(array) { + if (!(array && array.length)) { + return []; + } var index = -1, - length = (array && array.length && arrayMax(arrayMap(array, getLength))) >>> 0, - result = Array(length); + length = 0; + var groups = arrayFilter(array, function(value) { + if (isArray(value) || isArguments(value)) { + length = nativeMax(value.length, length); + return true; + } + }); + var result = Array(length); while (++index < length) { - result[index] = arrayMap(array, baseProperty(index)); + result[index] = arrayMap(groups, baseProperty(index)); } return result; } @@ -6069,8 +6078,8 @@ * @memberOf _ * @category Array * @param {...Array} [arrays] Arrays to be zipped with accumulator. - * @param {Function|Object|string} [iteratee=_.identity] The function used - * to reduce zipped elements. + * @param {Function|Object|string} [iteratee] The function used to reduce + * zipped elements. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Array} Returns new array of accumulated groups. * @example @@ -6083,15 +6092,19 @@ iteratee = arrays[length - 2], thisArg = arrays[length - 1]; - if (length > 2 && !isArray(iteratee)) { + if (length > 2 && typeof iteratee == 'function') { length -= 2; } else { - iteratee = (length > 1 && !isArray(thisArg)) ? (--length, thisArg) : undefined; + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; thisArg = undefined; } arrays.length = length; - iteratee = getCallback(iteratee, thisArg, 4); - return arrayMap(unzip(arrays), function(array) { + arrays = unzip(arrays); + if (!iteratee) { + return arrays; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(arrays, function(array) { return arrayReduce(array, iteratee, undefined, true); }); }); diff --git a/test/test.js b/test/test.js index 50952fe4d..04b0327fe 100644 --- a/test/test.js +++ b/test/test.js @@ -16644,6 +16644,11 @@ deepEqual(actual, expected); }); + test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', 1, function() { + var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }]; + deepEqual(func(array), [[1, 3], [2, 4]]); + }); + test('`_.' + methodName + '` should support consuming its return value', 1, function() { var expected = [['barney', 'fred'], [36, 40]]; deepEqual(func(func(func(func(expected)))), expected); @@ -16747,11 +16752,11 @@ deepEqual(actual, [4, 6]); }); - test('should use `_.identity` when `iteratee` is nullish', 1, function() { + test('should perform a basic zip when `iteratee` is nullish', 1, function() { var array1 = [1, 2], array2 = [3, 4], values = [, null, undefined], - expected = _.map(values, _.constant([1, 2])); + expected = _.map(values, _.constant(_.zip(array1, array2))); var actual = _.map(values, function(value, index) { return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);