Reduce the number of function creator helpers to improve readabilty.

This commit is contained in:
jdalton
2015-07-05 11:22:47 -07:00
committed by John-David Dalton
parent 86b19f742c
commit 10c44b08c9

View File

@@ -2475,52 +2475,6 @@
};
}
/**
* The base implementation of `_.merge` without support for argument juggling,
* multiple sources, and `this` binding `customizer` functions.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @param {Function} [customizer] The function to customize merged values.
* @param {Array} [stackA=[]] Tracks traversed source objects.
* @param {Array} [stackB=[]] Associates values with source counterparts.
* @returns {Object} Returns `object`.
*/
function baseMerge(object, source, customizer, stackA, stackB) {
if (!isObject(object)) {
return object;
}
var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
props = isSrcArr ? undefined : keys(source);
arrayEach(props || source, function(srcValue, key) {
if (props) {
key = srcValue;
srcValue = source[key];
}
if (isObjectLike(srcValue)) {
stackA || (stackA = []);
stackB || (stackB = []);
baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
}
else {
var value = object[key],
result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
isCommon = result === undefined;
if (isCommon) {
result = srcValue;
}
if ((result !== undefined || (isSrcArr && !(key in object))) &&
(isCommon || (result === result ? (result !== value) : (value === value)))) {
object[key] = result;
}
}
});
return object;
}
/**
* A specialized version of `baseMerge` for arrays and objects which performs
* deep merges and tracks traversed objects enabling objects with circular
@@ -3097,7 +3051,7 @@
}
/**
* Creates a `_.assign`, `_.defaults`, or `_.merge` function.
* Creates a `_.assign` or `_.merge` function.
*
* @private
* @param {Function} assigner The function to assign values.
@@ -3206,8 +3160,7 @@
}
/**
* Creates a function that produces compound words out of the words in a
* given string.
* Creates a `_.camelCase`, `_.kebabCase`, `_.snakeCase`, or `_.startCase` function.
*
* @private
* @param {Function} callback The function to combine each word.
@@ -3260,57 +3213,6 @@
};
}
/**
* Creates a `_.curry` or `_.curryRight` function.
*
* @private
* @param {boolean} flag The curry bit flag.
* @returns {Function} Returns the new curry function.
*/
function createCurry(flag) {
function curryFunc(func, arity, guard) {
if (guard && isIterateeCall(func, arity, guard)) {
arity = undefined;
}
var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curryFunc.placeholder;
return result;
}
return curryFunc;
}
/**
* Creates a `_.defaults` or `_.defaultsDeep` function.
*
* @private
* @param {Function} assigner The function to assign values.
* @param {Function} customizer The function to customize assigned values.
* @returns {Function} Returns the new defaults function.
*/
function createDefaults(assigner, customizer) {
return restParam(function(args) {
var object = args[0];
if (object == null) {
return object;
}
args.push(customizer);
return assigner.apply(undefined, args);
});
}
/**
* Creates a `_.max` or `_.min` function.
*
* @private
* @param {Function} extremumBy The function used to get the extremum value.
* @returns {Function} Returns the new extremum function.
*/
function createExtremum(extremumBy) {
return function(collection) {
return extremumBy(collection, identity);
};
}
/**
* Creates a `_.maxBy` or `_.minBy` function.
*
@@ -3339,56 +3241,6 @@
};
}
/**
* Creates a `_.find` or `_.findLast` function.
*
* @private
* @param {Function} eachFunc The function to iterate over a collection.
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new find function.
*/
function createFind(eachFunc, fromRight) {
return function(collection, predicate) {
predicate = getIteratee(predicate);
if (isArray(collection)) {
var index = baseFindIndex(collection, predicate, fromRight);
return index > -1 ? collection[index] : undefined;
}
return baseFind(collection, predicate, eachFunc);
};
}
/**
* Creates a `_.findIndex` or `_.findLastIndex` function.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new find function.
*/
function createFindIndex(fromRight) {
return function(array, predicate) {
if (!(array && array.length)) {
return -1;
}
predicate = getIteratee(predicate);
return baseFindIndex(array, predicate, fromRight);
};
}
/**
* Creates a `_.findKey` or `_.findLastKey` function.
*
* @private
* @param {Function} objectFunc The function to iterate over an object.
* @returns {Function} Returns the new find function.
*/
function createFindKey(objectFunc) {
return function(object, predicate) {
predicate = getIteratee(predicate);
return baseFind(object, predicate, objectFunc, true);
};
}
/**
* Creates a `_.flow` or `_.flowRight` function.
*
@@ -3444,116 +3296,6 @@
};
}
/**
* Creates a function for `_.forEach` or `_.forEachRight`.
*
* @private
* @param {Function} arrayFunc The function to iterate over an array.
* @param {Function} eachFunc The function to iterate over a collection.
* @returns {Function} Returns the new each function.
*/
function createForEach(arrayFunc, eachFunc) {
return function(collection, iteratee) {
return (typeof iteratee == 'function' && isArray(collection))
? arrayFunc(collection, iteratee)
: eachFunc(collection, toFunction(iteratee));
};
}
/**
* Creates a function for `_.forIn` or `_.forInRight`.
*
* @private
* @param {Function} objectFunc The function to iterate over an object.
* @returns {Function} Returns the new each function.
*/
function createForIn(objectFunc) {
return function(object, iteratee) {
return objectFunc(object, toFunction(iteratee), keysIn);
};
}
/**
* Creates a function for `_.forOwn` or `_.forOwnRight`.
*
* @private
* @param {Function} objectFunc The function to iterate over an object.
* @returns {Function} Returns the new each function.
*/
function createForOwn(objectFunc) {
return function(object, iteratee) {
return objectFunc(object, toFunction(iteratee));
};
}
/**
* Creates a function for `_.mapKeys` or `_.mapValues`.
*
* @private
* @param {boolean} [isMapKeys] Specify mapping keys instead of values.
* @returns {Function} Returns the new map function.
*/
function createObjectMapper(isMapKeys) {
return function(object, iteratee) {
var result = {};
iteratee = getIteratee(iteratee);
baseForOwn(object, function(value, key, object) {
var mapped = iteratee(value, key, object);
key = isMapKeys ? mapped : key;
value = isMapKeys ? value : mapped;
result[key] = value;
});
return result;
};
}
/**
* Creates a function for `_.padLeft` or `_.padRight`.
*
* @private
* @param {boolean} [fromRight] Specify padding from the right.
* @returns {Function} Returns the new pad function.
*/
function createPadDir(fromRight) {
return function(string, length, chars) {
string = baseToString(string);
return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string);
};
}
/**
* Creates a `_.partial` or `_.partialRight` function.
*
* @private
* @param {boolean} flag The partial bit flag.
* @returns {Function} Returns the new partial function.
*/
function createPartial(flag) {
var partialFunc = restParam(function(func, partials) {
var holders = replaceHolders(partials, partialFunc.placeholder);
return createWrapper(func, flag, undefined, partials, holders);
});
return partialFunc;
}
/**
* Creates a function for `_.reduce` or `_.reduceRight`.
*
* @private
* @param {Function} arrayFunc The function to iterate over an array.
* @param {Function} eachFunc The function to iterate over a collection.
* @returns {Function} Returns the new each function.
*/
function createReduce(arrayFunc, eachFunc) {
return function(collection, iteratee, accumulator) {
var initFromArray = arguments.length < 3;
return (typeof iteratee == 'function' && isArray(collection))
? arrayFunc(collection, iteratee, accumulator, initFromArray)
: baseReduce(collection, getIteratee(iteratee), accumulator, initFromArray, eachFunc);
};
}
/**
* Creates a function that wraps `func` and invokes it with optional `this`
* binding of, partial application, and currying.
@@ -3720,22 +3462,6 @@
};
}
/**
* Creates a `_.sortedIndex` or `_.sortedLastIndex` function.
*
* @private
* @param {boolean} [retHighest] Specify returning the highest qualified index.
* @returns {Function} Returns the new index function.
*/
function createSortedIndex(retHighest) {
return function(array, value, iteratee) {
var toIteratee = getIteratee();
return (iteratee == null && toIteratee === baseIteratee)
? binaryIndex(array, value, retHighest)
: binaryIndexBy(array, value, toIteratee(iteratee), retHighest);
};
}
/**
* Creates a function that either curries or invokes `func` with optional
* `this` binding and partially applied arguments.
@@ -4899,7 +4625,11 @@
* _.findIndex(users, 'active');
* // => 2
*/
var findIndex = createFindIndex();
function findIndex(array, predicate) {
return (array && array.length)
? baseFindIndex(array, getIteratee(predicate))
: -1;
}
/**
* This method is like `_.findIndex` except that it iterates over elements
@@ -4934,7 +4664,11 @@
* _.findLastIndex(users, 'active');
* // => 0
*/
var findLastIndex = createFindIndex(true);
function findLastIndex(array, predicate) {
return (array && array.length)
? baseFindIndex(array, getIteratee(predicate), true)
: -1;
}
/**
* Gets the first element of `array`.
@@ -5386,7 +5120,12 @@
* _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
* // => 1
*/
var sortedIndex = createSortedIndex();
function sortedIndex(array, value, iteratee) {
var toIteratee = getIteratee();
return (iteratee == null && toIteratee === baseIteratee)
? binaryIndex(array, value)
: binaryIndexBy(array, value, toIteratee(iteratee));
}
/**
* This method is like `_.sortedIndex` except that it returns the highest
@@ -5405,7 +5144,12 @@
* _.sortedLastIndex([4, 4, 5, 5], 5);
* // => 4
*/
var sortedLastIndex = createSortedIndex(true);
function sortedLastIndex(array, value, iteratee) {
var toIteratee = getIteratee();
return (iteratee == null && toIteratee === baseIteratee)
? binaryIndex(array, value, true)
: binaryIndexBy(array, value, toIteratee(iteratee), true);
}
/**
* Creates a slice of `array` with `n` elements taken from the beginning.
@@ -6302,7 +6046,14 @@
* resolve( _.find(users, 'active') );
* // => 'barney'
*/
var find = createFind(baseEach);
function find(collection, predicate) {
predicate = getIteratee(predicate);
if (isArray(collection)) {
var index = baseFindIndex(collection, predicate);
return index > -1 ? collection[index] : undefined;
}
return baseFind(collection, predicate, baseEach);
}
/**
* This method is like `_.find` except that it iterates over elements of
@@ -6321,7 +6072,14 @@
* });
* // => 3
*/
var findLast = createFind(baseEachRight, true);
function findLast(collection, predicate) {
predicate = getIteratee(predicate);
if (isArray(collection)) {
var index = baseFindIndex(collection, predicate, true);
return index > -1 ? collection[index] : undefined;
}
return baseFind(collection, predicate, baseEachRight);
}
/**
* Iterates over elements of `collection` invoking `iteratee` for each element.
@@ -6351,7 +6109,11 @@
* });
* // => logs each value-key pair and returns the object (iteration order is not guaranteed)
*/
var forEach = createForEach(arrayEach, baseEach);
function forEach(collection, iteratee) {
return (typeof iteratee == 'function' && isArray(collection))
? arrayEach(collection, iteratee)
: baseEach(collection, toFunction(iteratee));
}
/**
* This method is like `_.forEach` except that it iterates over elements of
@@ -6371,7 +6133,11 @@
* });
* // => logs each value from right to left and returns the array
*/
var forEachRight = createForEach(arrayEachRight, baseEachRight);
function forEachRight(collection, iteratee) {
return (typeof iteratee == 'function' && isArray(collection))
? arrayEachRight(collection, iteratee)
: baseEachRight(collection, toFunction(iteratee));
}
/**
* Creates an object composed of keys generated from the results of running
@@ -6642,7 +6408,12 @@
* }, {});
* // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)
*/
var reduce = createReduce(arrayReduce, baseEach);
function reduce(collection, iteratee, accumulator) {
var initFromArray = arguments.length < 3;
return (typeof iteratee == 'function' && isArray(collection))
? arrayReduce(collection, iteratee, accumulator, initFromArray)
: baseReduce(collection, getIteratee(iteratee), accumulator, initFromArray, baseEach);
}
/**
* This method is like `_.reduce` except that it iterates over elements of
@@ -6665,7 +6436,12 @@
* }, []);
* // => [4, 5, 2, 3, 0, 1]
*/
var reduceRight = createReduce(arrayReduceRight, baseEachRight);
function reduceRight(collection, iteratee, accumulator) {
var initFromArray = arguments.length < 3;
return (typeof iteratee == 'function' && isArray(collection))
? arrayReduceRight(collection, iteratee, accumulator, initFromArray)
: baseReduce(collection, getIteratee(iteratee), accumulator, initFromArray, baseEachRight);
}
/**
* The opposite of `_.filter`; this method returns the elements of `collection`
@@ -7237,7 +7013,14 @@
* curried(1)(_, 3)(2);
* // => [1, 2, 3]
*/
var curry = createCurry(CURRY_FLAG);
function curry(func, arity, guard) {
if (guard && isIterateeCall(func, arity, guard)) {
arity = undefined;
}
var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curry.placeholder;
return result;
}
/**
* This method is like `_.curry` except that arguments are applied to `func`
@@ -7276,7 +7059,14 @@
* curried(3)(1, _)(2);
* // => [1, 2, 3]
*/
var curryRight = createCurry(CURRY_RIGHT_FLAG);
function curryRight(func, arity, guard) {
if (guard && isIterateeCall(func, arity, guard)) {
arity = undefined;
}
var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curryRight.placeholder;
return result;
}
/**
* Creates a debounced function that delays invoking `func` until after `wait`
@@ -7734,7 +7524,10 @@
* greetFred('hi');
* // => 'hi fred'
*/
var partial = createPartial(PARTIAL_FLAG);
var partial = restParam(function(func, partials) {
var holders = replaceHolders(partials, partial.placeholder);
return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
});
/**
* This method is like `_.partial` except that partially applied arguments
@@ -7767,7 +7560,10 @@
* sayHelloTo('fred');
* // => 'hello fred'
*/
var partialRight = createPartial(PARTIAL_RIGHT_FLAG);
var partialRight = restParam(function(func, partials) {
var holders = replaceHolders(partials, partialRight.placeholder);
return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
});
/**
* Creates a function that invokes `func` with arguments arranged according
@@ -8862,7 +8658,39 @@
* });
* // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
*/
var merge = createAssigner(baseMerge);
var merge = createAssigner(function baseMerge(object, source, customizer, stackA, stackB) {
if (!isObject(object)) {
return object;
}
var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
props = isSrcArr ? undefined : keys(source);
arrayEach(props || source, function(srcValue, key) {
if (props) {
key = srcValue;
srcValue = source[key];
}
if (isObjectLike(srcValue)) {
stackA || (stackA = []);
stackB || (stackB = []);
baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
}
else {
var value = object[key],
result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
isCommon = result === undefined;
if (isCommon) {
result = srcValue;
}
if ((result !== undefined || (isSrcArr && !(key in object))) &&
(isCommon || (result === result ? (result !== value) : (value === value)))) {
object[key] = result;
}
}
});
return object;
});
/**
* Assigns own enumerable properties of source object(s) to the destination
@@ -8961,7 +8789,14 @@
* _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
* // => { 'user': 'barney', 'age': 36 }
*/
var defaults = createDefaults(assign, assignDefaults);
var defaults = restParam(function(args) {
var object = args[0];
if (object == null) {
return object;
}
args.push(assignDefaults);
return assign.apply(undefined, args);
});
/**
* This method is like `_.defaults` except that it recursively assigns
@@ -8981,7 +8816,14 @@
* // => { 'user': { 'name': 'barney', 'age': 36 } }
*
*/
var defaultsDeep = createDefaults(merge, mergeDefaults);
var defaultsDeep = restParam(function(args) {
var object = args[0];
if (object == null) {
return object;
}
args.push(mergeDefaults);
return merge.apply(undefined, args);
});
/**
* This method is like `_.find` except that it returns the key of the first
@@ -9016,7 +8858,10 @@
* _.findKey(users, 'active');
* // => 'barney'
*/
var findKey = createFindKey(baseForOwn);
function findKey(object, predicate) {
predicate = getIteratee(predicate);
return baseFind(object, predicate, baseForOwn, true);
}
/**
* This method is like `_.findKey` except that it iterates over elements of
@@ -9051,7 +8896,10 @@
* _.findLastKey(users, 'active');
* // => 'pebbles'
*/
var findLastKey = createFindKey(baseForOwnRight);
function findLastKey(object, predicate) {
predicate = getIteratee(predicate);
return baseFind(object, predicate, baseForOwnRight, true);
}
/**
* Iterates over own and inherited enumerable properties of an object invoking
@@ -9079,7 +8927,9 @@
* });
* // => logs 'a', 'b', and 'c' (iteration order is not guaranteed)
*/
var forIn = createForIn(baseFor);
function forIn(object, iteratee) {
return baseFor(object, toFunction(iteratee), keysIn);
}
/**
* This method is like `_.forIn` except that it iterates over properties of
@@ -9105,7 +8955,9 @@
* });
* // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'
*/
var forInRight = createForIn(baseForRight);
function forInRight(object, iteratee) {
return baseForRight(object, toFunction(iteratee), keysIn);
}
/**
* Iterates over own enumerable properties of an object invoking `iteratee`
@@ -9133,7 +8985,9 @@
* });
* // => logs 'a' and 'b' (iteration order is not guaranteed)
*/
var forOwn = createForOwn(baseForOwn);
function forOwn(object, iteratee) {
return baseForOwn(object, toFunction(iteratee));
}
/**
* This method is like `_.forOwn` except that it iterates over properties of
@@ -9159,7 +9013,10 @@
* });
* // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'
*/
var forOwnRight = createForOwn(baseForOwnRight);
function forOwnRight(object, iteratee) {
return baseForOwnRight(object, toFunction(iteratee));
}
/**
* Creates an array of function property names from all enumerable properties,
@@ -9432,7 +9289,15 @@
* });
* // => { 'a1': 1, 'b2': 2 }
*/
var mapKeys = createObjectMapper(true);
function mapKeys(object, iteratee) {
var result = {};
iteratee = getIteratee(iteratee);
baseForOwn(object, function(value, key, object) {
result[iteratee(value, key, object)] = value;
});
return result;
}
/**
* Creates an object with the same keys as `object` and values generated by
@@ -9459,7 +9324,15 @@
* _.mapValues(users, 'age');
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
*/
var mapValues = createObjectMapper();
function mapValues(object, iteratee) {
var result = {};
iteratee = getIteratee(iteratee);
baseForOwn(object, function(value, key, object) {
result[key] = iteratee(value, key, object);
});
return result;
}
/**
* The opposite of `_.pick`; this method creates an object composed of the
@@ -10103,7 +9976,10 @@
* _.padLeft('abc', 3);
* // => 'abc'
*/
var padLeft = createPadDir();
function padLeft(string, length, chars) {
string = baseToString(string);
return createPadding(string, length, chars) + string;
}
/**
* Pads `string` on the right side if it's shorter than `length`. Padding
@@ -10127,7 +10003,10 @@
* _.padRight('abc', 3);
* // => 'abc'
*/
var padRight = createPadDir(true);
function padRight(string, length, chars) {
string = baseToString(string);
return string + createPadding(string, length, chars);
}
/**
* Converts `string` to an integer of the specified radix. If `radix` is
@@ -11306,6 +11185,27 @@
*/
var floor = createRound('floor');
/**
* Gets the maximum value of `collection`. If `collection` is empty or falsey
* `-Infinity` is returned.
*
* @static
* @memberOf _
* @category Math
* @param {Array|Object|string} collection The collection to iterate over.
* @returns {*} Returns the maximum value.
* @example
*
* _.max([4, 2, 8, 6]);
* // => 8
*
* _.max([]);
* // => -Infinity
*/
function max(collection) {
return maxBy(collection, identity);
}
/**
* This method is like `_.max` except that it accepts an iteratee which is
* invoked for each value in `collection` to generate the criterion by which
@@ -11335,23 +11235,25 @@
var maxBy = createExtremumBy(gt, NEGATIVE_INFINITY);
/**
* Gets the maximum value of `collection`. If `collection` is empty or falsey
* `-Infinity` is returned.
* Gets the minimum value of `collection`. If `collection` is empty or falsey
* `Infinity` is returned.
*
* @static
* @memberOf _
* @category Math
* @param {Array|Object|string} collection The collection to iterate over.
* @returns {*} Returns the maximum value.
* @returns {*} Returns the minimum value.
* @example
*
* _.max([4, 2, 8, 6]);
* // => 8
* _.min([4, 2, 8, 6]);
* // => 2
*
* _.max([]);
* // => -Infinity
* _.min([]);
* // => Infinity
*/
var max = createExtremum(maxBy);
function min(collection) {
return minBy(collection, identity);
}
/**
* This method is like `_.min` except that it accepts an iteratee which is
@@ -11381,25 +11283,6 @@
*/
var minBy = createExtremumBy(lt, POSITIVE_INFINITY);
/**
* Gets the minimum value of `collection`. If `collection` is empty or falsey
* `Infinity` is returned.
*
* @static
* @memberOf _
* @category Math
* @param {Array|Object|string} collection The collection to iterate over.
* @returns {*} Returns the minimum value.
* @example
*
* _.min([4, 2, 8, 6]);
* // => 2
*
* _.min([]);
* // => Infinity
*/
var min = createExtremum(minBy);
/**
* Calculates `n` rounded to `precision`.
*