From 936a1c27646451844f4ebbb00b28ca13d01bd037 Mon Sep 17 00:00:00 2001 From: jdalton Date: Sat, 18 Apr 2015 11:24:11 -0700 Subject: [PATCH] Add support for `thisArg` in `zipWith`. --- lodash.src.js | 17 +++++++++++++++-- test/test.js | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/lodash.src.js b/lodash.src.js index 53af8d086..8452b8617 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -6069,7 +6069,9 @@ * @memberOf _ * @category Array * @param {...Array} [arrays] Arrays to be zipped with accumulator. - * @param {Function} accumulator Function used to reduce zipped elements. + * @param {Function|Object|string} [iteratee=_.identity] The function used + * to reduce zipped elements. + * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Array} Returns new array of accumulated groups. * @example * @@ -6077,7 +6079,18 @@ * // => [11, 22, 33] */ var zipWith = restParam(function(arrays) { - var iteratee = arrays.pop(); + var length = arrays.length, + iteratee = arrays[length - 2], + thisArg = arrays[length - 1]; + + if (length > 2 && !isArray(iteratee)) { + length -= 2; + } else { + iteratee = (length > 1 && !isArray(thisArg)) ? (--length, thisArg) : undefined; + thisArg = undefined; + } + arrays.length = length; + iteratee = getCallback(iteratee, thisArg, 4); return arrayMap(unzip(arrays), function(array) { return arrayReduce(array, iteratee, undefined, true); }); diff --git a/test/test.js b/test/test.js index c9428ad26..50952fe4d 100644 --- a/test/test.js +++ b/test/test.js @@ -16721,13 +16721,44 @@ QUnit.module('lodash.zipWith'); (function() { - test('should combine values in lists with given function', 2, function() { + test('should zip arrays combining their elements with `iteratee`', 2, function() { var array1 = [1, 2, 3], array2 = [1, 2, 3]; deepEqual(_.zipWith(array1, array2, _.add), [2, 4, 6]); deepEqual(_.zipWith(array1, [], _.add), [1, 2, 3]); }); + + test('should provide the correct `iteratee` arguments', 1, function() { + var args; + + _.zipWith([1, 2], [3, 4], [5, 6], function() { + args || (args = slice.call(arguments)); + }); + + deepEqual(args, [1, 3, 1, [1, 3, 5]]); + }); + + test('should support the `thisArg` argument', 1, function() { + var actual = _.zipWith([1.2, 2.3], [3.4, 4.5], function(a, b) { + return this.floor(a) + this.floor(b); + }, Math); + + deepEqual(actual, [4, 6]); + }); + + test('should use `_.identity` when `iteratee` is nullish', 1, function() { + var array1 = [1, 2], + array2 = [3, 4], + values = [, null, undefined], + expected = _.map(values, _.constant([1, 2])); + + var actual = _.map(values, function(value, index) { + return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2); + }); + + deepEqual(actual, expected); + }); }()) /*--------------------------------------------------------------------------*/