Remove callback support from _.flatten and make it shallow by default.

This commit is contained in:
John-David Dalton
2014-06-17 00:09:04 -07:00
parent 62e84e73ae
commit 20202b793b
2 changed files with 30 additions and 45 deletions

View File

@@ -1582,8 +1582,8 @@
} }
/** /**
* The base implementation of `_.flatten` without support for callback * The base implementation of `_.flatten` with added support for restricting
* shorthands and `this` binding. * flattening and specifying the start index.
* *
* @private * @private
* @param {Array} array The array to flatten. * @param {Array} array The array to flatten.
@@ -1592,7 +1592,7 @@
* @param {number} [fromIndex=0] The index to start from. * @param {number} [fromIndex=0] The index to start from.
* @returns {Array} Returns the new flattened array. * @returns {Array} Returns the new flattened array.
*/ */
function baseFlatten(array, isShallow, isStrict, fromIndex) { function baseFlatten(array, isDeep, isStrict, fromIndex) {
var index = (fromIndex || 0) - 1, var index = (fromIndex || 0) - 1,
length = array ? array.length : 0, length = array ? array.length : 0,
resIndex = 0, resIndex = 0,
@@ -1604,8 +1604,8 @@
if (value && typeof value == 'object' && typeof value.length == 'number' if (value && typeof value == 'object' && typeof value.length == 'number'
&& (isArray(value) || isArguments(value))) { && (isArray(value) || isArguments(value))) {
// recursively flatten arrays (susceptible to call stack limits) // recursively flatten arrays (susceptible to call stack limits)
if (!isShallow) { if (isDeep) {
value = baseFlatten(value, isShallow, isStrict); value = baseFlatten(value, isDeep, isStrict);
} }
var valIndex = -1, var valIndex = -1,
valLength = value.length; valLength = value.length;
@@ -2730,7 +2730,7 @@
break; break;
} }
} }
return baseDifference(arguments[index], baseFlatten(arguments, true, true, ++index)); return baseDifference(arguments[index], baseFlatten(arguments, false, true, ++index));
} }
/** /**
@@ -3031,51 +3031,29 @@
* @memberOf _ * @memberOf _
* @category Arrays * @category Arrays
* @param {Array} array The array to flatten. * @param {Array} array The array to flatten.
* @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. * @param {boolean} [isDeep=false] Specify a deep flatten.
* @param {Function|Object|string} [callback] The function called per iteration. * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
* If a property name or object is provided it is used to create a "_.pluck"
* or "_.where" style callback respectively.
* @param {*} [thisArg] The `this` binding of `callback`.
* @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];
*
* // using `isShallow`
* _.flatten([1, [2], [3, [[4]]]], true);
* // => [1, 2, 3, [[4]]]; * // => [1, 2, 3, [[4]]];
* *
* var characters = [ * // using `isDeep`
* { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, * _.flatten([1, [2], [3, [[4]]]], true);
* { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } * // => [1, 2, 3, 4];
* ];
*
* // using "_.pluck" callback shorthand
* _.flatten(characters, 'pets');
* // => ['hoppy', 'baby puss', 'dino']
*/ */
function flatten(array, isShallow, callback, thisArg) { function flatten(array, isDeep, guard) {
var length = array ? array.length : 0; var length = array ? array.length : 0;
if (!length) { if (!length) {
return []; return [];
} }
// juggle arguments // enables use as a callback for functions like `_.map`
var type = typeof isShallow; var type = typeof isDeep;
if (type != 'boolean' && isShallow != null) { if ((type == 'number' || type == 'string') && guard && guard[isDeep] === array) {
thisArg = callback; isDeep = false;
callback = isShallow;
isShallow = false;
// enables use as a callback for functions like `_.map`
if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === array) {
callback = null;
}
} }
if (callback != null) { return baseFlatten(array, isDeep);
array = map(array, callback, thisArg);
}
return baseFlatten(array, isShallow);
} }
/** /**
@@ -3341,7 +3319,7 @@
* // => [10, 20] * // => [10, 20]
*/ */
function pullAt(array) { function pullAt(array) {
return basePullAt(array, baseFlatten(arguments, true, false, 1)); return basePullAt(array, baseFlatten(arguments, false, false, 1));
} }
/** /**
@@ -3685,7 +3663,7 @@
* // => [1, 2, 3, 5, 4] * // => [1, 2, 3, 5, 4]
*/ */
function union() { function union() {
return baseUniq(baseFlatten(arguments, true, true)); return baseUniq(baseFlatten(arguments, false, true));
} }
/** /**
@@ -4023,7 +4001,7 @@
if (support.unindexedChars && isString(collection)) { if (support.unindexedChars && isString(collection)) {
collection = collection.split(''); collection = collection.split('');
} }
return baseAt(collection, baseFlatten(arguments, true, false, 1)); return baseAt(collection, baseFlatten(arguments, false, false, 1));
} }
/** /**
@@ -5312,7 +5290,7 @@
*/ */
function bindAll(object) { function bindAll(object) {
return baseBindAll(object, arguments.length > 1 return baseBindAll(object, arguments.length > 1
? baseFlatten(arguments, true, false, 1) ? baseFlatten(arguments, false, false, 1)
: functions(object)); : functions(object));
} }
@@ -7207,7 +7185,7 @@
if (typeof predicate == 'function') { if (typeof predicate == 'function') {
return basePick(object, negate(lodash.createCallback(predicate, thisArg, 3))); return basePick(object, negate(lodash.createCallback(predicate, thisArg, 3)));
} }
var omitProps = baseFlatten(arguments, true, false, 1); var omitProps = baseFlatten(arguments, false, false, 1);
return basePick(object, baseDifference(keysIn(object), arrayMap(omitProps, String))); return basePick(object, baseDifference(keysIn(object), arrayMap(omitProps, String)));
} }
@@ -7271,7 +7249,7 @@
} }
return basePick(object, typeof predicate == 'function' return basePick(object, typeof predicate == 'function'
? lodash.createCallback(predicate, thisArg, 3) ? lodash.createCallback(predicate, thisArg, 3)
: baseFlatten(arguments, true, false, 1)); : baseFlatten(arguments, false, false, 1));
} }
/** /**

View File

@@ -42,6 +42,12 @@
// excuse tests we intentionally fail or those with problems // excuse tests we intentionally fail or those with problems
QUnit.config.excused = { QUnit.config.excused = {
'Arrays': { 'Arrays': {
'flatten': [
'can flatten nested arrays',
'can shallowly flatten nested arrays',
'works on an arguments object',
'can shallowly flatten arrays containing only other arrays'
],
'initial': [ 'initial': [
'initial works on arguments object' 'initial works on arguments object'
], ],
@@ -158,6 +164,7 @@
delete QUnit.config.excused.Functions.partial; delete QUnit.config.excused.Functions.partial;
} }
QUnit.config.excused.Arrays.intersection.shift(); QUnit.config.excused.Arrays.intersection.shift();
delete QUnit.config.excused.Arrays.flatten;
delete QUnit.config.excused.Arrays.initial; delete QUnit.config.excused.Arrays.initial;
delete QUnit.config.excused.Arrays.rest; delete QUnit.config.excused.Arrays.rest;
delete QUnit.config.excused.Chaining; delete QUnit.config.excused.Chaining;