diff --git a/dist/lodash.compat.js b/dist/lodash.compat.js index 30d2abe71..ccddd5914 100644 --- a/dist/lodash.compat.js +++ b/dist/lodash.compat.js @@ -16,9 +16,10 @@ var BIND_FLAG = 1, BIND_KEY_FLAG = 2, CURRY_FLAG = 4, - CURRY_BOUND_FLAG = 8, - PARTIAL_FLAG = 16, - PARTIAL_RIGHT_FLAG = 32; + CURRY_RIGHT_FLAG = 8, + CURRY_BOUND_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64; /** Used as the semantic version number */ var version = '3.0.0-pre'; @@ -104,7 +105,7 @@ /** Used to assign default `context` object properties */ var contextProps = [ - 'Array', 'ArrayBuffer', 'Boolean', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', 'isFinite', 'isNaN', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', 'Uint8ClampedArray', @@ -385,11 +386,7 @@ var index = -1, length = string.length; - while (++index < length) { - if (chars.indexOf(string.charAt(index)) < 0) { - break; - } - } + while (++index < length && chars.indexOf(string.charAt(index)) > -1) { } return index; } @@ -404,11 +401,8 @@ */ function charsRightIndex(string, chars) { var index = string.length; - while (index--) { - if (chars.indexOf(string.charAt(index)) < 0) { - break; - } - } + + while (index-- && chars.indexOf(string.charAt(index)) > -1) { } return index; } @@ -557,6 +551,7 @@ */ function trimmedRightIndex(string) { var index = string.length; + while (index--) { var c = string.charCodeAt(index); if (!((c <= 160 && (c >= 9 && c <= 13) || c == 32 || c == 160) || c == 5760 || c == 6158 || @@ -585,7 +580,7 @@ * * @static * @memberOf _ - * @category Utilities + * @category Utility * @param {Object} [context=root] The context object. * @returns {Function} Returns a new `lodash` function. * @example @@ -617,6 +612,7 @@ Error = context.Error, Function = context.Function, Math = context.Math, + Number = context.Number, Object = context.Object, RegExp = context.RegExp, String = context.String, @@ -686,11 +682,11 @@ nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, nativeIsFinite = context.isFinite, - nativeIsNaN = context.isNaN, nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, nativeMax = Math.max, nativeMin = Math.min, nativeNow = isNative(nativeNow = Date.now) && nativeNow, + nativeNumIsFinite = isNative(nativeNumIsFinite = Number.isFinite) && nativeNumIsFinite, nativeParseInt = context.parseInt, nativeRandom = Math.random; @@ -736,38 +732,42 @@ * implicitly or explicitly included in the build. * * The chainable wrapper functions are: - * `after`, `assign`, `at`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `constant`, `countBy`, `create`, `createCallback`, - * `curry`, `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, - * `flatten`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, - * `forOwnRight`, `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, - * `invert`, `invoke`, `keys`, `map`, `mapValues`, `matches`, `max`, `memoize`, - * `merge`, `min`, `mixin`, `noop`, `object`, `omit`, `once`, `pairs`, `partial`, - * `partialRight`, `pick`, `pluck`, `property`, `pull`, `pullAt`, `push`, - * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, - * `xor`, and `zip` + * `after`, `assign`, `at`, `bind`, `bindAll`, `bindKey`, `callback`, `chain`, + * `chunk`, `compact`, `compose`, `concat`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defer`, `delay`, `difference`, `drop`, + * `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `flatten`, `forEach`, + * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, + * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, + * `keysIn`, `map`, `mapValues`, `matches`, `memoize`, `merge`, `mixin`, + * `negate`, `noop`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `pluck`, `property`, `pull`, `pullAt`, `push`, `range`, + * `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, + * `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`, + * `unzip`, `values`, `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, + * and `zipObject` * * The non-chainable wrapper functions are: - * `capitalize`, `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, - * `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, + * `camelCase`, `capitalize`, `clone`, `cloneDeep`, `contains`, `endsWith`, + * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, + * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, - * `isElement`, `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, - * `isNull`, `isNumber`, `isObject`, `isPlainObject`, `isRegExp`, `isString`, - * `isUndefined`, `join`, `lastIndexOf`, `noConflict`, `now`, `parseInt`, - * `pop`, `random`, `reduce`, `reduceRight`, `result`, `shift`, `size`, `some`, - * `sortedIndex`, `runInContext`, `template`, `trim`, `trimLeft`, `trimRight`, - * `unescape`, `uniqueId`, and `value` + * `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, `isFunction`, + * `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, `isRegExp`, + * `isString`, `isUndefined`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `max`, `min`, `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, + * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, + * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `startsWith`, `template`, + * `trim`, `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, and `value` * - * The wrapper functions `first`, `last`, and `sample` return wrapped values - * when `n` is provided, otherwise they return unwrapped values. + * The wrapper function `sample` will return a wrapped value when `n` is + * provided, otherwise it will return an unwrapped value. * * Explicit chaining can be enabled by using the `_.chain` method. * * @name _ * @constructor - * @category Chaining + * @category Chain * @param {*} value The value to wrap in a `lodash` instance. * @returns {Object} Returns a `lodash` instance. * @example @@ -788,10 +788,15 @@ * // => true */ function lodash(value) { - // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor - return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) - ? value - : new lodashWrapper(value); + if (value && typeof value == 'object') { + if (value instanceof lodashWrapper) { + return value; + } + if (!isArray(value) && hasOwnProperty.call(value, '__wrapped__')) { + value = value.__wrapped__; + } + } + return new lodashWrapper(value); } /** @@ -799,15 +804,13 @@ * * @private * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} [chainAll=false] A flag to enable chaining for all methods. + * @param {boolean} [chainAll=false] Enable chaining for all methods. * @returns {Object} Returns a `lodash` instance. */ function lodashWrapper(value, chainAll) { this.__chain__ = !!chainAll; this.__wrapped__ = value; } - // ensure `new lodashWrapper` is an instance of `lodash` - lodashWrapper.prototype = lodash.prototype; /** * An object used to flag environments features. @@ -1050,15 +1053,15 @@ * * @private * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @returns {Array} Returns `array`. */ - function arrayEach(array, callback) { + function arrayEach(array, iterator) { var index = -1, length = array ? array.length : 0; while (++index < length) { - if (callback(array[index], index, array) === false) { + if (iterator(array[index], index, array) === false) { break; } } @@ -1071,39 +1074,132 @@ * * @private * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @returns {Array} Returns `array`. */ - function arrayEachRight(array, callback) { + function arrayEachRight(array, iterator) { var length = array ? array.length : 0; + while (length--) { - if (callback(array[length], length, array) === false) { + if (iterator(array[length], length, array) === false) { break; } } return array; } + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function called per iteration. + * @returns {Array} Returns `true` if all elements passed the predicate check, + * else `false` + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + /** * A specialized version of `_.map` for arrays without support for callback * shorthands or `this` binding. * * @private * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @returns {Array} Returns the new mapped array. */ - function arrayMap(array, callback) { + function arrayMap(array, iterator) { var index = -1, length = array ? array.length >>> 0 : 0, result = Array(length); while (++index < length) { - result[index] = callback(array[index], index, array); + result[index] = iterator(array[index], index, array); } return result; } + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function called per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + } + } + return result; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iterator The function called per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray=false] Specify using the first element of + * `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iterator, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iterator(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function called per iteration. + * @returns {boolean} Returns `true` if any element passed the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + /** * Used by `_.defaults` to customize its `_.assign` use. * @@ -1142,62 +1238,77 @@ * @private * @param {Object} object The destination object. * @param {Object} source The source object. - * @param {Function} [callback] The function to customize assigning values. + * @param {Function} [customizer] The function to customize assigning values. * @returns {Object} Returns the destination object. */ - function baseAssign(object, source, callback) { + function baseAssign(object, source, customizer) { var index = -1, props = keys(source), length = props.length; while (++index < length) { var key = props[index]; - object[key] = callback ? callback(object[key], source[key], key, object, source) : source[key]; + object[key] = customizer ? customizer(object[key], source[key], key, object, source) : source[key]; } return object; } /** - * The base implementation of `_.bind` that creates the bound function and - * sets its metadata. + * The base implementation of `_.callback` without support for creating + * "_.pluck" and "_.where" style callbacks. * * @private - * @param {Array} data The metadata array. - * @returns {Function} Returns the new bound function. + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns the new function. */ - function baseBind(data) { - var func = data[0], - thisArg = data[3], - partialArgs = data[4], - partialHolders = data[6]; - - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object use disqualifying optimizations by - // converting it to an array before passing it to `composeArgs` - var length = arguments.length, - args = Array(length); - - while (length--) { - args[length] = arguments[length]; - } - args = composeArgs(partialArgs, partialHolders, args); - } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - - return isObject(result) ? result : thisBinding; - } - return func.apply(thisArg, args || arguments); + function baseCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; } - setData(bound, data); - return bound; + if (typeof thisArg == 'undefined') { + return func; + } + var data = func[expando]; + if (typeof data == 'undefined') { + if (support.funcNames) { + data = !func.name; + } + data = data || !support.funcDecomp; + if (!data) { + var source = fnToString.call(func); + if (!support.funcNames) { + data = !reFuncName.test(source); + } + if (!data) { + // checks if `func` references the `this` keyword and stores the result + data = reThis.test(source) || isNative(func); + setData(func, data); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (data === false || (data !== true && data[1] & BIND_FLAG)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; } /** @@ -1207,13 +1318,13 @@ * @private * @param {*} value The value to clone. * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. + * @param {Function} [customizer] The function to customize cloning values. * @param {Array} [stackA=[]] Tracks traversed source objects. * @param {Array} [stackB=[]] Associates clones with source counterparts. * @returns {*} Returns the cloned value. */ - function baseClone(value, isDeep, callback, stackA, stackB) { - var result = callback ? callback(value) : undefined; + function baseClone(value, isDeep, customizer, stackA, stackB) { + var result = customizer ? customizer(value) : undefined; if (typeof result != 'undefined') { return result; } @@ -1296,7 +1407,7 @@ // recursively populate clone (susceptible to call stack limits) (isArr ? arrayEach : baseForOwn)(value, function(valValue, key) { - var valClone = callback ? callback(valValue, key) : undefined; + var valClone = customizer ? customizer(valValue, key) : undefined; result[key] = typeof valClone == 'undefined' ? baseClone(valValue, isDeep, null, stackA, stackB) : valClone; @@ -1332,63 +1443,7 @@ } /** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" and "_.where" style callbacks. - * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns the new function. - */ - function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - if (typeof thisArg == 'undefined') { - return func; - } - var data = func[expando]; - if (typeof data == 'undefined') { - if (support.funcNames) { - data = !func.name; - } - data = data || !support.funcDecomp; - if (!data) { - var source = fnToString.call(func); - if (!support.funcNames) { - data = !reFuncName.test(source); - } - if (!data) { - // checks if `func` references the `this` keyword and stores the result - data = reThis.test(source) || isNative(func); - setData(func, data); - } - } - } - // exit early if there are no `this` references or `func` is bound - if (data === false || (data !== true && data[1] & BIND_FLAG)) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - case 5: return function(value, other, key, object, source) { - return func.call(thisArg, value, other, key, object, source); - }; - } - return bind(func, thisArg); - } - - /** - * The base implementation of `createWrapper` that creates the wrapper and + * The base implementation of `createWrapper` which creates the wrapper and * sets its metadata. * * @private @@ -1396,22 +1451,31 @@ * @returns {Function} Returns the new function. */ function baseCreateWrapper(data) { + var bitmask = data[1]; + if (bitmask == BIND_FLAG) { + return setData(createBindWrapper(data), data); + } + var partialHolders = data[6]; + if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !partialHolders.length) { + return setData(createPartialWrapper(data), data); + } var func = data[0], - bitmask = data[1], arity = data[2], thisArg = data[3], partialArgs = data[4], partialRightArgs = data[5], - partialHolders = data[6], partialRightHolders = data[7]; var isBind = bitmask & BIND_FLAG, isBindKey = bitmask & BIND_KEY_FLAG, isCurry = bitmask & CURRY_FLAG, - isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG; + + var Ctor = !isBindKey && createCtorWrapper(func), key = func; - function bound() { + var wrapper = function() { var length = arguments.length, index = length, args = Array(length); @@ -1425,37 +1489,52 @@ if (partialRightArgs) { args = composeArgsRight(partialRightArgs, partialRightHolders, args); } - if (isCurry) { + if (isCurry || isCurryRight) { var newPartialHolders = getHolders(args); length -= newPartialHolders.length; if (length < arity) { - bitmask |= PARTIAL_FLAG; - bitmask &= ~PARTIAL_RIGHT_FLAG + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + if (!isCurryBound) { bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); } - var newArity = nativeMax(arity - length, 0); - return baseCreateWrapper([func, bitmask, newArity, thisArg, args, null, newPartialHolders]); + var newData = [func, bitmask, nativeMax(arity - length, 0), thisArg]; + newData[isCurry ? 4 : 5] = args; + newData[isCurry ? 6 : 7] = newPartialHolders; + return baseCreateWrapper(newData); } } var thisBinding = isBind ? thisArg : this; if (isBindKey) { func = thisBinding[key]; } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - setData(bound, data); - return bound; + return (this instanceof wrapper ? (Ctor || createCtorWrapper(func)) : func).apply(thisBinding, args); + }; + + return setData(wrapper, data); } /** - * The base implementation of `_.difference` that accepts a single array + * The base implementation of `_.curry` and `_.curryRight` which handles + * resolving the default arity of `func`. + * + * @private + * @param {Function} func The function to curry. + * @param {number} bitmask The bitmask of flags to compose. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + */ + function baseCurry(func, bitmask, arity) { + if (typeof arity != 'number') { + arity = +arity || (func ? func.length : 0); + } + return createWrapper(func, bitmask, arity); + } + + /** + * The base implementation of `_.difference` which accepts a single array * of values to exclude. * * @private @@ -1506,10 +1585,10 @@ * * @private * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @returns {Array|Object|string} Returns `collection`. */ - function baseEach(collection, callback) { + function baseEach(collection, iterator) { var index = -1, iterable = collection, length = collection ? collection.length : 0; @@ -1519,12 +1598,12 @@ iterable = iterable.split(''); } while (++index < length) { - if (callback(iterable[index], index, collection) === false) { + if (iterator(iterable[index], index, collection) === false) { break; } } } else { - baseForOwn(collection, callback); + baseForOwn(collection, iterator); } return collection; } @@ -1535,10 +1614,10 @@ * * @private * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @returns {Array|Object|string} Returns `collection`. */ - function baseEachRight(collection, callback) { + function baseEachRight(collection, iterator) { var iterable = collection, length = collection ? collection.length : 0; @@ -1547,16 +1626,56 @@ iterable = iterable.split(''); } while (length--) { - if (callback(iterable[length], length, collection) === false) { + if (iterator(iterable[length], length, collection) === false) { break; } } } else { - baseForOwnRight(collection, callback); + baseForOwnRight(collection, iterator); } return collection; } + /** + * The base implementation of `_.every` without support for callback shorthands + * or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function called per iteration. + * @returns {Array} Returns `true` if all elements passed the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of `_.filter` without support for callback shorthands + * or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function called per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + /** * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, * without support for callback shorthands and `this` binding, which iterates @@ -1566,8 +1685,8 @@ * @param {Array|Object|string} collection The collection to search. * @param {Function} predicate The function called per iteration. * @param {Function} eachFunc The function to iterate over the collection. - * @param {boolean} [retKey=false] A flag to indicate returning the key of - * the found element instead of the element itself. + * @param {boolean} [retKey=false] Specify returning the key of the found + * element instead of the element itself. * @returns {*} Returns the found element or its key, else `undefined`. */ function baseFind(collection, predicate, eachFunc, retKey) { @@ -1583,19 +1702,19 @@ } /** - * The base implementation of `_.flatten` without support for callback - * shorthands and `this` binding. + * The base implementation of `_.flatten` with added support for restricting + * flattening and specifying the start index. * * @private * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {boolean} [isDeep=false] Specify a deep flatten. + * @param {boolean} [isStrict=false] Restrict flattening to arrays and `arguments` objects. * @param {number} [fromIndex=0] The index to start from. * @returns {Array} Returns the new flattened array. */ - function baseFlatten(array, isShallow, isStrict, fromIndex) { + function baseFlatten(array, isDeep, isStrict, fromIndex) { var index = (fromIndex || 0) - 1, - length = array ? array.length : 0, + length = array.length, resIndex = 0, result = []; @@ -1605,8 +1724,8 @@ if (value && typeof value == 'object' && typeof value.length == 'number' && (isArray(value) || isArguments(value))) { // recursively flatten arrays (susceptible to call stack limits) - if (!isShallow) { - value = baseFlatten(value, isShallow, isStrict); + if (isDeep) { + value = baseFlatten(value, isDeep, isStrict); } var valIndex = -1, valLength = value.length; @@ -1624,24 +1743,24 @@ /** * The base implementation of `baseForIn` and `baseForOwn` which iterates - * over `object` properties returned by `keysFunc` executing the callback - * for each property. Callbacks may exit iteration early by explicitly + * over `object` properties returned by `keysFunc` executing `iterator` for + * each property. Iterator functions may exit iteration early by explicitly * returning `false`. * * @private * @param {Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ - function baseFor(object, callback, keysFunc) { + function baseFor(object, iterator, keysFunc) { var index = -1, props = keysFunc(object), length = props.length; while (++index < length) { var key = props[index]; - if (callback(object[key], key, object) === false) { + if (iterator(object[key], key, object) === false) { break; } } @@ -1654,17 +1773,17 @@ * * @private * @param {Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ - function baseForRight(object, callback, keysFunc) { + function baseForRight(object, iterator, keysFunc) { var props = keysFunc(object), length = props.length; while (length--) { var key = props[length]; - if (callback(object[key], key, object) === false) { + if (iterator(object[key], key, object) === false) { break; } } @@ -1677,11 +1796,11 @@ * * @private * @param {Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @returns {Object} Returns `object`. */ - function baseForIn(object, callback) { - return baseFor(object, callback, keysIn); + function baseForIn(object, iterator) { + return baseFor(object, iterator, keysIn); } /** @@ -1690,11 +1809,11 @@ * * @private * @param {Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @returns {Object} Returns `object`. */ - function baseForOwn(object, callback) { - return baseFor(object, callback, keys); + function baseForOwn(object, iterator) { + return baseFor(object, iterator, keys); } /** @@ -1703,16 +1822,16 @@ * * @private * @param {Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. + * @param {Function} iterator The function called per iteration. * @returns {Object} Returns `object`. */ - function baseForOwnRight(object, callback) { - return baseForRight(object, callback, keys); + function baseForOwnRight(object, iterator) { + return baseForRight(object, iterator, keys); } /** - * The base implementation of `_.functions` which creates a sorted array of - * function property names from those returned by `keysFunc`. + * The base implementation of `_.functions` which creates an array of function + * property names from those returned by `keysFunc`. * * @private * @param {Object} object The object to inspect. @@ -1731,7 +1850,7 @@ result.push(key); } } - return result.sort(); + return result; } /** @@ -1741,14 +1860,14 @@ * @private * @param {*} value The value to compare to `other`. * @param {*} other The value to compare to `value`. - * @param {Function} [callback] The function to customize comparing values. - * @param {boolean} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isWhere=false] Specify performing partial comparisons. * @param {Array} [stackA=[]] Tracks traversed `value` objects. * @param {Array} [stackB=[]] Tracks traversed `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ - function baseIsEqual(value, other, callback, isWhere, stackA, stackB) { - var result = callback && !stackA ? callback(value, other) : undefined; + function baseIsEqual(value, other, customizer, isWhere, stackA, stackB) { + var result = customizer && !stackA ? customizer(value, other) : undefined; if (typeof result != 'undefined') { return !!result; } @@ -1816,7 +1935,7 @@ othWrapped = hasOwnProperty.call(other, '__wrapped__'); if (valWrapped || othWrapped) { - return baseIsEqual(valWrapped ? value.__wrapped__ : value, othWrapped ? other.__wrapped__ : other, callback, isWhere, stackA, stackB); + return baseIsEqual(valWrapped ? value.__wrapped__ : value, othWrapped ? other.__wrapped__ : other, customizer, isWhere, stackA, stackB); } var hasValCtor = !valIsArg && hasOwnProperty.call(value, 'constructor'), hasOthCtor = !othIsArg && hasOwnProperty.call(other, 'constructor'); @@ -1873,16 +1992,16 @@ if (isWhere) { var othIndex = othLength; while (othIndex--) { - result = baseIsEqual(valValue, other[othIndex], callback, isWhere, stackA, stackB); + result = baseIsEqual(valValue, other[othIndex], customizer, isWhere, stackA, stackB); if (result) { break; } } } else { var othValue = other[index]; - result = callback ? callback(valValue, othValue, index) : undefined; + result = customizer ? customizer(valValue, othValue, index) : undefined; if (typeof result == 'undefined') { - result = baseIsEqual(valValue, othValue, callback, isWhere, stackA, stackB); + result = baseIsEqual(valValue, othValue, customizer, isWhere, stackA, stackB); } } if (!result) { @@ -1912,9 +2031,9 @@ if (result) { valValue = value[key]; othValue = other[key]; - result = callback ? callback(valValue, othValue, key) : undefined; + result = customizer ? customizer(valValue, othValue, key) : undefined; if (typeof result == 'undefined') { - result = baseIsEqual(valValue, othValue, callback, isWhere, stackA, stackB); + result = baseIsEqual(valValue, othValue, customizer, isWhere, stackA, stackB); } } if (!result) { @@ -1953,6 +2072,24 @@ return result; } + /** + * The base implementation of `_.map` without support for callback shorthands + * or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iterator The function called per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iterator) { + var result = []; + + baseEach(collection, function(value, key, collection) { + result.push(iterator(value, key, collection)); + }); + return result; + } + /** * The base implementation of `_.merge` without support for argument juggling, * multiple sources, and `this` binding. @@ -1960,12 +2097,12 @@ * @private * @param {Object} object The destination object. * @param {Object} source The source object. - * @param {Function} [callback] The function to customize merging properties. + * @param {Function} [customizer] The function to customize merging properties. * @param {Array} [stackA=[]] Tracks traversed source objects. * @param {Array} [stackB=[]] Associates values with source counterparts. * @returns {Object} Returns the destination object. */ - function baseMerge(object, source, callback, stackA, stackB) { + function baseMerge(object, source, customizer, stackA, stackB) { var isSrcArr = isArrayLike(source); (isSrcArr ? arrayEach : baseForOwn)(source, function(srcValue, key, source) { var isArr = srcValue && isArrayLike(srcValue), @@ -1973,7 +2110,7 @@ value = object[key]; if (!(isArr || isObj)) { - result = callback ? callback(value, srcValue, key, object, source) : undefined; + result = customizer ? customizer(value, srcValue, key, object, source) : undefined; if (typeof result == 'undefined') { result = srcValue; } @@ -1993,7 +2130,7 @@ return; } } - var result = callback ? callback(value, srcValue, key, object, source) : undefined, + var result = customizer ? customizer(value, srcValue, key, object, source) : undefined, isShallow = typeof result != 'undefined'; if (!isShallow) { @@ -2008,7 +2145,7 @@ // recursively merge objects and arrays (susceptible to call stack limits) if (!isShallow) { - baseMerge(result, srcValue, callback, stackA, stackB); + baseMerge(result, srcValue, customizer, stackA, stackB); } object[key] = result; }); @@ -2016,6 +2153,27 @@ return object; } + /** + * The base implementation of `_.partial` and `_.partialRight` which accepts + * an array of arguments to partially apply and handles resolving the arity + * of `func`. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags to compose. + * @param {Array} args The array of arguments to be partially applied. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new partially applied function. + */ + function basePartial(func, bitmask, args, thisArg) { + if (func) { + var arity = func[expando] ? func[expando][2] : func.length; + arity -= args.length; + } + var isPartial = bitmask & PARTIAL_FLAG; + return createWrapper(func, bitmask, arity, thisArg, isPartial && args, !isPartial && args); + } + /** * The base implementation of `_.pick` without support for `this` binding * and individual property name arguments. @@ -2087,17 +2245,58 @@ return min + floor(nativeRandom() * (max - min + 1)); } + /** + * The base implementation of `_.reduce` without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iterator The function called per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromCollection=false] Specify using the first element + * of `collection` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iterator, accumulator, initFromCollection) { + baseEach(collection, function(value, index, collection) { + accumulator = initFromCollection + ? (initFromCollection = false, value) + : iterator(accumulator, value, index, collection) + }); + return accumulator; + } + + /** + * The base implementation of `_.some` without support for callback shorthands + * or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function called per iteration. + * @returns {boolean} Returns `true` if any element passed the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + /** * The base implementation of `_.uniq` without support for callback shorthands * and `this` binding. * * @private * @param {Array} array The array to inspect. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function} [callback] The function called per iteration. + * @param {boolean} [isSorted=false] Specify the array is sorted. + * @param {Function} [iterator] The function called per iteration. * @returns {Array} Returns the new duplicate-value-free array. */ - function baseUniq(array, isSorted, callback) { + function baseUniq(array, isSorted, iterator) { var length = array ? array.length : 0; if (!length) { return []; @@ -2113,12 +2312,12 @@ var seen = createCache(); indexOf = cacheIndexOf; } else { - seen = (callback && !isSorted) ? [] : result; + seen = (iterator && !isSorted) ? [] : result; } outer: while (++index < length) { var value = array[index], - computed = callback ? callback(value, index, array) : value; + computed = iterator ? iterator(value, index, array) : value; if (isCommon) { var seenIndex = seen.length; @@ -2127,7 +2326,7 @@ continue outer; } } - if (callback) { + if (iterator) { seen.push(computed); } result.push(value); @@ -2139,7 +2338,7 @@ } } else if (indexOf(seen, computed) < 0) { - if (callback || isLarge) { + if (iterator || isLarge) { seen.push(computed); } result.push(value); @@ -2261,9 +2460,9 @@ /** * Creates a function that aggregates a collection, creating an accumulator * object composed from the results of running each element in the collection - * through a callback. The given setter function sets the keys and values of - * the accumulator object. If `initializer` is provided it is used to - * initialize the accumulator object. + * through `iterator`. The given setter function sets the keys and values of + * the accumulator object. If `initializer` is provided it is used to initialize + * the accumulator object. * * @private * @param {Function} setter The function to set keys and values of the accumulator object. @@ -2271,9 +2470,9 @@ * @returns {Function} Returns the new aggregator function. */ function createAggregator(setter, initializer) { - return function(collection, callback, thisArg) { + return function(collection, iterator, thisArg) { var result = initializer ? initializer() : {}; - callback = lodash.createCallback(callback, thisArg, 3); + iterator = lodash.callback(iterator, thisArg, 3); if (isArray(collection)) { var index = -1, @@ -2281,11 +2480,11 @@ while (++index < length) { var value = collection[index]; - setter(result, value, callback(value, index, collection), collection); + setter(result, value, iterator(value, index, collection), collection); } } else { baseEach(collection, function(value, key, collection) { - setter(result, value, callback(value, key, collection), collection); + setter(result, value, iterator(value, key, collection), collection); }); } return result; @@ -2297,7 +2496,7 @@ * destination object. * * @private - * @param {Function} assigner The function to customize assigning values. + * @param {Function} assigner The function to handle assigning values. * @returns {Function} Returns the new assigner function. */ function createAssigner(assigner) { @@ -2315,18 +2514,37 @@ } // juggle arguments if (length > 3 && typeof args[length - 2] == 'function') { - var callback = baseCreateCallback(args[--length - 1], args[length--], 5); + var customizer = baseCallback(args[--length - 1], args[length--], 5); } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; + customizer = args[--length]; } var index = 0; while (++index < length) { - assigner(object, args[index], callback); + assigner(object, args[index], customizer); } return object; }; } + /** + * Creates a function that invokes the function specified in the metadata + * with its associated `this` binding. + * + * @private + * @param {Array} data The metadata array. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(data) { + var func = data[0], + thisArg = data[3], + Ctor = createCtorWrapper(func); + + function wrapper() { + return (this instanceof wrapper ? Ctor : func).apply(thisArg, arguments); + } + return wrapper; + } + /** * Creates a cache object to optimize linear searches of large arrays. * @@ -2345,6 +2563,25 @@ return cache; }; + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new function. + */ + function createCtorWrapper(Ctor) { + return function() { + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, arguments); + + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + return isObject(result) ? result : thisBinding; + }; + } + /** * Creates the pad required for `string` based on the given padding length. * The `chars` string may be truncated if the number of padding characters @@ -2368,6 +2605,45 @@ return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); } + /** + * Creates a function that invokes the function specified in the metadata + * with its associated partially applied arguments and optional `this` binding. + * + * @private + * @param {Array} data The metadata array. + * @returns {Function} Returns the new bound function. + */ + function createPartialWrapper(data) { + var func = data[0], + bitmask = data[1], + thisArg = data[3], + partialArgs = data[4], + partialHolders = data[6]; + + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + // avoid `arguments` object use disqualifying optimizations by + // converting it to an array before passing it to `composeArgs` + var argsIndex = 0, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partialArgs.length, + args = Array(argsLength + leftLength), + thisBinding = isBind ? thisArg : this; + + while (++leftIndex < leftLength) { + args[leftIndex] = partialArgs[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[argsIndex++]; + } + return (this instanceof wrapper ? Ctor : func).apply(thisBinding, args); + } + return wrapper; + } + /** * Creates a function that either curries or invokes `func` with an optional * `this` binding and partially applied arguments. @@ -2379,9 +2655,10 @@ * 1 - `_.bind` * 2 - `_.bindKey` * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` + * 8 - `_.curryRight` + * 16 - `_.curry` or `_.curryRight` of a bound function + * 32 - `_.partial` + * 64 - `_.partialRight` * @param {number} [arity] The arity of `func`. * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partialArgs] An array of arguments to prepend to those @@ -2463,12 +2740,7 @@ arity = isBindKey ? 0 : func.length; } arity = nativeMax(arity, 0); - - // fast path for `_.bind` - data = [func, bitmask, arity, thisArg, partialArgs, partialRightArgs, partialHolders, partialRightHolders]; - return (bitmask == BIND_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) - ? baseBind(data) - : baseCreateWrapper(data); + return baseCreateWrapper([func, bitmask, arity, thisArg, partialArgs, partialRightArgs, partialHolders, partialRightHolders]); } /** @@ -2566,11 +2838,13 @@ * @private * @param {Function} func The function to set data on. * @param {Array} value The data array to set. + * @returns {Function} Returns `func`. */ - var setData = !defineProperty ? noop : function(func, value) { + var setData = !defineProperty ? identity : function(func, value) { descriptor.value = value; defineProperty(func, expando, descriptor); descriptor.value = null; + return func; }; /** @@ -2653,7 +2927,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to process. * @param {numer} [chunkSize=1] The size of each chunk. * @returns {Array} Returns the new array containing chunks. @@ -2683,7 +2957,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to compact. * @returns {Array} Returns the new array of filtered values. * @example @@ -2712,7 +2986,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to inspect. * @param {...Array} [values] The arrays of values to exclude. * @returns {Array} Returns the new array of filtered values. @@ -2731,7 +3005,7 @@ break; } } - return baseDifference(arguments[index], baseFlatten(arguments, true, true, ++index)); + return baseDifference(arguments[index], baseFlatten(arguments, false, true, ++index)); } /** @@ -2740,9 +3014,10 @@ * @static * @memberOf _ * @type Function - * @category Arrays + * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -2758,7 +3033,10 @@ * _.drop([1, 2, 3], 0); * // => [1, 2, 3] */ - var drop = rest; + function drop(array, n, guard) { + n = (n == null || guard) ? 1 : n; + return slice(array, n < 0 ? 0 : n); + } /** * Creates a slice of `array` with `n` elements dropped from the end. @@ -2766,9 +3044,10 @@ * @static * @memberOf _ * @type Function - * @category Arrays + * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -2784,7 +3063,12 @@ * _.dropRight([1, 2, 3], 0); * // => [1, 2, 3] */ - var dropRight = initial; + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + n = (n == null || guard) ? 1 : n; + n = length - (n || 0); + return slice(array, 0, n < 0 ? 0 : n); + } /** * Creates a slice of `array` excluding elements dropped from the end. @@ -2801,10 +3085,11 @@ * @static * @memberOf _ * @type Function - * @category Arrays + * @category Array * @param {Array} array The array to query. * @param {Function|Object|string} [predicate=identity] The function called * per element. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -2825,7 +3110,14 @@ * _.pluck(_.dropRightWhile(characters, { 'employer': 'na' }), 'name'); * // => ['barney', 'fred'] */ - var dropRightWhile = initial; + function dropRightWhile(array, predicate, thisArg) { + var length = array ? array.length : 0, + index = length; + + predicate = lodash.callback(predicate, thisArg, 3); + while (index-- && predicate(array[index], index, array)) { } + return slice(array, 0, index + 1); + } /** * Creates a slice of `array` excluding elements dropped from the beginning. @@ -2842,7 +3134,7 @@ * @static * @memberOf _ * @type Function - * @category Arrays + * @category Array * @param {Array} array The array to query. * @param {Function|Object|string} [predicate=identity] The function called * per element. @@ -2866,7 +3158,14 @@ * _.pluck(_.dropWhile(characters, { 'employer': 'slate' }), 'name'); * // => ['pebbles'] */ - var dropWhile = rest; + function dropWhile(array, predicate, thisArg) { + var index = -1, + length = array ? array.length : 0; + + predicate = lodash.callback(predicate, thisArg, 3); + while (++index < length && predicate(array[index], index, array)) { } + return slice(array, index); + } /** * This method is like `_.find` except that it returns the index of the first @@ -2881,7 +3180,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to search. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -2913,7 +3212,7 @@ var index = -1, length = array ? array.length : 0; - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); while (++index < length) { if (predicate(array[index], index, array)) { return index; @@ -2935,7 +3234,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to search. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -2966,7 +3265,7 @@ function findLastIndex(array, predicate, thisArg) { var length = array ? array.length : 0; - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); while (length--) { if (predicate(array[length], length, array)) { return length; @@ -2978,13 +3277,10 @@ /** * Gets the first element of `array`. * - * Note: The `n` and `predicate` arguments are deprecated; replace with - * `_.take` and `_.takeWhile` respectively. - * * @static * @memberOf _ * @alias head - * @category Arrays + * @category Array * @param {Array} array The array to query. * @returns {*} Returns the first element of `array`. * @example @@ -2995,88 +3291,41 @@ * _.first([]); * // => undefined */ - function first(array, predicate, thisArg) { - if (typeof predicate != 'number' && predicate != null) { - var index = -1, - length = array ? array.length : 0, - n = 0; - - predicate = lodash.createCallback(predicate, thisArg, 3); - while (++index < length && predicate(array[index], index, array)) { - n++; - } - } else { - n = predicate; - if (n == null || thisArg) { - return array ? array[0] : undefined; - } - } - return slice(array, 0, n < 0 ? 0 : n); + function first(array) { + return array ? array[0] : undefined; } /** - * Flattens a nested array (the nesting can be to any depth). If `isShallow` - * is truthy, the array is only flattened a single level. If a callback is - * provided each element of the array is passed through the callback before - * flattening. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback returns the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * returns `true` for elements that have the properties of the given object, - * else `false`. + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {Function|Object|string} [callback] The function called per iteration. - * 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`. + * @param {boolean} [isDeep=false] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Array} Returns the new flattened array. * @example * * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * // using `isShallow` - * _.flatten([1, [2], [3, [[4]]]], true); * // => [1, 2, 3, [[4]]]; * - * var characters = [ - * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * // using "_.pluck" callback shorthand - * _.flatten(characters, 'pets'); - * // => ['hoppy', 'baby puss', 'dino'] + * // using `isDeep` + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, 4]; */ - function flatten(array, isShallow, callback, thisArg) { + function flatten(array, isDeep, guard) { var length = array ? array.length : 0; if (!length) { return []; } - // juggle arguments - var type = typeof isShallow; - if (type != 'boolean' && isShallow != null) { - thisArg = callback; - callback = isShallow; - isShallow = false; - - // enables use as a callback for functions like `_.map` - if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === array) { - callback = null; - } + // enables use as a callback for functions like `_.map` + var type = typeof isDeep; + if ((type == 'number' || type == 'string') && guard && guard[isDeep] === array) { + isDeep = false; } - if (callback != null) { - array = map(array, callback, thisArg); - } - return baseFlatten(array, isShallow); + return baseFlatten(array, isDeep); } /** @@ -3086,7 +3335,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to search. * @param {*} value The value to search for. * @param {boolean|number} [fromIndex=0] The index to search from or `true` @@ -3119,12 +3368,9 @@ /** * Gets all but the last element of `array`. * - * Note: The `n` and `predicate` arguments are deprecated; replace with - * `_.dropRight` and `_.dropRightWhile` respectively. - * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to query. * @returns {Array} Returns the slice of `array`. * @example @@ -3132,22 +3378,9 @@ * _.initial([1, 2, 3]); * // => [1, 2] */ - function initial(array, predicate, thisArg) { + function initial(array) { var length = array ? array.length : 0; - - if (typeof predicate != 'number' && predicate != null) { - var index = length, - n = 0; - - predicate = lodash.createCallback(predicate, thisArg, 3); - while (index-- && predicate(array[index], index, array)) { - n++; - } - } else { - n = (predicate == null || thisArg) ? 1 : predicate; - } - n = length - (n || 0); - return slice(array, 0, n < 0 ? 0 : n); + return slice(array, 0, length ? length - 1 : 0); } /** @@ -3156,7 +3389,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of shared values. * @example @@ -3210,12 +3443,9 @@ /** * Gets the last element of `array`. * - * Note: The `n` and `predicate` arguments are deprecated; replace with - * `_.takeRight` and `_.takeRightWhile` respectively. - * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to query. * @returns {*} Returns the last element of `array`. * @example @@ -3223,25 +3453,9 @@ * _.last([1, 2, 3]); * // => 3 */ - function last(array, predicate, thisArg) { + function last(array) { var length = array ? array.length : 0; - - if (typeof predicate != 'number' && predicate != null) { - var index = length, - n = 0; - - predicate = lodash.createCallback(predicate, thisArg, 3); - while (index-- && predicate(array[index], index, array)) { - n++; - } - } else { - n = predicate; - if (n == null || thisArg) { - return array ? array[length - 1] : undefined; - } - } - n = length - (n || 0); - return slice(array, n < 0 ? 0 : n); + return length ? array[length - 1] : undefined; } /** @@ -3251,7 +3465,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to search. * @param {*} value The value to search for. * @param {number} [fromIndex=array.length-1] The index to search from. @@ -3286,7 +3500,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to modify. * @param {...*} [values] The values to remove. * @returns {Array} Returns `array`. @@ -3318,14 +3532,14 @@ /** * Removes elements from `array` corresponding to the specified indexes and - * returns an array of removed elements. Indexes may be specified as an array - * of indexes or as individual arguments. + * returns an array of the removed elements. Indexes may be specified as an + * array of indexes or as individual arguments. * * Note: Unlike `_.at`, this method mutates `array`. * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to modify. * @param {...(number|number[])} [indexes] The indexes of elements to remove, * specified as individual indexes or arrays of indexes. @@ -3342,13 +3556,13 @@ * // => [10, 20] */ function pullAt(array) { - return basePullAt(array, baseFlatten(arguments, true, false, 1)); + return basePullAt(array, baseFlatten(arguments, false, false, 1)); } /** * Removes all elements from `array` that the predicate returns truthy for - * and returns an array of removed elements. The predicate is bound to `thisArg` - * and invoked with three arguments; (value, index, array). + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments; (value, index, array). * * If a property name is provided for `predicate` the created "_.pluck" style * callback returns the property value of the given element. @@ -3361,7 +3575,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to modify. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -3384,7 +3598,7 @@ length = array ? array.length : 0, result = []; - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { @@ -3399,13 +3613,10 @@ /** * Gets all but the first element of `array`. * - * Note: The `n` and `predicate` arguments are deprecated; replace with - * `_.drop` and `_.dropWhile` respectively. - * * @static * @memberOf _ * @alias tail - * @category Arrays + * @category Array * @param {Array} array The array to query. * @returns {Array} Returns the slice of `array`. * @example @@ -3413,22 +3624,8 @@ * _.rest([1, 2, 3]); * // => [2, 3] */ - function rest(array, predicate, thisArg) { - if (typeof predicate != 'number' && predicate != null) { - var index = -1, - length = array ? array.length : 0, - n = 0; - - predicate = lodash.createCallback(predicate, thisArg, 3); - while (++index < length && predicate(array[index], index, array)) { - n++; - } - } else if (predicate == null || thisArg) { - n = 1; - } else { - n = predicate < 0 ? 0 : predicate; - } - return slice(array, n); + function rest(array) { + return slice(array, 1); } /** @@ -3439,7 +3636,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to slice. * @param {number} [start=0] The start index. * @param {number} [end=array.length] The end index. @@ -3473,26 +3670,26 @@ /** * Uses a binary search to determine the smallest index at which a value * should be inserted into a given sorted array in order to maintain the sort - * order of the array. If a callback is provided it is executed for `value` - * and each element of `array` to compute their sort ranking. The callback - * is bound to `thisArg` and invoked with one argument; (value). + * order of the array. If an iterator function is provided it is executed for + * `value` and each element of `array` to compute their sort ranking. The + * iterator function is bound to `thisArg` and invoked with one argument; (value). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to evaluate. - * @param {Function|Object|string} [callback=identity] The function called + * @param {Function|Object|string} [iterator=identity] The function called * per iteration. 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example @@ -3504,13 +3701,7 @@ * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'forty': 40, 'fifty': 50 } * }; * - * // using `callback` - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'forty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * // using `callback` with `thisArg` + * // using an iterator function * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'forty', function(word) { * return this.wordToNumber[word]; * }, dict); @@ -3520,17 +3711,17 @@ * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); * // => 2 */ - function sortedIndex(array, value, callback, thisArg) { + function sortedIndex(array, value, iterator, thisArg) { var low = 0, high = array ? array.length : low; // explicitly reference `identity` for better inlining in Firefox - callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; - value = callback(value); + iterator = iterator ? lodash.callback(iterator, thisArg, 1) : identity; + value = iterator(value); while (low < high) { var mid = (low + high) >>> 1; - (callback(array[mid]) < value) + (iterator(array[mid]) < value) ? (low = mid + 1) : (high = mid); } @@ -3543,9 +3734,10 @@ * @static * @memberOf _ * @type Function - * @category Arrays + * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -3561,7 +3753,10 @@ * _.take([1, 2, 3], 0); * // => [] */ - var take = first; + function take(array, n, guard) { + n = (n == null || guard) ? 1 : n; + return slice(array, 0, n < 0 ? 0 : n); + } /** * Creates a slice of `array` with `n` elements taken from the end. @@ -3569,9 +3764,10 @@ * @static * @memberOf _ * @type Function - * @category Arrays + * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * @@ -3587,7 +3783,12 @@ * _.takeRight([1, 2, 3], 0); * // => [] */ - var takeRight = last; + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + n = (n == null || guard) ? 1 : n; + n = length - (n || 0); + return slice(array, n < 0 ? 0 : n); + } /** * Creates a slice of `array` with elements taken from the end. Elements are @@ -3604,7 +3805,7 @@ * @static * @memberOf _ * @type Function - * @category Arrays + * @category Array * @param {Array} array The array to query. * @param {Function|Object|string} [predicate=identity] The function called * per element. @@ -3628,7 +3829,14 @@ * _.pluck(_.takeRightWhile(characters, { 'employer': 'na' }), 'name'); * // => ['pebbles'] */ - var takeRightWhile = last; + function takeRightWhile(array, predicate, thisArg) { + var length = array ? array.length : 0, + index = length; + + predicate = lodash.callback(predicate, thisArg, 3); + while (index-- && predicate(array[index], index, array)) { } + return slice(array, index + 1); + } /** * Creates a slice of `array` with elements taken from the beginning. Elements @@ -3645,7 +3853,7 @@ * @static * @memberOf _ * @type Function - * @category Arrays + * @category Array * @param {Array} array The array to query. * @param {Function|Object|string} [predicate=identity] The function called * per element. @@ -3669,7 +3877,14 @@ * _.pluck(_.takeWhile(characters, { 'employer': 'slate' }), 'name'); * // => ['barney', 'fred'] */ - var takeWhile = first; + function takeWhile(array, predicate, thisArg) { + var index = -1, + length = array ? array.length : 0; + + predicate = lodash.callback(predicate, thisArg, 3); + while (++index < length && predicate(array[index], index, array)) { } + return slice(array, 0, index); + } /** * Creates an array of unique values, in order, of the provided arrays using @@ -3677,7 +3892,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of combined values. * @example @@ -3686,34 +3901,34 @@ * // => [1, 2, 3, 5, 4] */ function union() { - return baseUniq(baseFlatten(arguments, true, true)); + return baseUniq(baseFlatten(arguments, false, true)); } /** * Creates a duplicate-value-free version of an array using strict equality * for comparisons, i.e. `===`. Providing `true` for `isSorted` performs a - * faster search algorithm for sorted arrays. If a callback is provided it - * is executed for each value in the array to generate the criterion by which - * uniqueness is computed. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). + * faster search algorithm for sorted arrays. If an iterator function is + * provided it is executed for each value in the array to generate the criterion + * by which uniqueness is computed. The `iterator` is bound to `thisArg` and + * invoked with three arguments; (value, index, array). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ * @alias unique - * @category Arrays + * @category Array * @param {Array} array The array to inspect. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function|Object|string} [callback] The function called per iteration. + * @param {boolean} [isSorted=false] Specify the array is sorted. + * @param {Function|Object|string} [iterator] The function called per iteration. * 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Array} Returns the new duplicate-value-free array. * @example * @@ -3724,11 +3939,7 @@ * _.uniq([1, 1, 2], true); * // => [1, 2] * - * // using `callback` - * _.uniq(['A', 'b', 'a', 'B'], function(chr) { return chr.toLowerCase(); }); - * // => ['A', 'b'] - * - * // using `callback` with `thisArg` + * // using an iterator function * _.uniq([1, 2.5, 1.5, 2], function(n) { return this.floor(n); }, Math); * // => [1, 2.5] * @@ -3736,7 +3947,7 @@ * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ - function uniq(array, isSorted, callback, thisArg) { + function uniq(array, isSorted, iterator, thisArg) { var length = array ? array.length : 0; if (!length) { return []; @@ -3744,19 +3955,19 @@ // juggle arguments var type = typeof isSorted; if (type != 'boolean' && isSorted != null) { - thisArg = callback; - callback = isSorted; + thisArg = iterator; + iterator = isSorted; isSorted = false; // enables use as a callback for functions like `_.map` - if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === array) { - callback = null; + if ((type == 'number' || type == 'string') && thisArg && thisArg[iterator] === array) { + iterator = null; } } - if (callback != null) { - callback = lodash.createCallback(callback, thisArg, 3); + if (iterator != null) { + iterator = lodash.callback(iterator, thisArg, 3); } - return baseUniq(array, isSorted, callback); + return baseUniq(array, isSorted, iterator); } /** @@ -3765,7 +3976,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {Array} array The array to filter. * @param {...*} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. @@ -3785,7 +3996,7 @@ * * @static * @memberOf _ - * @category Arrays + * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of values. * @example @@ -3820,7 +4031,7 @@ * @static * @memberOf _ * @alias unzip - * @category Arrays + * @category Array * @param {...Array} [arrays] The arrays to process. * @returns {Array} Returns the array of grouped elements. * @example @@ -3851,7 +4062,7 @@ * @static * @memberOf _ * @alias object - * @category Arrays + * @category Array * @param {Array} keys The array of keys. * @param {Array} [values=[]] The array of values. * @returns {Object} Returns the new object. @@ -3887,7 +4098,7 @@ * * @static * @memberOf _ - * @category Chaining + * @category Chain * @param {*} value The value to wrap. * @returns {Object} Returns the new wrapper object. * @example @@ -3906,7 +4117,9 @@ * // => 'pebbles is 1' */ function chain(value) { - return new lodashWrapper(value, true); + var result = lodash(value); + result.__chain__ = true; + return result; } /** @@ -3917,7 +4130,7 @@ * * @static * @memberOf _ - * @category Chaining + * @category Chain * @param {*} value The value to provide to `interceptor`. * @param {Function} interceptor The function to invoke. * @param {*} [thisArg] The `this` binding of `interceptor`. @@ -3940,7 +4153,7 @@ * * @name chain * @memberOf _ - * @category Chaining + * @category Chain * @returns {*} Returns the wrapper object. * @example * @@ -3970,7 +4183,7 @@ * * @name toString * @memberOf _ - * @category Chaining + * @category Chain * @returns {string} Returns the coerced string value. * @example * @@ -3987,7 +4200,7 @@ * @name valueOf * @memberOf _ * @alias toJSON, value - * @category Chaining + * @category Chain * @returns {*} Returns the wrapped value. * @example * @@ -4007,7 +4220,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {...(number|number[]|string|string[])} [keys] The keys of elements * to pick, specified as individual keys or arrays of keys. @@ -4024,7 +4237,7 @@ if (support.unindexedChars && isString(collection)) { collection = collection.split(''); } - return baseAt(collection, baseFlatten(arguments, true, false, 1)); + return baseAt(collection, baseFlatten(arguments, false, false, 1)); } /** @@ -4035,7 +4248,7 @@ * @static * @memberOf _ * @alias include - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to search. * @param {*} target The value to check for. * @param {number} [fromIndex=0] The index to search from. @@ -4079,26 +4292,26 @@ /** * Creates an object composed of keys generated from the results of running - * each element of `collection` through the callback. The corresponding value - * of each key is the number of times the key was returned by the callback. - * The callback is bound to `thisArg` and invoked with three arguments; + * each element of `collection` through `iterator`. The corresponding value + * of each key is the number of times the key was returned by `iterator`. + * The `iterator` is bound to `thisArg` and invoked with three arguments; * (value, index|key, collection). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called + * @param {Function|Object|string} [iterator=identity] The function called * per iteration. 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Object} Returns the composed aggregate object. * @example * @@ -4130,7 +4343,7 @@ * @static * @memberOf _ * @alias all - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -4157,27 +4370,11 @@ * // => false */ function every(collection, predicate, thisArg) { - var result = true; - if (typeof predicate != 'function' || typeof thisArg != 'undefined') { - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); } - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!predicate(collection[index], index, collection)) { - return false; - } - } - } else { - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - } - return result; + var func = isArray(collection) ? arrayEvery : baseEvery; + return func(collection, predicate); } /** @@ -4195,7 +4392,7 @@ * @static * @memberOf _ * @alias select - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -4221,27 +4418,10 @@ * // => [{ 'name': 'barney', 'age': 36 }] */ function filter(collection, predicate, thisArg) { - var result = []; - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (predicate(value, index, collection)) { - result.push(value); - } - } - } else { - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - } - return result; + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, predicate); } /** @@ -4259,7 +4439,7 @@ * @static * @memberOf _ * @alias detect - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to search. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -4292,7 +4472,7 @@ var index = findIndex(collection, predicate, thisArg); return index > -1 ? collection[index] : undefined; } - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); return baseFind(collection, predicate, baseEach); } @@ -4302,7 +4482,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to search. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -4315,7 +4495,7 @@ * // => 3 */ function findLast(collection, predicate, thisArg) { - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); return baseFind(collection, predicate, baseEachRight); } @@ -4326,7 +4506,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to search. * @param {Object} source The object of property values to match. * @returns {*} Returns the matched element, else `undefined`. @@ -4348,10 +4528,10 @@ } /** - * Iterates over elements of a collection executing the callback for each - * element. The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Callbacks may exit iteration early by - * explicitly returning `false`. + * Iterates over elements of a collection executing `iterator` for each + * element. The `iterator` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Iterator functions may exit iteration early + * by explicitly returning `false`. * * Note: As with other "Collections" methods, objects with a `length` property * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` @@ -4360,23 +4540,23 @@ * @static * @memberOf _ * @alias each - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [iterator=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Array|Object|string} Returns `collection`. * @example * * _([1, 2, 3]).forEach(function(n) { console.log(n); }).join(','); * // => logs each number and returns '1,2,3' * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(n) { console.log(n); }); - * // => logs each number and returns the object (property order is not guaranteed across environments) + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(n, key) { console.log(n, key); }); + * // => logs each value-key pair and returns the object (property order is not guaranteed across environments) */ - function forEach(collection, callback, thisArg) { - return (typeof callback == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayEach(collection, callback) - : baseEach(collection, baseCreateCallback(callback, thisArg, 3)); + function forEach(collection, iterator, thisArg) { + return (typeof iterator == 'function' && typeof thisArg == 'undefined' && isArray(collection)) + ? arrayEach(collection, iterator) + : baseEach(collection, baseCallback(iterator, thisArg, 3)); } /** @@ -4386,44 +4566,44 @@ * @static * @memberOf _ * @alias eachRight - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [iterator=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Array|Object|string} Returns `collection`. * @example * * _([1, 2, 3]).forEachRight(function(n) { console.log(n); }).join(','); * // => logs each number from right to left and returns '3,2,1' */ - function forEachRight(collection, callback, thisArg) { - return (typeof callback == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayEachRight(collection, callback) - : baseEachRight(collection, baseCreateCallback(callback, thisArg, 3)); + function forEachRight(collection, iterator, thisArg) { + return (typeof iterator == 'function' && typeof thisArg == 'undefined' && isArray(collection)) + ? arrayEachRight(collection, iterator) + : baseEachRight(collection, baseCallback(iterator, thisArg, 3)); } /** * Creates an object composed of keys generated from the results of running - * each element of a collection through the callback. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). + * each element of a collection through `iterator`. The corresponding + * value of each key is an array of the elements responsible for generating + * the key. The `iterator` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called + * @param {Function|Object|string} [iterator=identity] The function called * per iteration. 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Object} Returns the composed aggregate object. * @example * @@ -4447,26 +4627,26 @@ /** * Creates an object composed of keys generated from the results of running - * each element of the collection through the given callback. The corresponding - * value of each key is the last element responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; + * each element of the collection through `iterator`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iterator function is bound to `thisArg` and invoked with three arguments; * (value, index|key, collection). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called + * @param {Function|Object|string} [iterator=identity] The function called * per iteration. 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Object} Returns the composed aggregate object. * @example * @@ -4496,7 +4676,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|string} methodName The name of the method to invoke or * the function invoked per iteration. @@ -4515,26 +4695,26 @@ } /** - * Creates an array of values by running each element in the collection - * through the callback. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). + * Creates an array of values by running each element in the collection through + * `iterator`. The `iterator` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ * @alias collect - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called + * @param {Function|Object|string} [iterator=identity] The function called * per iteration. 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Array} Returns the new mapped array. * @example * @@ -4553,43 +4733,35 @@ * _.map(characters, 'name'); * // => ['barney', 'fred'] */ - function map(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); + function map(collection, iterator, thisArg) { + iterator = lodash.callback(iterator, thisArg, 3); - if (isArray(collection)) { - return arrayMap(collection, callback, thisArg); - } - var index = -1, - result = []; - - baseEach(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - return result; + var func = isArray(collection) ? arrayMap : baseMap; + return func(collection, iterator); } /** * Retrieves the maximum value of a collection. If the collection is empty - * or falsey `-Infinity` is returned. If a callback is provided it is executed - * for each value in the collection to generate the criterion by which the - * value is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). + * or falsey `-Infinity` is returned. If an iterator function is provided it + * is executed for each value in the collection to generate the criterion by + * which the value is ranked. The `iterator` is bound to `thisArg` and invoked + * with three arguments; (value, index, collection). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback] The function called per iteration. + * @param {Function|Object|string} [iterator] The function called per iteration. * 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {*} Returns the maximum value. * @example * @@ -4611,16 +4783,16 @@ * _.max(characters, 'age'); * // => { 'name': 'fred', 'age': 40 }; */ - function max(collection, callback, thisArg) { + function max(collection, iterator, thisArg) { var computed = -Infinity, result = computed, - type = typeof callback; + type = typeof iterator; // enables use as a callback for functions like `_.map` - if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === collection) { - callback = null; + if ((type == 'number' || type == 'string') && thisArg && thisArg[iterator] === collection) { + iterator = null; } - if (callback == null && isArray(collection)) { + if (iterator == null && isArray(collection)) { var index = -1, length = collection.length; @@ -4631,12 +4803,12 @@ } } } else { - callback = (callback == null && isString(collection)) + iterator = (iterator == null && isString(collection)) ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); + : lodash.callback(iterator, thisArg, 3); baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); + var current = iterator(value, index, collection); if (current > computed || (current === -Infinity && current === result)) { computed = current; result = value; @@ -4648,26 +4820,26 @@ /** * Retrieves the minimum value of a collection. If the collection is empty - * or falsey `Infinity` is returned. If a callback is provided it is executed - * for each value in the collection to generate the criterion by which the - * value is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). + * or falsey `Infinity` is returned. If an iterator function is provided it + * is executed for each value in the collection to generate the criterion by + * which the value is ranked. The `iterator` is bound to `thisArg` and invoked + * with three arguments; (value, index, collection). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback] The function called per iteration. + * @param {Function|Object|string} [iterator] The function called per iteration. * 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {*} Returns the minimum value. * @example * @@ -4689,16 +4861,16 @@ * _.min(characters, 'age'); * // => { 'name': 'barney', 'age': 36 }; */ - function min(collection, callback, thisArg) { + function min(collection, iterator, thisArg) { var computed = Infinity, result = computed, - type = typeof callback; + type = typeof iterator; // enables use as a callback for functions like `_.map` - if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === collection) { - callback = null; + if ((type == 'number' || type == 'string') && thisArg && thisArg[iterator] === collection) { + iterator = null; } - if (callback == null && isArray(collection)) { + if (iterator == null && isArray(collection)) { var index = -1, length = collection.length; @@ -4709,12 +4881,12 @@ } } } else { - callback = (callback == null && isString(collection)) + iterator = (iterator == null && isString(collection)) ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); + : lodash.callback(iterator, thisArg, 3); baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); + var current = iterator(value, index, collection); if (current < computed || (current === Infinity && current === result)) { computed = current; result = value; @@ -4739,7 +4911,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -4777,7 +4949,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {string} key The name of the property to pluck. * @returns {Array} Returns the property values. @@ -4797,20 +4969,20 @@ /** * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection is used - * as the initial `accumulator` value. The callback is bound to `thisArg` and - * invoked with four arguments; (accumulator, value, index|key, collection). + * each element in the collection through `iterator`, where each successive + * execution consumes the return value of the previous execution. If `accumulator` + * is not provided the first element of the collection is used as the initial + * value. The `iterator` is bound to `thisArg`and invoked with four arguments; + * (accumulator, value, index|key, collection). * * @static * @memberOf _ * @alias foldl, inject - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [iterator=identity] The function called per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {*} Returns the accumulated value. * @example * @@ -4823,28 +4995,11 @@ * }, {}); * // => { 'a': 3, 'b': 6, 'c': 9 } */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); + function reduce(collection, iterator, accumulator, thisArg) { + iterator = lodash.callback(iterator, thisArg, 4); - if (isArray(collection)) { - var index = -1, - length = collection.length; - - if (noaccum && length) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - baseEach(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; + var func = isArray(collection) ? arrayReduce : baseReduce; + return func(collection, iterator, accumulator, arguments.length < 3); } /** @@ -4854,11 +5009,11 @@ * @static * @memberOf _ * @alias foldr - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [iterator=identity] The function called per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {*} Returns the accumulated value. * @example * @@ -4866,14 +5021,14 @@ * _.reduceRight(array, function(flattened, other) { return flattened.concat(other); }, []); * // => [4, 5, 2, 3, 0, 1] */ - function reduceRight(collection, callback, accumulator, thisArg) { + function reduceRight(collection, iterator, accumulator, thisArg) { var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); + iterator = lodash.callback(iterator, thisArg, 4); baseEachRight(collection, function(value, index, collection) { accumulator = noaccum ? (noaccum = false, value) - : callback(accumulator, value, index, collection); + : iterator(accumulator, value, index, collection); }); return accumulator; } @@ -4891,7 +5046,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -4917,7 +5072,7 @@ * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] */ function reject(collection, predicate, thisArg) { - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); return filter(collection, negate(predicate)); } @@ -4926,7 +5081,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to sample. * @param {number} [n] The number of elements to sample. * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. @@ -4940,13 +5095,15 @@ * // => [3, 1] */ function sample(collection, n, guard) { - if (collection && typeof collection.length != 'number') { + var length = collection ? collection.length : 0; + + if (!(typeof length == 'number' && length > -1 && length <= maxSafeInteger)) { collection = values(collection); + length = collection.length; } else if (support.unindexedChars && isString(collection)) { collection = collection.split(''); } if (n == null || guard) { - var length = collection ? collection.length : 0; return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; } var result = shuffle(collection); @@ -4961,7 +5118,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to shuffle. * @returns {Array} Returns the new shuffled array. * @example @@ -4988,7 +5145,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to inspect. * @returns {number} Returns `collection.length` or number of own enumerable properties. * @example @@ -5025,7 +5182,7 @@ * @static * @memberOf _ * @alias any - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -5052,54 +5209,38 @@ * // => false */ function some(collection, predicate, thisArg) { - var result; - if (typeof predicate != 'function' || typeof thisArg != 'undefined') { - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); } - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (predicate(collection[index], index, collection)) { - return true; - } - } - } else { - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - } - return !!result; + var func = isArray(collection) ? arraySome : baseSome; + return func(collection, predicate); } /** * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through the callback. This method - * performs a stable sort, that is, it preserves the original sort order of - * equal elements. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). + * running each element in a collection through `iterator`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iterator` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an array of property names is provided for `callback` the collection + * If an array of property names is provided for `iterator` the collection * is sorted by each property value. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [callback=identity] The function + * @param {Array|Function|Object|string} [iterator=identity] The function * called per iteration. If property name(s) or an object is provided it * is used to create a "_.pluck" or "_.where" style callback respectively. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Array} Returns the new sorted array. * @example * @@ -5124,25 +5265,25 @@ * _.map(_.sortBy(characters, ['name', 'age']), _.values); * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] */ - function sortBy(collection, callback, thisArg) { + function sortBy(collection, iterator, thisArg) { var index = -1, length = collection && collection.length, - multi = callback && isArray(callback), + multi = iterator && isArray(iterator), result = Array(length < 0 ? 0 : length >>> 0); if (!multi) { - callback = lodash.createCallback(callback, thisArg, 3); + iterator = lodash.callback(iterator, thisArg, 3); } baseEach(collection, function(value, key, collection) { if (multi) { - var length = callback.length, + var length = iterator.length, criteria = Array(length); while (length--) { - criteria[length] = value[callback[length]]; + criteria[length] = value[iterator[length]]; } } else { - criteria = callback(value, key, collection); + criteria = iterator(value, key, collection); } result[++index] = { 'criteria': criteria, 'index': index, 'value': value }; }); @@ -5160,7 +5301,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to convert. * @returns {Array} Returns the new converted array. * @example @@ -5169,7 +5310,8 @@ * // => [2, 3, 4] */ function toArray(collection) { - var length = collection && collection.length; + var length = collection ? collection.length : 0; + if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { return (support.unindexedChars && isString(collection)) ? collection.split('') @@ -5185,7 +5327,7 @@ * * @static * @memberOf _ - * @category Collections + * @category Collection * @param {Array|Object|string} collection The collection to search. * @param {Object} source The object of property values to match. * @returns {Array} Returns the new filtered array. @@ -5217,7 +5359,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {number} n The number of times the function must be called before * `func` is executed. * @param {Function} func The function to restrict. @@ -5257,7 +5399,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to bind. * @param {*} [thisArg] The `this` binding of `func`. * @param {...*} [args] The arguments to be partially applied. @@ -5273,16 +5415,9 @@ * // => 'hi fred' */ function bind(func, thisArg) { - if (arguments.length < 3) { - return createWrapper(func, BIND_FLAG, null, thisArg); - } - if (func) { - var arity = func[expando] ? func[expando][2] : func.length, - partialArgs = slice(arguments, 2); - - arity -= partialArgs.length; - } - return createWrapper(func, BIND_FLAG | PARTIAL_FLAG, arity, thisArg, partialArgs); + return arguments.length < 3 + ? createWrapper(func, BIND_FLAG, null, thisArg) + : basePartial(func, BIND_FLAG | PARTIAL_FLAG, slice(arguments, 2), thisArg); } /** @@ -5295,7 +5430,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Object} object The object to bind and assign the bound methods to. * @param {...(string|string[])} [methodNames] The object method names to bind, * specified as individual method names or arrays of method names. @@ -5313,7 +5448,7 @@ */ function bindAll(object) { return baseBindAll(object, arguments.length > 1 - ? baseFlatten(arguments, true, false, 1) + ? baseFlatten(arguments, false, false, 1) : functions(object)); } @@ -5347,7 +5482,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Object} object The object the method belongs to. * @param {string} key The key of the method. * @param {...*} [args] The arguments to be partially applied. @@ -5386,7 +5521,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {...Function} [funcs] Functions to compose. * @returns {Function} Returns the new composed function. * @example @@ -5410,20 +5545,23 @@ */ function compose() { var funcs = arguments, - funcsLength = funcs.length, - length = funcsLength; + length = funcs.length, + fromIndex = length - 1; + if (!length) { + return function() {}; + } while (length--) { if (!isFunction(funcs[length])) { throw new TypeError(funcErrorText); } } return function() { - var length = funcsLength - 1, - result = funcs[length].apply(this, arguments); + var index = fromIndex, + result = funcs[index].apply(this, arguments); - while (length--) { - result = funcs[length].call(this, result); + while (index--) { + result = funcs[index].call(this, result); } return result; }; @@ -5440,30 +5578,58 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to curry. * @param {number} [arity=func.length] The arity of `func`. * @returns {Function} Returns the new curried function. * @example * * var curried = _.curry(function(a, b, c) { - * console.log(a + b + c); + * console.log([a, b, c]); * }); * * curried(1)(2)(3); - * // => 6 + * // => [1, 2, 3] * * curried(1, 2)(3); - * // => 6 + * // => [1, 2, 3] * * curried(1, 2, 3); - * // => 6 + * // => [1, 2, 3] */ function curry(func, arity) { - if (typeof arity != 'number') { - arity = +arity || (func ? func.length : 0); - } - return createWrapper(func, CURRY_FLAG, arity); + return baseCurry(func, CURRY_FLAG, arity); + } + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * Note: This method does not set the `length` property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curryRight(function(a, b, c) { + * console.log([a, b, c]); + * }); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + */ + function curryRight(func, arity) { + return baseCurry(func, CURRY_RIGHT_FLAG, arity); } /** @@ -5480,13 +5646,16 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to debounce. * @param {number} wait The number of milliseconds to delay. * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @param {boolean} [options.leading=false] Specify execution on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it is called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing + * edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * @@ -5642,7 +5811,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to defer. * @param {...*} [args] The arguments to invoke the function with. * @returns {number} Returns the timer id. @@ -5665,7 +5834,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay execution. * @param {...*} [args] The arguments to invoke the function with. @@ -5693,7 +5862,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to have its output memoized. * @param {Function} [resolver] The function to resolve the cache key. * @returns {Function} Returns the new memoizing function. @@ -5743,7 +5912,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} predicate The predicate to negate. * @returns {Function} Returns the new function. * @example @@ -5771,7 +5940,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example @@ -5811,7 +5980,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to partially apply arguments to. * @param {...*} [args] The arguments to be partially applied. * @returns {Function} Returns the new partially applied function. @@ -5823,13 +5992,7 @@ * // => 'hello fred' */ function partial(func) { - if (func) { - var arity = func[expando] ? func[expando][2] : func.length, - partialArgs = slice(arguments, 1); - - arity -= partialArgs.length; - } - return createWrapper(func, PARTIAL_FLAG, arity, null, partialArgs); + return basePartial(func, PARTIAL_FLAG, slice(arguments, 1)); } /** @@ -5841,7 +6004,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to partially apply arguments to. * @param {...*} [args] The arguments to be partially applied. * @returns {Function} Returns the new partially applied function. @@ -5864,13 +6027,7 @@ * // => { 'a': { 'b': { 'c': 1, 'd': 2 } } } */ function partialRight(func) { - if (func) { - var arity = func[expando] ? func[expando][2] : func.length, - partialRightArgs = slice(arguments, 1); - - arity -= partialRightArgs.length; - } - return createWrapper(func, PARTIAL_RIGHT_FLAG, arity, null, null, partialRightArgs); + return basePartial(func, PARTIAL_RIGHT_FLAG, slice(arguments, 1)); } /** @@ -5887,12 +6044,14 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {Function} func The function to throttle. * @param {number} wait The number of milliseconds to throttle executions to. * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @param {boolean} [options.leading=true] Specify execution on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing + * edge of the timeout. * @returns {Function} Returns the new throttled function. * @example * @@ -5934,7 +6093,7 @@ * * @static * @memberOf _ - * @category Functions + * @category Function * @param {*} value The value to wrap. * @param {Function} wrapper The wrapper function. * @returns {Function} Returns the new function. @@ -5955,19 +6114,19 @@ /** * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources overwrite property assignments of previous - * sources. If a callback is provided it is executed to produce the assigned - * values. The callback is bound to `thisArg` and invoked with five arguments; + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is executed to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments; * (objectValue, sourceValue, key, object, source). * * @static * @memberOf _ * @alias extend - * @category Objects + * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [customizer] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {Object} Returns the destination object. * @example * @@ -5985,10 +6144,10 @@ /** * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, - * otherwise they are assigned by reference. If a callback is provided it is - * executed to produce the cloned values. If the callback returns `undefined` - * cloning is handled by the method instead. The callback is bound to `thisArg` - * and invoked with two argument; (value, index|key). + * otherwise they are assigned by reference. If `customizer` is provided it is + * executed to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value, index|key). * * Note: This method is loosely based on the structured clone algorithm. Functions * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and @@ -5998,11 +6157,11 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to clone. * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {*} Returns the cloned value. * @example * @@ -6029,29 +6188,29 @@ * clone.childNodes.length; * // => 0 */ - function clone(value, isDeep, callback, thisArg) { + function clone(value, isDeep, customizer, thisArg) { var type = typeof isDeep; // juggle arguments if (type != 'boolean' && isDeep != null) { - thisArg = callback; - callback = isDeep; + thisArg = customizer; + customizer = isDeep; isDeep = false; // enables use as a callback for functions like `_.map` - if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === value) { - callback = null; + if ((type == 'number' || type == 'string') && thisArg && thisArg[customizer] === value) { + customizer = null; } } - callback = typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1); - return baseClone(value, isDeep, callback); + customizer = typeof customizer == 'function' && baseCallback(customizer, thisArg, 1); + return baseClone(value, isDeep, customizer); } /** - * Creates a deep clone of `value`. If a callback is provided it is executed - * to produce the cloned values. If the callback returns `undefined` cloning - * is handled by the method instead. The callback is bound to `thisArg` and - * invoked with two argument; (value, index|key). + * Creates a deep clone of `value`. If `customizer` is provided it is executed + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value, index|key). * * Note: This method is loosely based on the structured clone algorithm. Functions * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and @@ -6061,10 +6220,10 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {*} Returns the deep cloned value. * @example * @@ -6089,9 +6248,9 @@ * clone.node == view.node; * // => false */ - function cloneDeep(value, callback, thisArg) { - callback = typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1); - return baseClone(value, true, callback); + function cloneDeep(value, customizer, thisArg) { + customizer = typeof customizer == 'function' && baseCallback(customizer, thisArg, 1); + return baseClone(value, true, customizer); } /** @@ -6101,7 +6260,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} prototype The object to inherit from. * @param {Object} [properties] The properties to assign to the object. * @returns {Object} Returns the new object. @@ -6140,7 +6299,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. @@ -6172,7 +6331,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to search. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -6201,7 +6360,7 @@ * // => 'fred' */ function findKey(object, predicate, thisArg) { - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); return baseFind(object, predicate, baseForOwn, true); } @@ -6218,7 +6377,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to search. * @param {Function|Object|string} [predicate=identity] The function called * per iteration. If a property name or object is provided it is used to @@ -6247,22 +6406,22 @@ * // => 'pebbles' */ function findLastKey(object, predicate, thisArg) { - predicate = lodash.createCallback(predicate, thisArg, 3); + predicate = lodash.callback(predicate, thisArg, 3); return baseFind(object, predicate, baseForOwnRight, true); } /** * Iterates over own and inherited enumerable properties of an object executing - * the callback for each property. The callback is bound to `thisArg` and invoked - * with three arguments; (value, key, object). Callbacks may exit iteration - * early by explicitly returning `false`. + * `iterator` for each property. The `iterator` is bound to `thisArg` and invoked + * with three arguments; (value, key, object). Iterator functions may exit + * iteration early by explicitly returning `false`. * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [iterator=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Object} Returns `object`. * @example * @@ -6278,11 +6437,11 @@ * }); * // => logs 'x', 'y', and 'z' (property order is not guaranteed across environments) */ - function forIn(object, callback, thisArg) { - if (typeof callback != 'function' || typeof thisArg != 'undefined') { - callback = baseCreateCallback(callback, thisArg, 3); + function forIn(object, iterator, thisArg) { + if (typeof iterator != 'function' || typeof thisArg != 'undefined') { + iterator = baseCallback(iterator, thisArg, 3); } - return baseFor(object, callback, keysIn); + return baseFor(object, iterator, keysIn); } /** @@ -6291,10 +6450,10 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [iterator=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Object} Returns `object`. * @example * @@ -6310,23 +6469,23 @@ * }); * // => logs 'z', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'z' */ - function forInRight(object, callback, thisArg) { - callback = baseCreateCallback(callback, thisArg, 3); - return baseForRight(object, callback, keysIn); + function forInRight(object, iterator, thisArg) { + iterator = baseCallback(iterator, thisArg, 3); + return baseForRight(object, iterator, keysIn); } /** - * Iterates over own enumerable properties of an object executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. + * Iterates over own enumerable properties of an object executing `iterator` + * for each property. The `iterator` is bound to `thisArg` and invoked with + * three arguments; (value, key, object). Iterator functions may exit iteration + * early by explicitly returning `false`. * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [iterator=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Object} Returns `object`. * @example * @@ -6335,11 +6494,11 @@ * }); * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) */ - function forOwn(object, callback, thisArg) { - if (typeof callback != 'function' || typeof thisArg != 'undefined') { - callback = baseCreateCallback(callback, thisArg, 3); + function forOwn(object, iterator, thisArg) { + if (typeof iterator != 'function' || typeof thisArg != 'undefined') { + iterator = baseCallback(iterator, thisArg, 3); } - return baseForOwn(object, callback); + return baseForOwn(object, iterator); } /** @@ -6348,10 +6507,10 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [iterator=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Object} Returns `object`. * @example * @@ -6360,19 +6519,19 @@ * }); * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' */ - function forOwnRight(object, callback, thisArg) { - callback = baseCreateCallback(callback, thisArg, 3); - return baseForRight(object, callback, keys); + function forOwnRight(object, iterator, thisArg) { + iterator = baseCallback(iterator, thisArg, 3); + return baseForRight(object, iterator, keys); } /** - * Creates a sorted array of function property names from all enumerable - * properties, own and inherited, of `object`. + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. * * @static * @memberOf _ * @alias methods - * @category Objects + * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the new sorted array of property names. * @example @@ -6390,7 +6549,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to inspect. * @param {string} key The name of the property to check. * @returns {boolean} Returns `true` if key is a direct property, else `false`. @@ -6411,7 +6570,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to invert. * @param {boolean} [multiValue=false] Allow multiple values per key. * @returns {Object} Returns the new inverted object. @@ -6457,7 +6616,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, else `false`. * @example @@ -6485,7 +6644,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example @@ -6506,7 +6665,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a boolean value, else `false`. * @example @@ -6527,7 +6686,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a date object, else `false`. * @example @@ -6547,7 +6706,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. * @example @@ -6577,7 +6736,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Array|Object|string} value The value to inspect. * @returns {boolean} Returns `true` if `value` is empty, else `false`. * @example @@ -6599,11 +6758,11 @@ */ function isEmpty(value) { var result = true; - if (!value) { + if (value == null) { return result; } var length = value.length; - if ((length > -1 && length <= maxSafeInteger) && + if ((typeof length == 'number' && length > -1 && length <= maxSafeInteger) && (isArray(value) || isString(value) || isArguments(value) || (typeof value == 'object' && isFunction(value.splice)))) { return !length; @@ -6617,23 +6776,23 @@ /** * Performs a deep comparison between two values to determine if they are - * equivalent. If a callback is provided it is executed to compare values. - * If the callback returns `undefined` comparisons are handled by the method - * instead. The callback is bound to `thisArg` and invoked with three arguments; - * (value, other, key). + * equivalent. If `customizer` is provided it is executed to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments; (value, other, key). * * Note: This method supports comparing arrays, booleans, `Date` objects, * numbers, `Object` objects, regexes, and strings. Functions and DOM nodes - * are **not** supported. A callback may be used to extend support for - * comparing other values. + * are **not** supported. A customizer function may be used to extend support + * for comparing other values. * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to compare to `other`. * @param {*} other The value to compare to `value`. - * @param {Function} [callback] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [customizer] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * @@ -6654,10 +6813,10 @@ * }); * // => true */ - function isEqual(value, other, callback, thisArg) { - callback = typeof callback == 'function' && baseCreateCallback(callback, thisArg, 3); + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' && baseCallback(customizer, thisArg, 3); - if (!callback) { + if (!customizer) { // exit early for identical values if (value === other) { // treat `-0` vs. `+0` as not equal @@ -6672,7 +6831,7 @@ return false; } } - return baseIsEqual(value, other, callback); + return baseIsEqual(value, other, customizer); } /** @@ -6681,7 +6840,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an error object, else `false`. * @example @@ -6697,44 +6856,44 @@ } /** - * Checks if `value` is, or can be coerced to, a finite number. + * Checks if `value` is a finite number. * - * Note: This method is not the same as native `isFinite` which returns - * `true` for booleans and empty strings. See the [ES5 spec](http://es5.github.io/#x15.1.2.5) + * Note: This method is based on ES6 `Number.isFinite`. See the + * [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite) * for more details. * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is finite, else `false`. * @example * - * _.isFinite(-101); + * _.isFinite(10); * // => true * * _.isFinite('10'); - * // => true + * // => false * * _.isFinite(true); * // => false * - * _.isFinite(''); + * _.isFinite(Object(10)); * // => false * * _.isFinite(Infinity); * // => false */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } + var isFinite = nativeNumIsFinite || function(value) { + return typeof value == 'number' && nativeIsFinite(value); + }; /** * Checks if `value` is a function. * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example @@ -6765,7 +6924,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example @@ -6795,7 +6954,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. * @example @@ -6823,7 +6982,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `null`, else `false`. * @example @@ -6846,7 +7005,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a number, else `false`. * @example @@ -6875,7 +7034,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example @@ -6914,7 +7073,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a regexp object, else `false`. * @example @@ -6934,7 +7093,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a string, else `false`. * @example @@ -6955,7 +7114,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. * @example @@ -6975,7 +7134,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the array of property names. * @example @@ -6991,15 +7150,17 @@ * // => ['x', 'y'] (property order is not guaranteed across environments) */ var keys = !nativeKeys ? shimKeys : function(object) { - var Ctor = object && object.constructor, - length = object ? object.length : 0; + object = Object(object); + + var Ctor = object.constructor, + length = object.length; if ((Ctor && object === Ctor.prototype) || (typeof length == 'number' && length > 0) || (support.enumPrototypes && typeof object == 'function')) { return shimKeys(object); } - return isObject(object) ? nativeKeys(object) : []; + return nativeKeys(object); }; /** @@ -7007,7 +7168,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the array of property names. * @example @@ -7023,9 +7184,11 @@ * // => ['x', 'y', 'z'] (property order is not guaranteed across environments) */ function keysIn(object) { - if (!isObject(object)) { + if (object == null) { return []; } + object = Object(object); + var length = object.length; length = (typeof length == 'number' && length > 0 && (isArray(object) || (support.nonEnumStrings && isString(object)) || @@ -7076,25 +7239,25 @@ /** * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through the callback. - * The callback is bound to `thisArg` and invoked with three arguments; + * running each own enumerable property of `object` through `iterator`. The + * iterator function is bound to `thisArg` and invoked with three arguments; * (value, key, object). * - * If a property name is provided for `callback` the created "_.pluck" style + * If a property name is provided for `iterator` the created "_.pluck" style * callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback + * If an object is provided for `iterator` the created "_.where" style callback * returns `true` for elements that have the properties of the given object, * else `false`. * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [callback=identity] The function called + * @param {Function|Object|string} [iterator=identity] The function called * per iteration. 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`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {Object} Returns the new mapped object. * @example * @@ -7110,12 +7273,12 @@ * _.mapValues(characters, 'age'); * // => { 'fred': 40, 'pebbles': 1 } */ - function mapValues(object, callback, thisArg) { + function mapValues(object, iterator, thisArg) { var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); + iterator = lodash.callback(iterator, thisArg, 3); baseForOwn(object, function(value, key, object) { - result[key] = callback(value, key, object); + result[key] = iterator(value, key, object); }); return result; } @@ -7123,19 +7286,19 @@ /** * Recursively merges own enumerable properties of the source object(s), that * don't resolve to `undefined` into the destination object. Subsequent sources - * overwrite property assignments of previous sources. If a callback is provided - * it is executed to produce the merged values of the destination and source - * properties. If the callback returns `undefined` merging is handled by the - * method instead. The callback is bound to `thisArg` and invoked with five - * arguments; (objectValue, sourceValue, key, object, source). + * overwrite property assignments of previous sources. If `customizer` is + * provided it is executed to produce the merged values of the destination + * and source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments; (objectValue, sourceValue, key, object, source). * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {Function} [customizer] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `customizer`. * @returns {Object} Returns the destination object. * @example * @@ -7183,7 +7346,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The source object. * @param {Function|...(string|string[])} [predicate] The function called per * iteration or property names to omit, specified as individual property @@ -7201,14 +7364,14 @@ * // => { 'name': 'fred' } */ function omit(object, predicate, thisArg) { - if (!isObject(object)) { + if (object == null) { return {}; } if (typeof predicate == 'function') { - return basePick(object, negate(lodash.createCallback(predicate, thisArg, 3))); + return basePick(object, negate(lodash.callback(predicate, thisArg, 3))); } - var omitProps = baseFlatten(arguments, true, false, 1); - return basePick(object, baseDifference(keysIn(object), arrayMap(omitProps, String))); + var omitProps = baseFlatten(arguments, false, false, 1); + return basePick(Object(object), baseDifference(keysIn(object), arrayMap(omitProps, String))); } /** @@ -7217,7 +7380,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the new array of key-value pairs. * @example @@ -7248,7 +7411,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The source object. * @param {Function|...(string|string[])} [predicate] The function called per * iteration or property names to pick, specified as individual property @@ -7266,29 +7429,29 @@ * // => { 'name': 'fred' } */ function pick(object, predicate, thisArg) { - if (!isObject(object)) { + if (object == null) { return {}; } - return basePick(object, typeof predicate == 'function' - ? lodash.createCallback(predicate, thisArg, 3) - : baseFlatten(arguments, true, false, 1)); + return basePick(Object(object), typeof predicate == 'function' + ? lodash.callback(predicate, thisArg, 3) + : baseFlatten(arguments, false, false, 1)); } /** * An alternative to `_.reduce`; this method transforms `object` to a new * `accumulator` object which is the result of running each of its own - * enumerable properties through a callback, with each callback execution - * potentially mutating the `accumulator` object. The callback is bound to - * `thisArg` and invoked with four arguments; (accumulator, value, key, object). - * Callbacks may exit iteration early by explicitly returning `false`. + * enumerable properties through `iterator`, with each execution potentially + * mutating the `accumulator` object. The `iterator` is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, key, object). Iterator + * functions may exit iteration early by explicitly returning `false`. * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Array|Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. + * @param {Function} [iterator=identity] The function called per iteration. * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `callback`. + * @param {*} [thisArg] The `this` binding of `iterator`. * @returns {*} Returns the accumulated value. * @example * @@ -7305,7 +7468,7 @@ * }); * // => { 'a': 3, 'b': 6, 'c': 9 } */ - function transform(object, callback, accumulator, thisArg) { + function transform(object, iterator, accumulator, thisArg) { var isArr = isArrayLike(object); if (accumulator == null) { if (isArr) { @@ -7318,10 +7481,10 @@ accumulator = baseCreate(proto); } } - if (callback) { - callback = lodash.createCallback(callback, thisArg, 4); + if (iterator) { + iterator = lodash.callback(iterator, thisArg, 4); (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); + return iterator(accumulator, value, index, object); }); } return accumulator; @@ -7332,7 +7495,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the array of property values. * @example @@ -7357,7 +7520,7 @@ * * @static * @memberOf _ - * @category Objects + * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the array of property values. * @example @@ -7384,7 +7547,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to camel case. * @returns {string} Returns the camel cased string. * @example @@ -7410,7 +7573,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to capitalize. * @returns {string} Returns the capitalized string. * @example @@ -7431,7 +7594,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to search. * @param {string} [target] The string to search for. * @param {number} [position=string.length] The position to search from. @@ -7470,7 +7633,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to escape. * @returns {string} Returns the escaped string. * @example @@ -7488,7 +7651,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to escape. * @returns {string} Returns the escaped string. * @example @@ -7507,7 +7670,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to kebab case. * @returns {string} Returns the kebab cased string. * @example @@ -7532,7 +7695,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. @@ -7571,7 +7734,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. @@ -7599,7 +7762,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. @@ -7625,7 +7788,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to repeat. * @param {number} [n=0] The number of times to repeat the string. * @returns {string} Returns the repeated string. @@ -7655,6 +7818,7 @@ n = floor(n / 2); string += string; } while (n); + return result; } @@ -7664,7 +7828,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to snake case. * @returns {string} Returns the snake cased string. * @example @@ -7687,7 +7851,7 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The string to search. * @param {string} [target] The string to search for. * @param {number} [position=0] The position to search from. @@ -7712,12 +7876,10 @@ /** * Creates a compiled template function that can interpolate data properties - * in "interpolate" delimiters, HTML-escaped interpolated data properties in - * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. If - * a data object is provided the interpolated template string is returned. - * Data properties may be accessed as free variables in the template. If a - * settings object is provided it overrides `_.templateSettings` for the - * template. + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it overrides `_.templateSettings` for the template. * * Note: In the development build, `_.template` utilizes sourceURLs for easier debugging. * See the [HTML5 Rocks article on sourcemaps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) @@ -7731,9 +7893,8 @@ * * @static * @memberOf _ - * @category Strings + * @category String * @param {string} [string=''] The template string. - * @param {Object} [data] The data object used to populate the template string. * @param {Object} [options] The options object. * @param {RegExp} [options.escape] The HTML "escape" delimiter. * @param {RegExp} [options.evaluate] The "evaluate" delimiter. @@ -7741,8 +7902,7 @@ * @param {RegExp} [options.interpolate] The "interpolate" delimiter. * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. * @param {string} [options.variable] The data object variable name. - * @returns {Function|string} Returns the interpolated string if a data object - * is provided, else the compiled template function. + * @returns {Function} Returns the compiled template function. * @example * * // using the "interpolate" delimiter to create a compiled template @@ -7751,39 +7911,44 @@ * // => 'hello fred' * * // using the HTML "escape" delimiter to escape data property values - * _.template('<%- value %>', { 'value': '