mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-09 18:37:50 +00:00
Add _.unzipWith.
This commit is contained in:
@@ -5923,7 +5923,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is like `_.zip` except that it accepts an array of grouped
|
* 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`
|
* elements and creates an array regrouping the elements to their pre-zipped
|
||||||
* configuration.
|
* configuration.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
@@ -5946,7 +5946,7 @@
|
|||||||
var index = -1,
|
var index = -1,
|
||||||
length = 0;
|
length = 0;
|
||||||
|
|
||||||
var groups = arrayFilter(array, function(value) {
|
array = arrayFilter(array, function(value) {
|
||||||
if (isArray(value) || isArguments(value)) {
|
if (isArray(value) || isArguments(value)) {
|
||||||
length = nativeMax(value.length, length);
|
length = nativeMax(value.length, length);
|
||||||
return true;
|
return true;
|
||||||
@@ -5954,11 +5954,46 @@
|
|||||||
});
|
});
|
||||||
var result = Array(length);
|
var result = Array(length);
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
result[index] = arrayMap(groups, baseProperty(index));
|
result[index] = arrayMap(array, baseProperty(index));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is like `_.unzip` except that it accepts an iteratee to specify
|
||||||
|
* how regrouped values should be combined. The `iteratee` is bound to `thisArg`
|
||||||
|
* and invoked with four arguments: (accumulator, value, index, array).
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Array
|
||||||
|
* @param {Array} array The array of grouped elements to process.
|
||||||
|
* @param {Function} [iteratee] The function to combine regrouped values.
|
||||||
|
* @param {*} [thisArg] The `this` binding of `iteratee`.
|
||||||
|
* @returns {Array} Returns the new array of regrouped elements.
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* var zipped = _.zip([1, 2], [10, 20], [100, 200]);
|
||||||
|
* // => [[1, 10, 100], [2, 20, 200]]
|
||||||
|
*
|
||||||
|
* _.unzipWith(zipped, _.add);
|
||||||
|
* // => [3, 30, 300]
|
||||||
|
*/
|
||||||
|
function unzipWith(array, iteratee, thisArg) {
|
||||||
|
var length = array ? array.length : 0;
|
||||||
|
if (!length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var result = unzip(array);
|
||||||
|
if (iteratee == null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
iteratee = bindCallback(iteratee, thisArg, 4);
|
||||||
|
return arrayMap(result, function(other) {
|
||||||
|
return arrayReduce(other, iteratee, undefined, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an array excluding all provided values using `SameValueZero` for
|
* Creates an array excluding all provided values using `SameValueZero` for
|
||||||
* equality comparisons.
|
* equality comparisons.
|
||||||
@@ -6071,21 +6106,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines elements of given arrays, like `_.zip` but with a function
|
* This method is like `_.zip` except that it accepts an iteratee to specify
|
||||||
* specifying how they should be combined.
|
* how grouped values should be combined. The `iteratee` is bound to `thisArg`
|
||||||
|
* and invoked with four arguments: (accumulator, value, index, array).
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Array
|
* @category Array
|
||||||
* @param {...Array} [arrays] Arrays to be zipped with accumulator.
|
* @param {...Array} [arrays] The arrays to process.
|
||||||
* @param {Function|Object|string} [iteratee] The function used to reduce
|
* @param {Function} [iteratee] The function to combine grouped values.
|
||||||
* zipped elements.
|
|
||||||
* @param {*} [thisArg] The `this` binding of `iteratee`.
|
* @param {*} [thisArg] The `this` binding of `iteratee`.
|
||||||
* @returns {Array} Returns new array of accumulated groups.
|
* @returns {Array} Returns the new array of grouped elements.
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* _.zipWith([1, 2, 3], [10, 20 , 30], _.add);
|
* _.zipWith([1, 2], [10, 20], [100, 200], _.add);
|
||||||
* // => [11, 22, 33]
|
* // => [111, 222]
|
||||||
*/
|
*/
|
||||||
var zipWith = restParam(function(arrays) {
|
var zipWith = restParam(function(arrays) {
|
||||||
var length = arrays.length,
|
var length = arrays.length,
|
||||||
@@ -6099,14 +6134,7 @@
|
|||||||
thisArg = undefined;
|
thisArg = undefined;
|
||||||
}
|
}
|
||||||
arrays.length = length;
|
arrays.length = length;
|
||||||
arrays = unzip(arrays);
|
return unzipWith(arrays, iteratee, thisArg);
|
||||||
if (!iteratee) {
|
|
||||||
return arrays;
|
|
||||||
}
|
|
||||||
iteratee = bindCallback(iteratee, thisArg, 4);
|
|
||||||
return arrayMap(arrays, function(array) {
|
|
||||||
return arrayReduce(array, iteratee, undefined, true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
@@ -12049,6 +12077,7 @@
|
|||||||
lodash.union = union;
|
lodash.union = union;
|
||||||
lodash.uniq = uniq;
|
lodash.uniq = uniq;
|
||||||
lodash.unzip = unzip;
|
lodash.unzip = unzip;
|
||||||
|
lodash.unzipWith = unzipWith;
|
||||||
lodash.values = values;
|
lodash.values = values;
|
||||||
lodash.valuesIn = valuesIn;
|
lodash.valuesIn = valuesIn;
|
||||||
lodash.where = where;
|
lodash.where = where;
|
||||||
|
|||||||
193
test/test.js
193
test/test.js
@@ -16330,6 +16330,47 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
QUnit.module('lodash.unzipWith');
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
test('should unzip arrays combining regrouped elements with `iteratee`', 1, function() {
|
||||||
|
var array = [[1, 4], [2, 5], [3, 6]];
|
||||||
|
deepEqual(_.unzipWith(array, _.add), [6, 15]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should provide the correct `iteratee` arguments', 1, function() {
|
||||||
|
var args;
|
||||||
|
|
||||||
|
_.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(args, [1, 2, 1, [1, 2]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should support the `thisArg` argument', 1, function() {
|
||||||
|
var actual = _.unzipWith([[1.2, 3.4], [2.3, 4.5]], function(a, b) {
|
||||||
|
return this.floor(a) + this.floor(b);
|
||||||
|
}, Math);
|
||||||
|
|
||||||
|
deepEqual(actual, [3, 7]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should perform a basic unzip when `iteratee` is nullish', 1, function() {
|
||||||
|
var array = [[1, 3], [2, 4]],
|
||||||
|
values = [, null, undefined],
|
||||||
|
expected = _.map(values, _.constant(_.unzip(array)));
|
||||||
|
|
||||||
|
var actual = _.map(values, function(value, index) {
|
||||||
|
return index ? _.unzipWith(array, value) : _.unzipWith(array);
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
QUnit.module('lodash.values');
|
QUnit.module('lodash.values');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
@@ -16586,77 +16627,6 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
QUnit.module('lodash.unzip and lodash.zip');
|
|
||||||
|
|
||||||
_.each(['unzip', 'zip'], function(methodName, index) {
|
|
||||||
var func = _[methodName];
|
|
||||||
func = _.bind(index ? func.apply : func.call, func, null);
|
|
||||||
|
|
||||||
var object = {
|
|
||||||
'an empty array': [
|
|
||||||
[],
|
|
||||||
[]
|
|
||||||
],
|
|
||||||
'0-tuples': [
|
|
||||||
[[], []],
|
|
||||||
[]
|
|
||||||
],
|
|
||||||
'2-tuples': [
|
|
||||||
[['barney', 'fred'], [36, 40]],
|
|
||||||
[['barney', 36], ['fred', 40]]
|
|
||||||
],
|
|
||||||
'3-tuples': [
|
|
||||||
[['barney', 'fred'], [36, 40], [true, false]],
|
|
||||||
[['barney', 36, true], ['fred', 40, false]]
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
_.forOwn(object, function(pair, key) {
|
|
||||||
test('`_.' + methodName + '` should work with ' + key, 2, function() {
|
|
||||||
var actual = func(pair[0]);
|
|
||||||
deepEqual(actual, pair[1]);
|
|
||||||
deepEqual(func(actual), actual.length ? pair[0] : []);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
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 = func(pair[0]);
|
|
||||||
ok('0' in actual[2]);
|
|
||||||
deepEqual(actual, pair[1]);
|
|
||||||
|
|
||||||
actual = func(actual);
|
|
||||||
ok('2' in actual[0]);
|
|
||||||
deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('`_.' + methodName + '` should treat falsey values as empty arrays', 1, function() {
|
|
||||||
var expected = _.map(falsey, _.constant([]));
|
|
||||||
|
|
||||||
var actual = _.map(falsey, function(value) {
|
|
||||||
return func([value, value, value]);
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
QUnit.module('lodash.zipObject');
|
QUnit.module('lodash.zipObject');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
@@ -16726,11 +16696,11 @@
|
|||||||
QUnit.module('lodash.zipWith');
|
QUnit.module('lodash.zipWith');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
test('should zip arrays combining their elements with `iteratee`', 2, function() {
|
test('should zip arrays combining grouped elements with `iteratee`', 2, function() {
|
||||||
var array1 = [1, 2, 3],
|
var array1 = [1, 2, 3],
|
||||||
array2 = [1, 2, 3];
|
array2 = [4, 5, 6];
|
||||||
|
|
||||||
deepEqual(_.zipWith(array1, array2, _.add), [2, 4, 6]);
|
deepEqual(_.zipWith(array1, array2, _.add), [5, 7, 9]);
|
||||||
deepEqual(_.zipWith(array1, [], _.add), [1, 2, 3]);
|
deepEqual(_.zipWith(array1, [], _.add), [1, 2, 3]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -16764,7 +16734,78 @@
|
|||||||
|
|
||||||
deepEqual(actual, expected);
|
deepEqual(actual, expected);
|
||||||
});
|
});
|
||||||
}())
|
}());
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
QUnit.module('lodash.unzip and lodash.zip');
|
||||||
|
|
||||||
|
_.each(['unzip', 'zip'], function(methodName, index) {
|
||||||
|
var func = _[methodName];
|
||||||
|
func = _.bind(index ? func.apply : func.call, func, null);
|
||||||
|
|
||||||
|
var object = {
|
||||||
|
'an empty array': [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
'0-tuples': [
|
||||||
|
[[], []],
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
'2-tuples': [
|
||||||
|
[['barney', 'fred'], [36, 40]],
|
||||||
|
[['barney', 36], ['fred', 40]]
|
||||||
|
],
|
||||||
|
'3-tuples': [
|
||||||
|
[['barney', 'fred'], [36, 40], [true, false]],
|
||||||
|
[['barney', 36, true], ['fred', 40, false]]
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
_.forOwn(object, function(pair, key) {
|
||||||
|
test('`_.' + methodName + '` should work with ' + key, 2, function() {
|
||||||
|
var actual = func(pair[0]);
|
||||||
|
deepEqual(actual, pair[1]);
|
||||||
|
deepEqual(func(actual), actual.length ? pair[0] : []);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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 = func(pair[0]);
|
||||||
|
ok('0' in actual[2]);
|
||||||
|
deepEqual(actual, pair[1]);
|
||||||
|
|
||||||
|
actual = func(actual);
|
||||||
|
ok('2' in actual[0]);
|
||||||
|
deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('`_.' + methodName + '` should treat falsey values as empty arrays', 1, function() {
|
||||||
|
var expected = _.map(falsey, _.constant([]));
|
||||||
|
|
||||||
|
var actual = _.map(falsey, function(value) {
|
||||||
|
return func([value, value, value]);
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -17566,7 +17607,7 @@
|
|||||||
|
|
||||||
var acceptFalsey = _.difference(allMethods, rejectFalsey);
|
var acceptFalsey = _.difference(allMethods, rejectFalsey);
|
||||||
|
|
||||||
test('should accept falsey arguments', 219, function() {
|
test('should accept falsey arguments', 220, function() {
|
||||||
var emptyArrays = _.map(falsey, _.constant([])),
|
var emptyArrays = _.map(falsey, _.constant([])),
|
||||||
isExposed = '_' in root,
|
isExposed = '_' in root,
|
||||||
oldDash = root._;
|
oldDash = root._;
|
||||||
|
|||||||
Reference in New Issue
Block a user