diff --git a/lodash.src.js b/lodash.src.js index 0db5e8ab8..a42dc037b 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -2185,20 +2185,7 @@ * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ - function baseFor(object, iteratee, keysFunc) { - var index = -1, - iterable = toObject(object), - props = keysFunc(object), - length = props.length; - - while (++index < length) { - var key = props[index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - } + var baseFor = createBaseFor(); /** * This function is like `baseFor` except that it iterates over properties @@ -2210,19 +2197,7 @@ * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ - function baseForRight(object, iteratee, keysFunc) { - var iterable = toObject(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[length]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - } + var baseForRight = createBaseFor(true); /** * The base implementation of `_.forIn` without support for callback @@ -3151,6 +3126,23 @@ }; } + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + /** * Creates a function that wraps `func` and invokes it with the `this` * binding of `thisArg`. @@ -3257,6 +3249,18 @@ }; } + function createCurry(curryFlag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = null; + } + var result = createWrapper(func, curryFlag, null, null, null, null, null, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } + /** * Creates a function that gets the extremum value of a collection. * @@ -3290,6 +3294,84 @@ }; } + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + } + } + + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } + + function createFindKey(eachFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, eachFunc, true); + }; + } + + function createForOwn(eachFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return eachFunc(object, iteratee); + }; + } + + function createForEach(arrayFunc, baseFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) + ? arrayFunc(collection, iteratee) + : baseFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } + + function createForIn(baseFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return baseFunc(object, iteratee, keysIn); + }; + } + + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return string && ((fromRight ? string : '') + createPad(string, length, chars) + (fromRight ? '' : string)); + }; + } + + function createPartial(partialFlag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, partialFlag, null, partials, holders); + }); + return partialFunc; + } + + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; + } + /** * Creates a function that wraps `func` and invokes it with optional `this` * binding of, partial application, and currying. @@ -4583,13 +4665,7 @@ * _.findIndex(users, 'active'); * // => 2 */ - function findIndex(array, predicate, thisArg) { - if (!(array && array.length)) { - return -1; - } - predicate = getCallback(predicate, thisArg, 3); - return baseFindIndex(array, predicate); - } + var findIndex = createFindIndex(); /** * This method is like `_.findIndex` except that it iterates over elements @@ -4639,13 +4715,7 @@ * _.findLastIndex(users, 'active'); * // => 0 */ - function findLastIndex(array, predicate, thisArg) { - if (!(array && array.length)) { - return -1; - } - predicate = getCallback(predicate, thisArg, 3); - return baseFindIndex(array, predicate, true); - } + var findLastIndex = createFindIndex(true); /** * Gets the first element of `array`. @@ -6098,14 +6168,7 @@ * _.result(_.find(users, 'active'), 'user'); * // => 'barney' */ - function find(collection, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - if (isArray(collection)) { - var index = baseFindIndex(collection, predicate); - return index > -1 ? collection[index] : undefined; - } - return baseFind(collection, predicate, baseEach); - } + var find = createFind(baseEach); /** * This method is like `_.find` except that it iterates over elements of @@ -6126,10 +6189,7 @@ * }); * // => 3 */ - function findLast(collection, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(collection, predicate, baseEachRight); - } + var findLast = createFind(baseEachRight, true); /** * Performs a deep comparison between each element in `collection` and the @@ -6194,11 +6254,7 @@ * }); * // => logs each value-key pair and returns the object (iteration order is not guaranteed) */ - function forEach(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayEach(collection, iteratee) - : baseEach(collection, bindCallback(iteratee, thisArg, 3)); - } + var forEach = createForEach(arrayEach, baseEach); /** * This method is like `_.forEach` except that it iterates over elements of @@ -6219,11 +6275,7 @@ * }).join(','); * // => logs each value from right to left and returns the array */ - function forEachRight(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayEachRight(collection, iteratee) - : baseEachRight(collection, bindCallback(iteratee, thisArg, 3)); - } + var forEachRight = createForEach(arrayEachRight, baseEachRight); /** * Creates an object composed of keys generated from the results of running @@ -6600,12 +6652,7 @@ * }, {}); * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) */ - function reduce(collection, iteratee, accumulator, thisArg) { - var initFromArray = arguments.length < 3; - return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayReduce(collection, iteratee, accumulator, initFromArray) - : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, baseEach); - } + var reduce = createReduce(arrayReduce, baseEach); /** * This method is like `_.reduce` except that it iterates over elements of @@ -6629,12 +6676,7 @@ * }, []); * // => [4, 5, 2, 3, 0, 1] */ - function reduceRight(collection, iteratee, accumulator, thisArg) { - var initFromArray = arguments.length < 3; - return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayReduceRight(collection, iteratee, accumulator, initFromArray) - : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, baseEachRight); - } + var reduceRight = createReduce(arrayReduceRight, baseEachRight); /** * The opposite of `_.filter`; this method returns the elements of `collection` @@ -7276,7 +7318,7 @@ * bound('hi'); * // => 'hiya fred!' */ - var bindKey = restParam(function(object, key, partials) { + var bindKey = restParam(function(object, key, partials) { var bitmask = BIND_FLAG | BIND_KEY_FLAG; if (partials.length) { var holders = replaceHolders(partials, bindKey.placeholder); @@ -7325,14 +7367,7 @@ * curried(1)(_, 3)(2); * // => [1, 2, 3] */ - function curry(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = null; - } - var result = createWrapper(func, CURRY_FLAG, null, null, null, null, null, arity); - result.placeholder = curry.placeholder; - return result; - } + var curry = createCurry(CURRY_FLAG); /** * This method is like `_.curry` except that arguments are applied to `func` @@ -7371,14 +7406,7 @@ * curried(3)(1, _)(2); * // => [1, 2, 3] */ - function curryRight(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = null; - } - var result = createWrapper(func, CURRY_RIGHT_FLAG, null, null, null, null, null, arity); - result.placeholder = curryRight.placeholder; - return result; - } + var curryRight = createCurry(CURRY_RIGHT_FLAG); /** * Creates a function that delays invoking `func` until after `wait` milliseconds @@ -7797,10 +7825,7 @@ * greetFred('hi'); * // => 'hi fred' */ - var partial = restParam(function(func, partials) { - var holders = replaceHolders(partials, partial.placeholder); - return createWrapper(func, PARTIAL_FLAG, null, partials, holders); - }); + var partial = createPartial(PARTIAL_FLAG); /** * This method is like `_.partial` except that partially applied arguments @@ -7833,10 +7858,7 @@ * sayHelloTo('fred'); * // => 'hello fred' */ - var partialRight = restParam(function(func, partials) { - var holders = replaceHolders(partials, partialRight.placeholder); - return createWrapper(func, PARTIAL_RIGHT_FLAG, null, partials, holders); - }); + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); /** * Creates a function that invokes `func` with arguments arranged according @@ -8970,10 +8992,7 @@ * _.findKey(users, 'active'); * // => 'barney' */ - function findKey(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, baseForOwn, true); - } + var findKey = createFindKey(baseForOwn); /** * This method is like `_.findKey` except that it iterates over elements of @@ -9023,10 +9042,7 @@ * _.findLastKey(users, 'active'); * // => 'pebbles' */ - function findLastKey(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, baseForOwnRight, true); - } + var findLastKey = createFindKey(baseForOwnRight); /** * Iterates over own and inherited enumerable properties of an object invoking @@ -9055,12 +9071,7 @@ * }); * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) */ - function forIn(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return baseFor(object, iteratee, keysIn); - } + var forIn = createForIn(baseFor); /** * This method is like `_.forIn` except that it iterates over properties of @@ -9087,10 +9098,7 @@ * }); * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' */ - function forInRight(object, iteratee, thisArg) { - iteratee = bindCallback(iteratee, thisArg, 3); - return baseForRight(object, iteratee, keysIn); - } + var forInRight = createForIn(baseForRight); /** * Iterates over own enumerable properties of an object invoking `iteratee` @@ -9119,12 +9127,7 @@ * }); * // => logs 'a' and 'b' (iteration order is not guaranteed) */ - function forOwn(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return baseForOwn(object, iteratee); - } + var forOwn = createForOwn(baseForOwn); /** * This method is like `_.forOwn` except that it iterates over properties of @@ -9151,10 +9154,7 @@ * }); * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' */ - function forOwnRight(object, iteratee, thisArg) { - iteratee = bindCallback(iteratee, thisArg, 3); - return baseForRight(object, iteratee, keys); - } + var forOwnRight = createForOwn(baseForOwnRight); /** * Creates an array of function property names from all enumerable properties, @@ -10068,10 +10068,7 @@ * _.padLeft('abc', 3); * // => 'abc' */ - function padLeft(string, length, chars) { - string = baseToString(string); - return string && (createPad(string, length, chars) + string); - } + var padLeft = createPadDir(); /** * Pads `string` on the right side if it is shorter then the given padding @@ -10096,10 +10093,7 @@ * _.padRight('abc', 3); * // => 'abc' */ - function padRight(string, length, chars) { - string = baseToString(string); - return string && (string + createPad(string, length, chars)); - } + var padRight = createPadDir(true); /** * Converts `string` to an integer of the specified radix. If `radix` is