Added _.flattenDepth for variable-depth flatten.

This commit is contained in:
Michael Morgan
2016-02-08 17:09:13 -06:00
committed by John-David Dalton
parent 2b1eedb036
commit 046470a8db
3 changed files with 75 additions and 43 deletions

View File

@@ -1399,23 +1399,23 @@
* `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
* `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
* `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
* `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
* `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
* `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`,
* `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`,
* `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`,
* `method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`,
* `orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`,
* `partialRight`, `partition`, `pick`, `pickBy`, `plant`, `property`,
* `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`,
* `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`,
* `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`,
* `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`,
* `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`,
* `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`,
* `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`,
* `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`,
* `zipObjectDeep`, and `zipWith`
* `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`,
* `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`,
* `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`,
* `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`,
* `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`,
* `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`,
* `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`,
* `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`,
* `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`,
* `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`,
* `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`,
* `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`,
* `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`,
* `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`,
* `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`,
* `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`,
* `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith`
*
* The wrapper methods that are **not** chainable by default are:
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
@@ -2494,12 +2494,14 @@
*
* @private
* @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 {Array} [result=[]] The initial result value.
* @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 = []);
var index = -1,
@@ -2509,9 +2511,9 @@
var value = array[index];
if (isArrayLikeObject(value) &&
(isStrict || isArray(value) || isArguments(value))) {
if (isDeep) {
if (depth > 1) {
// Recursively flatten arrays (susceptible to call stack limits).
baseFlatten(value, isDeep, isStrict, result);
baseFlatten(value, depth - 1, isStrict, result);
} else {
arrayPush(result, value);
}
@@ -5475,7 +5477,7 @@
*/
var difference = rest(function(array, values) {
return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, false, true))
? baseDifference(array, baseFlatten(values, 1, true))
: [];
});
@@ -5506,7 +5508,7 @@
iteratee = undefined;
}
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;
}
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.
* @example
*
* _.flatten([1, [2, 3, [4]]]);
* _.flatten([1, 2, [3, [4]]]);
* // => [1, 2, 3, [4]]
*/
function flatten(array) {
@@ -5832,12 +5834,35 @@
* @returns {Array} Returns the new flattened array.
* @example
*
* _.flattenDeep([1, [2, 3, [4]]]);
* // => [1, 2, 3, 4]
* _.flattenDeep([1, [2, [3, [[4]]], 5]]);
* // => [1, 2, 3, 4, 5]
*/
function flattenDeep(array) {
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]
*/
var union = rest(function(arrays) {
return baseUniq(baseFlatten(arrays, false, true));
return baseUniq(baseFlatten(arrays, 1, true));
});
/**
@@ -6705,7 +6730,7 @@
if (isArrayLikeObject(iteratee)) {
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)) {
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.flatten = flatten;
lodash.flattenDeep = flattenDeep;
lodash.flattenDepth = flattenDepth;
lodash.flip = flip;
lodash.flow = flow;
lodash.flowRight = flowRight;