mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-11 03:17:49 +00:00
Added _.flattenDepth for variable-depth flatten.
This commit is contained in:
committed by
John-David Dalton
parent
2b1eedb036
commit
046470a8db
@@ -50,9 +50,9 @@ exports.aryMethod = {
|
|||||||
'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
|
'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
|
||||||
'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every',
|
'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every',
|
||||||
'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex',
|
'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex',
|
||||||
'findLastKey', 'flatMap', 'forEach', 'forEachRight', 'forIn', 'forInRight',
|
'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn',
|
||||||
'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn',
|
'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has',
|
||||||
'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap',
|
'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap',
|
||||||
'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map',
|
'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map',
|
||||||
'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit',
|
'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit',
|
||||||
'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
|
'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
|
||||||
|
|||||||
88
lodash.js
88
lodash.js
@@ -1399,23 +1399,23 @@
|
|||||||
* `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
|
* `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
|
||||||
* `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
|
* `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
|
||||||
* `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
|
* `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
|
||||||
* `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
|
* `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`,
|
||||||
* `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
|
* `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`,
|
||||||
* `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`,
|
* `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`,
|
||||||
* `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`,
|
* `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`,
|
||||||
* `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`,
|
* `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`,
|
||||||
* `method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`,
|
* `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`,
|
||||||
* `orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`,
|
* `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`,
|
||||||
* `partialRight`, `partition`, `pick`, `pickBy`, `plant`, `property`,
|
* `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`,
|
||||||
* `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`,
|
* `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`,
|
||||||
* `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`,
|
* `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`,
|
||||||
* `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`,
|
* `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`,
|
||||||
* `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`,
|
* `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`,
|
||||||
* `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`,
|
* `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`,
|
||||||
* `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`,
|
* `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`,
|
||||||
* `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`,
|
* `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`,
|
||||||
* `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`,
|
* `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`,
|
||||||
* `zipObjectDeep`, and `zipWith`
|
* `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith`
|
||||||
*
|
*
|
||||||
* The wrapper methods that are **not** chainable by default are:
|
* The wrapper methods that are **not** chainable by default are:
|
||||||
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
|
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
|
||||||
@@ -2494,12 +2494,14 @@
|
|||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {Array} array The array to flatten.
|
* @param {Array} array The array to flatten.
|
||||||
* @param {boolean} [isDeep] Specify a deep flatten.
|
* @param {number} [depth=1] The maximum recursion depth.
|
||||||
* @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
|
* @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
|
||||||
* @param {Array} [result=[]] The initial result value.
|
* @param {Array} [result=[]] The initial result value.
|
||||||
* @returns {Array} Returns the new flattened array.
|
* @returns {Array} Returns the new flattened array.
|
||||||
*/
|
*/
|
||||||
function baseFlatten(array, isDeep, isStrict, result) {
|
function baseFlatten(array, depth, isStrict, result) {
|
||||||
|
depth = depth === undefined ? 1 : depth;
|
||||||
|
|
||||||
result || (result = []);
|
result || (result = []);
|
||||||
|
|
||||||
var index = -1,
|
var index = -1,
|
||||||
@@ -2509,9 +2511,9 @@
|
|||||||
var value = array[index];
|
var value = array[index];
|
||||||
if (isArrayLikeObject(value) &&
|
if (isArrayLikeObject(value) &&
|
||||||
(isStrict || isArray(value) || isArguments(value))) {
|
(isStrict || isArray(value) || isArguments(value))) {
|
||||||
if (isDeep) {
|
if (depth > 1) {
|
||||||
// Recursively flatten arrays (susceptible to call stack limits).
|
// Recursively flatten arrays (susceptible to call stack limits).
|
||||||
baseFlatten(value, isDeep, isStrict, result);
|
baseFlatten(value, depth - 1, isStrict, result);
|
||||||
} else {
|
} else {
|
||||||
arrayPush(result, value);
|
arrayPush(result, value);
|
||||||
}
|
}
|
||||||
@@ -5475,7 +5477,7 @@
|
|||||||
*/
|
*/
|
||||||
var difference = rest(function(array, values) {
|
var difference = rest(function(array, values) {
|
||||||
return isArrayLikeObject(array)
|
return isArrayLikeObject(array)
|
||||||
? baseDifference(array, baseFlatten(values, false, true))
|
? baseDifference(array, baseFlatten(values, 1, true))
|
||||||
: [];
|
: [];
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -5506,7 +5508,7 @@
|
|||||||
iteratee = undefined;
|
iteratee = undefined;
|
||||||
}
|
}
|
||||||
return isArrayLikeObject(array)
|
return isArrayLikeObject(array)
|
||||||
? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee))
|
? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee))
|
||||||
: [];
|
: [];
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -5535,7 +5537,7 @@
|
|||||||
comparator = undefined;
|
comparator = undefined;
|
||||||
}
|
}
|
||||||
return isArrayLikeObject(array)
|
return isArrayLikeObject(array)
|
||||||
? baseDifference(array, baseFlatten(values, false, true), undefined, comparator)
|
? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator)
|
||||||
: [];
|
: [];
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -5814,7 +5816,7 @@
|
|||||||
* @returns {Array} Returns the new flattened array.
|
* @returns {Array} Returns the new flattened array.
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* _.flatten([1, [2, 3, [4]]]);
|
* _.flatten([1, 2, [3, [4]]]);
|
||||||
* // => [1, 2, 3, [4]]
|
* // => [1, 2, 3, [4]]
|
||||||
*/
|
*/
|
||||||
function flatten(array) {
|
function flatten(array) {
|
||||||
@@ -5832,12 +5834,35 @@
|
|||||||
* @returns {Array} Returns the new flattened array.
|
* @returns {Array} Returns the new flattened array.
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* _.flattenDeep([1, [2, 3, [4]]]);
|
* _.flattenDeep([1, [2, [3, [[4]]], 5]]);
|
||||||
* // => [1, 2, 3, 4]
|
* // => [1, 2, 3, 4, 5]
|
||||||
*/
|
*/
|
||||||
function flattenDeep(array) {
|
function flattenDeep(array) {
|
||||||
var length = array ? array.length : 0;
|
var length = array ? array.length : 0;
|
||||||
return length ? baseFlatten(array, true) : [];
|
return length ? baseFlatten(array, INFINITY) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively flatten `array` up to `depth` times.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Array
|
||||||
|
* @param {Array} array The array to flatten.
|
||||||
|
* @param {number} depth The maximum recursion depth.
|
||||||
|
* @returns {Array} Returns the new flattened array.
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* _.flattenDepth([1, [2, [3, [4]], 5]], 1);
|
||||||
|
* // => [1, 2, [3, [4]], 5]
|
||||||
|
*
|
||||||
|
* _.flattenDepth([1, [2, [3, [4]], 5]], 2);
|
||||||
|
* // => [1, 2, 3, [4], 5]
|
||||||
|
*/
|
||||||
|
function flattenDepth(array, depth) {
|
||||||
|
depth = toInteger(depth);
|
||||||
|
var length = array ? array.length : 0;
|
||||||
|
return length ? (depth >= 1 ? baseFlatten(array, depth) : copyArray(array)) : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6677,7 +6702,7 @@
|
|||||||
* // => [2, 1, 4]
|
* // => [2, 1, 4]
|
||||||
*/
|
*/
|
||||||
var union = rest(function(arrays) {
|
var union = rest(function(arrays) {
|
||||||
return baseUniq(baseFlatten(arrays, false, true));
|
return baseUniq(baseFlatten(arrays, 1, true));
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6705,7 +6730,7 @@
|
|||||||
if (isArrayLikeObject(iteratee)) {
|
if (isArrayLikeObject(iteratee)) {
|
||||||
iteratee = undefined;
|
iteratee = undefined;
|
||||||
}
|
}
|
||||||
return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee));
|
return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee));
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6732,7 +6757,7 @@
|
|||||||
if (isArrayLikeObject(comparator)) {
|
if (isArrayLikeObject(comparator)) {
|
||||||
comparator = undefined;
|
comparator = undefined;
|
||||||
}
|
}
|
||||||
return baseUniq(baseFlatten(arrays, false, true), undefined, comparator);
|
return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14208,6 +14233,7 @@
|
|||||||
lodash.flatMap = flatMap;
|
lodash.flatMap = flatMap;
|
||||||
lodash.flatten = flatten;
|
lodash.flatten = flatten;
|
||||||
lodash.flattenDeep = flattenDeep;
|
lodash.flattenDeep = flattenDeep;
|
||||||
|
lodash.flattenDepth = flattenDepth;
|
||||||
lodash.flip = flip;
|
lodash.flip = flip;
|
||||||
lodash.flow = flow;
|
lodash.flow = flow;
|
||||||
lodash.flowRight = flowRight;
|
lodash.flowRight = flowRight;
|
||||||
|
|||||||
24
test/test.js
24
test/test.js
@@ -5620,31 +5620,37 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should work with empty arrays', function(assert) {
|
QUnit.test('should work with empty arrays', function(assert) {
|
||||||
assert.expect(2);
|
assert.expect(3);
|
||||||
|
|
||||||
var array = [[], [[]], [[], [[[]]]]];
|
var array = [[], [[]], [[], [[[]]]]];
|
||||||
|
|
||||||
assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
|
assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
|
||||||
assert.deepEqual(_.flattenDeep(array), []);
|
assert.deepEqual(_.flattenDeep(array), []);
|
||||||
|
assert.deepEqual(_.flattenDepth(array, 2), [[[]]])
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should support flattening of nested arrays', function(assert) {
|
QUnit.test('should support flattening of nested arrays', function(assert) {
|
||||||
assert.expect(2);
|
assert.expect(4);
|
||||||
|
|
||||||
var array = [1, [2, 3], 4, [[5]]];
|
var array = [1, [[2, 3], 4, [[[5]]]]];
|
||||||
|
|
||||||
assert.deepEqual(_.flatten(array), [1, 2, 3, 4, [5]]);
|
assert.deepEqual(_.flatten(array), [1, [2, 3], 4, [[[5]]]]);
|
||||||
assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
|
assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
|
||||||
|
assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 4, [[5]]]);
|
||||||
|
assert.deepEqual(_.flattenDepth(array, 3), [1, 2, 3, 4, [5]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should return an empty array for non array-like objects', function(assert) {
|
QUnit.test('should return an empty array for non array-like objects', function(assert) {
|
||||||
assert.expect(3);
|
assert.expect(5);
|
||||||
|
|
||||||
|
var nonArray = { 'a': 1 };
|
||||||
var expected = [];
|
var expected = [];
|
||||||
|
|
||||||
assert.deepEqual(_.flatten({ 'a': 1 }), expected);
|
assert.deepEqual(_.flatten(nonArray), expected);
|
||||||
assert.deepEqual(_.flatten({ 'a': 1 }, true), expected);
|
assert.deepEqual(_.flatten(nonArray, true), expected);
|
||||||
assert.deepEqual(_.flattenDeep({ 'a': 1 }), expected);
|
assert.deepEqual(_.flattenDeep(nonArray), expected);
|
||||||
|
assert.deepEqual(_.flattenDepth(nonArray, 2), expected);
|
||||||
|
assert.deepEqual(_.flattenDepth(nonArray, 0), expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should return a wrapped value when chaining', function(assert) {
|
QUnit.test('should return a wrapped value when chaining', function(assert) {
|
||||||
@@ -24035,7 +24041,7 @@
|
|||||||
var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
|
var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
|
||||||
|
|
||||||
QUnit.test('should accept falsey arguments', function(assert) {
|
QUnit.test('should accept falsey arguments', function(assert) {
|
||||||
assert.expect(295);
|
assert.expect(296);
|
||||||
|
|
||||||
var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);
|
var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user