Add _.unzip. [closes #225]

Former-commit-id: 4b2c7fc068fd430f3d78de850a5f7670fd0e1a4e
This commit is contained in:
John-David Dalton
2013-04-02 22:34:15 -07:00
parent 265ca8ba67
commit e76360c1b5
6 changed files with 138 additions and 26 deletions

View File

@@ -171,6 +171,7 @@
'union': ['uniq'],
'uniq': ['createCallback', 'indexOf'],
'uniqueId': [],
'unzip': ['max', 'pluck'],
'value': ['forOwn', 'isArray'],
'values': ['keys'],
'where': ['filter'],
@@ -258,8 +259,8 @@
'without'
];
/** List of methods used by Underscore */
var underscoreMethods = _.without.apply(_, [allMethods].concat([
/** List of Lo-Dash only methods */
var lodashOnlyMethods = [
'at',
'bindKey',
'cloneDeep',
@@ -272,8 +273,12 @@
'merge',
'parseInt',
'partialRight',
'runInContext'
]));
'runInContext',
'unzip'
];
/** List of methods used by Underscore */
var underscoreMethods = _.without.apply(_, [allMethods].concat(lodashOnlyMethods));
/** List of ways to export the `lodash` function */
var exportsAll = [

View File

@@ -210,6 +210,7 @@
'uniq',
'unique',
'uniqueId',
'unzip',
'value',
'values',
'variable',

View File

@@ -222,8 +222,8 @@
* `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
* `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
* `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
* `tap`, `throttle`, `times`, `toArray`, `union`, `uniq`, `unshift`, `values`,
* `where`, `without`, `wrap`, and `zip`
* `tap`, `throttle`, `times`, `toArray`, `union`, `uniq`, `unshift`, `unzip`,
* `values`, `where`, `without`, `wrap`, and `zip`
*
* The non-chainable wrapper functions are:
* `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
@@ -4051,6 +4051,37 @@
return result;
}
/**
* 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(array) {
var index = -1,
length = array ? array.length : 0,
tupleLength = length ? max(pluck(array, 'length')) : 0,
result = Array(tupleLength);
while (++index < length) {
var tupleIndex = -1,
tuple = array[index];
while (++tupleIndex < tupleLength) {
(result[tupleIndex] || (result[tupleIndex] = Array(length)))[index] = tuple[tupleIndex];
}
}
return result;
}
/**
* Creates an array with all occurrences of the passed values removed using
* strict equality for comparisons, i.e. `===`.
@@ -5242,6 +5273,7 @@
lodash.toArray = toArray;
lodash.union = union;
lodash.uniq = uniq;
lodash.unzip = unzip;
lodash.values = values;
lodash.where = where;
lodash.without = without;

View File

@@ -487,6 +487,10 @@
var _findWhere = _.findWhere || _.find,\
lodashFindWhere = lodash.findWhere || lodash.find,\
whereObject = { "num": 9 };\
}\
if (typeof zip != "undefined") {\
var unzipped = [["a", "b", "c"], [1, 2, 3], [true, false, true]],\
zipped = [["a", 1, true], ["b", 2, false], ["c", 3, true]];\
}'
});
@@ -1752,6 +1756,20 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.unzip`')
.add(buildName, {
'fn': 'lodash.unzip(zipped);',
'teardown': 'function zip(){}'
})
.add(otherName, {
'fn': '_.unzip(zipped);',
'teardown': 'function zip(){}'
})
);
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.values`')
.add(buildName, '\
@@ -1802,6 +1820,20 @@
/*--------------------------------------------------------------------------*/
suites.push(
Benchmark.Suite('`_.zip`')
.add(buildName, {
'fn': 'lodash.zip.apply(lodash, unzipped);',
'teardown': 'function zip(){}'
})
.add(otherName, {
'fn': '_.zip.apply(_, unzipped);',
'teardown': 'function zip(){}'
})
);
/*--------------------------------------------------------------------------*/
if (Benchmark.platform + '') {
log(Benchmark.platform);
}

View File

@@ -118,6 +118,7 @@
'union',
'uniq',
'unique',
'unzip',
'without',
'zip',
'zipObject'
@@ -296,8 +297,8 @@
'without'
];
/** List of methods used by Underscore */
var underscoreMethods = _.without.apply(_, [allMethods].concat([
/** List of Lo-Dash only methods */
var lodashOnlyMethods = [
'at',
'bindKey',
'cloneDeep',
@@ -310,8 +311,12 @@
'merge',
'parseInt',
'partialRight',
'runInContext'
]));
'runInContext',
'unzip'
];
/** List of methods used by Underscore */
var underscoreMethods = _.without.apply(_, [allMethods].concat(lodashOnlyMethods));
/*--------------------------------------------------------------------------*/
@@ -970,22 +975,7 @@
vm.runInContext(data.source, context);
var lodash = context._;
_.each([
'assign',
'at',
'bindKey',
'createCallback',
'findIndex',
'findKey',
'forIn',
'forOwn',
'isPlainObject',
'merge',
'parseInt',
'partialRight',
'runInContext',
'zipObject'
], function(methodName) {
_.each(lodashOnlyMethods.concat('assign'), function(methodName) {
equal(lodash[methodName], undefined, '_.' + methodName + ' should not exist: ' + basename);
});

View File

@@ -2787,6 +2787,58 @@
/*--------------------------------------------------------------------------*/
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() {