/**
* @license
- * lodash 4.11.2 <https://lodash.com/>
- * Copyright jQuery Foundation and other contributors <https://jquery.org/>
- * Released under MIT license <https://lodash.com/license>
+ * lodash 4.5.1 <https://lodash.com/>
+ * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
- * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license <https://lodash.com/license>
*/
;(function() {
var undefined;
/** Used as the semantic version number. */
- var VERSION = '4.11.2';
-
- /** Used as the size to enable large array optimizations. */
- var LARGE_ARRAY_SIZE = 200;
-
- /** Used as the `TypeError` message for "Functions" methods. */
- var FUNC_ERROR_TEXT = 'Expected a function';
-
- /** Used to stand-in for `undefined` hash values. */
- var HASH_UNDEFINED = '__lodash_hash_undefined__';
-
- /** Used as the internal argument placeholder. */
- var PLACEHOLDER = '__lodash_placeholder__';
+ var VERSION = '4.5.1';
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
var HOT_COUNT = 150,
HOT_SPAN = 16;
+ /** Used as the size to enable large array optimizations. */
+ var LARGE_ARRAY_SIZE = 200;
+
/** Used to indicate the type of lazy iteratees. */
var LAZY_FILTER_FLAG = 1,
LAZY_MAP_FLAG = 2,
LAZY_WHILE_FLAG = 3;
+ /** Used as the `TypeError` message for "Functions" methods. */
+ var FUNC_ERROR_TEXT = 'Expected a function';
+
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0,
MAX_SAFE_INTEGER = 9007199254740991,
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
+ /** Used as the internal argument placeholder. */
+ var PLACEHOLDER = '__lodash_placeholder__';
+
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
- promiseTag = '[object Promise]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakSetTag = '[object WeakSet]';
var arrayBufferTag = '[object ArrayBuffer]',
- dataViewTag = '[object DataView]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
reIsPlainProp = /^\w*$/,
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
- /**
- * Used to match `RegExp`
- * [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns).
- */
+ /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
reHasRegExpChar = RegExp(reRegExpChar.source);
reTrimStart = /^\s+/,
reTrimEnd = /\s+$/;
- /** Used to match non-compound words composed of alphanumeric characters. */
- var reBasicWord = /[a-zA-Z0-9]+/g;
-
/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;
- /**
- * Used to match
- * [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components).
- */
+ /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
/** Used to match `RegExp` flags from their coerced string values. */
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
- /** Used to detect host constructors (Safari). */
+ /** Used to detect host constructors (Safari > 5). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
/** Used to detect octal string values. */
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
- rsPunctuationRange = '\\u2000-\\u206f',
+ rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
rsVarRange = '\\ufe0e\\ufe0f',
- rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
+ rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
/** Used to compose unicode capture groups. */
- var rsApos = "['\u2019]",
- rsAstral = '[' + rsAstralRange + ']',
+ var rsAstral = '[' + rsAstralRange + ']',
rsBreak = '[' + rsBreakRange + ']',
rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
rsDigits = '\\d+',
/** Used to compose unicode regexes. */
var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
- rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
- rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
reOptMod = rsModifier + '?',
rsOptVar = '[' + rsVarRange + ']?',
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
- /** Used to match apostrophes. */
- var reApos = RegExp(rsApos, 'g');
-
/**
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
+ /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+ var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
+
+ /** Used to match non-compound words composed of alphanumeric characters. */
+ var reBasicWord = /[a-zA-Z0-9]+/g;
+
/** Used to match complex or compound words. */
var reComplexWord = RegExp([
- rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
- rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
- rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,
- rsUpper + '+' + rsOptUpperContr,
+ rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
+ rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
+ rsUpper + '?' + rsLowerMisc + '+',
+ rsUpper + '+',
rsDigits,
rsEmoji
].join('|'), 'g');
- /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
- var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
-
/** Used to detect strings that need a more robust regexp to match words. */
- var reHasComplexWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
+ var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
/** Used to assign default `context` object properties. */
var contextProps = [
- 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
+ 'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
- 'Promise', 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError',
- 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
- '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
+ 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
+ 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
+ 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
];
/** Used to make template sourceURLs easier to identify. */
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
- typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
- typedArrayTags[errorTag] = typedArrayTags[funcTag] =
- typedArrayTags[mapTag] = typedArrayTags[numberTag] =
- typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
- typedArrayTags[setTag] = typedArrayTags[stringTag] =
- typedArrayTags[weakMapTag] = false;
+ typedArrayTags[dateTag] = typedArrayTags[errorTag] =
+ typedArrayTags[funcTag] = typedArrayTags[mapTag] =
+ typedArrayTags[numberTag] = typedArrayTags[objectTag] =
+ typedArrayTags[regexpTag] = typedArrayTags[setTag] =
+ typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
/** Used to identify `toStringTag` values supported by `_.clone`. */
var cloneableTags = {};
cloneableTags[argsTag] = cloneableTags[arrayTag] =
- cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
- cloneableTags[boolTag] = cloneableTags[dateTag] =
- cloneableTags[float32Tag] = cloneableTags[float64Tag] =
- cloneableTags[int8Tag] = cloneableTags[int16Tag] =
- cloneableTags[int32Tag] = cloneableTags[mapTag] =
- cloneableTags[numberTag] = cloneableTags[objectTag] =
- cloneableTags[regexpTag] = cloneableTags[setTag] =
- cloneableTags[stringTag] = cloneableTags[symbolTag] =
- cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
- cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+ cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
+ cloneableTags[dateTag] = cloneableTags[float32Tag] =
+ cloneableTags[float64Tag] = cloneableTags[int8Tag] =
+ cloneableTags[int16Tag] = cloneableTags[int32Tag] =
+ cloneableTags[mapTag] = cloneableTags[numberTag] =
+ cloneableTags[objectTag] = cloneableTags[regexpTag] =
+ cloneableTags[setTag] = cloneableTags[stringTag] =
+ cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
+ cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
+ cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] =
cloneableTags[weakMapTag] = false;
* @returns {Object} Returns `map`.
*/
function addMapEntry(map, pair) {
- // Don't return `Map#set` because it doesn't return the map instance in IE 11.
map.set(pair[0], pair[1]);
return map;
}
* @private
* @param {Function} func The function to invoke.
* @param {*} thisArg The `this` binding of `func`.
- * @param {Array} args The arguments to invoke `func` with.
+ * @param {...*} args The arguments to invoke `func` with.
* @returns {*} Returns the result of `func`.
*/
function apply(func, thisArg, args) {
* @private
* @param {Array} array The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
*/
function arrayEvery(array, predicate) {
var index = -1,
function arrayFilter(array, predicate) {
var index = -1,
length = array.length,
- resIndex = 0,
+ resIndex = -1,
result = [];
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
- result[resIndex++] = value;
+ result[++resIndex] = value;
}
}
return result;
}
/**
- * This function is like `arrayIncludes` except that it accepts a comparator.
+ * A specialized version of `_.includesWith` for arrays without support for
+ * specifying an index to search from.
*
* @private
* @param {Array} array The array to search.
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {boolean} [initAccum] Specify using the first element of `array` as
- * the initial value.
+ * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduce(array, iteratee, accumulator, initAccum) {
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {boolean} [initAccum] Specify using the last element of `array` as
- * the initial value.
+ * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduceRight(array, iteratee, accumulator, initAccum) {
* @private
* @param {Array} array The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
*/
function arraySome(array, predicate) {
var index = -1,
}
/**
+ * The base implementation of methods like `_.max` and `_.min` which accepts a
+ * `comparator` to determine the extremum value.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The iteratee invoked per iteration.
+ * @param {Function} comparator The comparator used to compare values.
+ * @returns {*} Returns the extremum value.
+ */
+ function baseExtremum(array, iteratee, comparator) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var value = array[index],
+ current = iteratee(value);
+
+ if (current != null && (computed === undefined
+ ? current === current
+ : comparator(current, computed)
+ )) {
+ var computed = current,
+ result = value;
+ }
+ }
+ return result;
+ }
+
+ /**
* The base implementation of methods like `_.find` and `_.findKey`, without
* support for iteratee shorthands, which iterates over `collection` using
* `eachFunc`.
* @param {Array|Object} collection The collection to search.
* @param {Function} predicate The function invoked per iteration.
* @param {Function} eachFunc The function to iterate over `collection`.
- * @param {boolean} [retKey] Specify returning the key of the found element
- * instead of the element itself.
+ * @param {boolean} [retKey] 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) {
}
/**
- * This function is like `baseIndexOf` except that it accepts a comparator.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} fromIndex The index to search from.
- * @param {Function} comparator The comparator invoked per element.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
- function baseIndexOfWith(array, value, fromIndex, comparator) {
- var index = fromIndex - 1,
- length = array.length;
-
- while (++index < length) {
- if (comparator(array[index], value)) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * The base implementation of `_.mean` and `_.meanBy` without support for
- * iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {number} Returns the mean.
- */
- function baseMean(array, iteratee) {
- var length = array ? array.length : 0;
- return length ? (baseSum(array, iteratee) / length) : NAN;
- }
-
- /**
* The base implementation of `_.reduce` and `_.reduceRight`, without support
* for iteratee shorthands, which iterates over `collection` using `eachFunc`.
*
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} accumulator The initial value.
- * @param {boolean} initAccum Specify using the first or last element of
- * `collection` as the initial value.
+ * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
* @param {Function} eachFunc The function to iterate over `collection`.
* @returns {*} Returns the accumulated value.
*/
}
/**
- * The base implementation of `_.sortBy` which uses `comparer` to define the
- * sort order of `array` and replaces criteria objects with their corresponding
- * values.
+ * The base implementation of `_.sortBy` which uses `comparer` to define
+ * the sort order of `array` and replaces criteria objects with their
+ * corresponding values.
*
* @private
* @param {Array} array The array to sort.
}
/**
- * The base implementation of `_.sum` and `_.sumBy` without support for
- * iteratee shorthands.
+ * The base implementation of `_.sum` without support for iteratee shorthands.
*
* @private
* @param {Array} array The array to iterate over.
}
/**
+ * Compares values to sort them in ascending order.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {number} Returns the sort order indicator for `value`.
+ */
+ function compareAscending(value, other) {
+ if (value !== other) {
+ var valIsNull = value === null,
+ valIsUndef = value === undefined,
+ valIsReflexive = value === value;
+
+ var othIsNull = other === null,
+ othIsUndef = other === undefined,
+ othIsReflexive = other === other;
+
+ if ((value > other && !othIsNull) || !valIsReflexive ||
+ (valIsNull && !othIsUndef && othIsReflexive) ||
+ (valIsUndef && othIsReflexive)) {
+ return 1;
+ }
+ if ((value < other && !valIsNull) || !othIsReflexive ||
+ (othIsNull && !valIsUndef && valIsReflexive) ||
+ (othIsUndef && valIsReflexive)) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Used by `_.orderBy` to compare multiple properties of a value to another
+ * and stable sort them.
+ *
+ * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
+ * specify an order of "desc" for descending or "asc" for ascending sort order
+ * of corresponding values.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {boolean[]|string[]} orders The order to sort by for each property.
+ * @returns {number} Returns the sort order indicator for `object`.
+ */
+ function compareMultiple(object, other, orders) {
+ var index = -1,
+ objCriteria = object.criteria,
+ othCriteria = other.criteria,
+ length = objCriteria.length,
+ ordersLength = orders.length;
+
+ while (++index < length) {
+ var result = compareAscending(objCriteria[index], othCriteria[index]);
+ if (result) {
+ if (index >= ordersLength) {
+ return result;
+ }
+ var order = orders[index];
+ return result * (order == 'desc' ? -1 : 1);
+ }
+ }
+ // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
+ // that causes it, under certain circumstances, to provide the same value for
+ // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
+ // for more details.
+ //
+ // This also ensures a stable sort in V8 and other engines.
+ // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
+ return object.index - other.index;
+ }
+
+ /**
* Gets the number of `placeholder` occurrences in `array`.
*
* @private
}
/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+ function isIndex(value, length) {
+ value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+ length = length == null ? MAX_SAFE_INTEGER : length;
+ return value > -1 && value % 1 == 0 && value < length;
+ }
+
+ /**
* Converts `iterator` to an array.
*
* @private
function replaceHolders(array, placeholder) {
var index = -1,
length = array.length,
- resIndex = 0,
+ resIndex = -1,
result = [];
while (++index < length) {
var value = array[index];
if (value === placeholder || value === PLACEHOLDER) {
array[index] = PLACEHOLDER;
- result[resIndex++] = index;
+ result[++resIndex] = index;
}
}
return result;
*
* @static
* @memberOf _
- * @since 1.1.0
* @category Util
* @param {Object} [context=root] The context object.
* @returns {Function} Returns a new `lodash` function.
/** Used for built-in method references. */
var arrayProto = context.Array.prototype,
- objectProto = context.Object.prototype,
- stringProto = context.String.prototype;
+ objectProto = context.Object.prototype;
/** Used to resolve the decompiled source of functions. */
var funcToString = context.Function.prototype.toString;
var objectCtorString = funcToString.call(Object);
/**
- * Used to resolve the
- * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
Uint8Array = context.Uint8Array,
clearTimeout = context.clearTimeout,
enumerate = Reflect ? Reflect.enumerate : undefined,
+ getPrototypeOf = Object.getPrototypeOf,
getOwnPropertySymbols = Object.getOwnPropertySymbols,
iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
objectCreate = Object.create,
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeCeil = Math.ceil,
nativeFloor = Math.floor,
- nativeGetPrototype = Object.getPrototypeOf,
nativeIsFinite = context.isFinite,
nativeJoin = arrayProto.join,
nativeKeys = Object.keys,
nativeMin = Math.min,
nativeParseInt = context.parseInt,
nativeRandom = Math.random,
- nativeReplace = stringProto.replace,
- nativeReverse = arrayProto.reverse,
- nativeSplit = stringProto.split;
+ nativeReverse = arrayProto.reverse;
/* Built-in method references that are verified to be native. */
- var DataView = getNative(context, 'DataView'),
- Map = getNative(context, 'Map'),
- Promise = getNative(context, 'Promise'),
+ var Map = getNative(context, 'Map'),
Set = getNative(context, 'Set'),
WeakMap = getNative(context, 'WeakMap'),
nativeCreate = getNative(Object, 'create');
/** Used to store function metadata. */
var metaMap = WeakMap && new WeakMap;
- /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */
- var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');
-
- /** Used to lookup unminified function names. */
- var realNames = {};
-
/** Used to detect maps, sets, and weakmaps. */
- var dataViewCtorString = toSource(DataView),
- mapCtorString = toSource(Map),
- promiseCtorString = toSource(Promise),
- setCtorString = toSource(Set),
- weakMapCtorString = toSource(WeakMap);
+ var mapCtorString = Map ? funcToString.call(Map) : '',
+ setCtorString = Set ? funcToString.call(Set) : '',
+ weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : '';
/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol ? Symbol.prototype : undefined,
- symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
- symbolToString = symbolProto ? symbolProto.toString : undefined;
+ symbolValueOf = Symbol ? symbolProto.valueOf : undefined,
+ symbolToString = Symbol ? symbolProto.toString : undefined;
+
+ /** Used to lookup unminified function names. */
+ var realNames = {};
/*------------------------------------------------------------------------*/
/**
* Creates a `lodash` object which wraps `value` to enable implicit method
- * chain sequences. Methods that operate on and return arrays, collections,
- * and functions can be chained together. Methods that retrieve a single value
- * or may return a primitive value will automatically end the chain sequence
- * and return the unwrapped value. Otherwise, the value must be unwrapped
- * with `_#value`.
+ * chaining. Methods that operate on and return arrays, collections, and
+ * functions can be chained together. Methods that retrieve a single value or
+ * may return a primitive value will automatically end the chain sequence and
+ * return the unwrapped value. Otherwise, the value must be unwrapped with
+ * `_#value`.
*
- * Explicit chain sequences, which must be unwrapped with `_#value`, may be
- * enabled using `_.chain`.
+ * Explicit chaining, which must be unwrapped with `_#value` in all cases,
+ * may be enabled using `_.chain`.
*
* The execution of chained methods is lazy, that is, it's deferred until
* `_#value` is implicitly or explicitly called.
*
- * Lazy evaluation allows several methods to support shortcut fusion.
- * Shortcut fusion is an optimization to merge iteratee calls; this avoids
- * the creation of intermediate arrays and can greatly reduce the number of
- * iteratee executions. Sections of a chain sequence qualify for shortcut
- * fusion if the section is applied to an array of at least `200` elements
- * and any iteratees accept only one argument. The heuristic for whether a
- * section qualifies for shortcut fusion is subject to change.
+ * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
+ * fusion is an optimization to merge iteratee calls; this avoids the creation
+ * of intermediate arrays and can greatly reduce the number of iteratee executions.
+ * Sections of a chain sequence qualify for shortcut fusion if the section is
+ * applied to an array of at least two hundred elements and any iteratees
+ * accept only one argument. The heuristic for whether a section qualifies
+ * for shortcut fusion is subject to change.
*
* Chaining is supported in custom builds as long as the `_#value` method is
* directly or indirectly included in the build.
* `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
* `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
* `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
- * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
- * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
- * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
- * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
- * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
- * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
- * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
- * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
- * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
- * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
- * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
- * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
- * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
- * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
- * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
- * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
- * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
- * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
- * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
- * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
- * `zipObject`, `zipObjectDeep`, and `zipWith`
+ * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
+ * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
+ * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`,
+ * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`,
+ * `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`,
+ * `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`,
+ * `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`,
+ * `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`,
+ * `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`,
+ * `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`,
+ * `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`,
+ * `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`,
+ * `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`,
+ * `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`,
+ * `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`,
+ * `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`,
+ * `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`,
+ * `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`,
+ * `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith`
*
* The wrapper methods that are **not** chainable by default are:
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
- * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `divide`, `each`,
- * `eachRight`, `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`,
- * `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`,
- * `floor`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
- * `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`,
- * `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`,
- * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`,
- * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
- * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`,
- * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
+ * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
+ * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
+ * `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`, `forIn`,
+ * `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`,
+ * `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`,
+ * `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
+ * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
+ * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`,
+ * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
* `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
* `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`,
* `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`,
- * `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `multiply`,
- * `noConflict`, `noop`, `now`, `nth`, `pad`, `padEnd`, `padStart`, `parseInt`,
- * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
- * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
- * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
- * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toInteger`,
- * `toJSON`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, `toString`,
- * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`,
- * `uniqueId`, `upperCase`, `upperFirst`, `value`, and `words`
+ * `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`,
+ * `now`, `pad`, `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`,
+ * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `sample`,
+ * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`,
+ * `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`,
+ * `sum`, `sumBy`, `template`, `times`, `toLower`, `toInteger`, `toLength`,
+ * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`,
+ * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`,
+ * `value`, and `words`
*
* @name _
* @constructor
}
/**
- * The function whose prototype chain sequence wrappers inherit from.
+ * The function whose prototype all chaining wrappers inherit from.
*
* @private
*/
*
* @private
* @param {*} value The value to wrap.
- * @param {boolean} [chainAll] Enable explicit method chain sequences.
+ * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
*/
function LodashWrapper(value, chainAll) {
this.__wrapped__ = value;
}
};
- // Ensure wrappers are instances of `baseLodash`.
- lodash.prototype = baseLodash.prototype;
- lodash.prototype.constructor = lodash;
-
- LodashWrapper.prototype = baseCreate(baseLodash.prototype);
- LodashWrapper.prototype.constructor = LodashWrapper;
-
/*------------------------------------------------------------------------*/
/**
return result;
}
- // Ensure `LazyWrapper` is an instance of `baseLodash`.
- LazyWrapper.prototype = baseCreate(baseLodash.prototype);
- LazyWrapper.prototype.constructor = LazyWrapper;
-
/*------------------------------------------------------------------------*/
/**
- * Creates a hash object.
+ * Creates an hash object.
*
* @private
* @constructor
hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
}
- // Avoid inheriting from `Object.prototype` when possible.
- Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
-
/*------------------------------------------------------------------------*/
/**
* @memberOf MapCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
- * @returns {Object} Returns the map cache instance.
+ * @returns {Object} Returns the map cache object.
*/
function mapSet(key, value) {
var data = this.__data__;
return this;
}
- // Add methods to `MapCache`.
- MapCache.prototype.clear = mapClear;
- MapCache.prototype['delete'] = mapDelete;
- MapCache.prototype.get = mapGet;
- MapCache.prototype.has = mapHas;
- MapCache.prototype.set = mapSet;
-
/*------------------------------------------------------------------------*/
/**
}
}
- // Add methods to `SetCache`.
- SetCache.prototype.push = cachePush;
-
/*------------------------------------------------------------------------*/
/**
* @memberOf Stack
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
- * @returns {Object} Returns the stack cache instance.
+ * @returns {Object} Returns the stack cache object.
*/
function stackSet(key, value) {
var data = this.__data__,
return this;
}
- // Add methods to `Stack`.
- Stack.prototype.clear = stackClear;
- Stack.prototype['delete'] = stackDelete;
- Stack.prototype.get = stackGet;
- Stack.prototype.has = stackHas;
- Stack.prototype.set = stackSet;
-
/*------------------------------------------------------------------------*/
/**
* Removes `key` and its value from the associative array.
*
* @private
- * @param {Array} array The array to modify.
+ * @param {Array} array The array to query.
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
}
/**
- * Gets the index at which the `key` is found in `array` of key-value pairs.
+ * Gets the index at which the first occurrence of `key` is found in `array`
+ * of key-value pairs.
*
* @private
* @param {Array} array The array to search.
}
/**
- * This function is like `assignValue` except that it doesn't assign
- * `undefined` values.
+ * This function is like `assignValue` except that it doesn't assign `undefined` values.
*
* @private
* @param {Object} object The object to modify.
}
/**
+ * Casts `value` to an empty array if it's not an array like object.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Array} Returns the array-like object.
+ */
+ function baseCastArrayLikeObject(value) {
+ return isArrayLikeObject(value) ? value : [];
+ }
+
+ /**
+ * Casts `value` to `identity` if it's not a function.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Array} Returns the array-like object.
+ */
+ function baseCastFunction(value) {
+ return typeof value == 'function' ? value : identity;
+ }
+
+ /**
+ * Casts `value` to a path array if it's not one.
+ *
+ * @private
+ * @param {*} value The value to inspect.
+ * @returns {Array} Returns the cast property path array.
+ */
+ function baseCastPath(value) {
+ return isArray(value) ? value : stringToPath(value);
+ }
+
+ /**
* The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
*
* @private
* @private
* @param {*} value The value to clone.
* @param {boolean} [isDeep] Specify a deep clone.
- * @param {boolean} [isFull] Specify a clone including symbols.
* @param {Function} [customizer] The function to customize cloning.
* @param {string} [key] The key of `value`.
* @param {Object} [object] The parent object of `value`.
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
* @returns {*} Returns the cloned value.
*/
- function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
+ function baseClone(value, isDeep, customizer, key, object, stack) {
var result;
if (customizer) {
result = object ? customizer(value, key, object, stack) : customizer(value);
if (!cloneableTags[tag]) {
return object ? value : {};
}
- result = initCloneByTag(value, tag, baseClone, isDeep);
+ result = initCloneByTag(value, tag, isDeep);
}
}
// Check for circular references and return its corresponding clone.
}
stack.set(value, result);
- if (!isArr) {
- var props = isFull ? getAllKeys(value) : keys(value);
- }
// Recursively populate clone (susceptible to call stack limits).
- arrayEach(props || value, function(subValue, key) {
- if (props) {
- key = subValue;
- subValue = value[key];
- }
- assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
+ (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
+ assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
});
- return result;
+ return isArr ? result : copySymbols(value, result);
}
/**
predicate = source[key],
value = object[key];
- if ((value === undefined &&
- !(key in Object(object))) || !predicate(value)) {
+ if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
return false;
}
}
}
/**
- * The base implementation of methods like `_.difference` without support
- * for excluding multiple arrays or iteratee shorthands.
+ * The base implementation of methods like `_.difference` without support for
+ * excluding multiple arrays or iteratee shorthands.
*
* @private
* @param {Array} array The array to inspect.
var value = array[index],
computed = iteratee ? iteratee(value) : value;
- value = (comparator || value !== 0) ? value : 0;
if (isCommon && computed === computed) {
var valuesIndex = valuesLength;
while (valuesIndex--) {
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
*/
function baseEvery(collection, predicate) {
var result = true;
}
/**
- * The base implementation of methods like `_.max` and `_.min` which accepts a
- * `comparator` to determine the extremum value.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The iteratee invoked per iteration.
- * @param {Function} comparator The comparator used to compare values.
- * @returns {*} Returns the extremum value.
- */
- function baseExtremum(array, iteratee, comparator) {
- var index = -1,
- length = array.length;
-
- while (++index < length) {
- var value = array[index],
- current = iteratee(value);
-
- if (current != null && (computed === undefined
- ? (current === current && !isSymbol(current))
- : comparator(current, computed)
- )) {
- var computed = current,
- result = value;
- }
- }
- return result;
- }
-
- /**
* The base implementation of `_.fill` without an iteratee call guard.
*
* @private
* @private
* @param {Array} array The array to flatten.
* @param {number} depth The maximum recursion depth.
- * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
- * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
+ * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
* @param {Array} [result=[]] The initial result value.
* @returns {Array} Returns the new flattened array.
*/
- function baseFlatten(array, depth, predicate, isStrict, result) {
+ function baseFlatten(array, depth, isStrict, result) {
+ result || (result = []);
+
var index = -1,
length = array.length;
- predicate || (predicate = isFlattenable);
- result || (result = []);
-
while (++index < length) {
var value = array[index];
- if (depth > 0 && predicate(value)) {
+ if (depth > 0 && isArrayLikeObject(value) &&
+ (isStrict || isArray(value) || isArguments(value))) {
if (depth > 1) {
// Recursively flatten arrays (susceptible to call stack limits).
- baseFlatten(value, depth - 1, predicate, isStrict, result);
+ baseFlatten(value, depth - 1, isStrict, result);
} else {
arrayPush(result, value);
}
}
/**
- * The base implementation of `baseForOwn` which iterates over `object`
- * properties returned by `keysFunc` and invokes `iteratee` for each property.
- * Iteratee functions may exit iteration early by explicitly returning `false`.
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
*
* @private
* @param {Object} object The object to iterate over.
var baseForRight = createBaseFor(true);
/**
+ * The base implementation of `_.forIn` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+ function baseForIn(object, iteratee) {
+ return object == null ? object : baseFor(object, iteratee, keysIn);
+ }
+
+ /**
* The base implementation of `_.forOwn` without support for iteratee shorthands.
*
* @private
* @returns {*} Returns the resolved value.
*/
function baseGet(object, path) {
- path = isKey(path, object) ? [path] : castPath(path);
+ path = isKey(path, object) ? [path + ''] : baseCastPath(path);
var index = 0,
length = path.length;
while (object != null && index < length) {
- object = object[toKey(path[index++])];
+ object = object[path[index++]];
}
return (index && index == length) ? object : undefined;
}
/**
- * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
- * `keysFunc` and `symbolsFunc` to get the enumerable property names and
- * symbols of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Function} keysFunc The function to get the keys of `object`.
- * @param {Function} symbolsFunc The function to get the symbols of `object`.
- * @returns {Array} Returns the array of property names and symbols.
- */
- function baseGetAllKeys(object, keysFunc, symbolsFunc) {
- var result = keysFunc(object);
- return isArray(object)
- ? result
- : arrayPush(result, symbolsFunc(object));
- }
-
- /**
- * The base implementation of `_.gt` which doesn't coerce arguments to numbers.
- *
- * @private
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if `value` is greater than `other`,
- * else `false`.
- */
- function baseGt(value, other) {
- return value > other;
- }
-
- /**
* The base implementation of `_.has` without support for deep paths.
*
* @private
// that are composed entirely of index properties, return `false` for
// `hasOwnProperty` checks of them.
return hasOwnProperty.call(object, key) ||
- (typeof object == 'object' && key in object && getPrototype(object) === null);
+ (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
}
/**
*/
function baseIntersection(arrays, iteratee, comparator) {
var includes = comparator ? arrayIncludesWith : arrayIncludes,
- length = arrays[0].length,
othLength = arrays.length,
othIndex = othLength,
caches = Array(othLength),
- maxLength = Infinity,
result = [];
while (othIndex--) {
if (othIndex && iteratee) {
array = arrayMap(array, baseUnary(iteratee));
}
- maxLength = nativeMin(array.length, maxLength);
- caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
+ caches[othIndex] = !comparator && (iteratee || array.length >= 120)
? new SetCache(othIndex && array)
: undefined;
}
array = arrays[0];
var index = -1,
+ length = array.length,
seen = caches[0];
outer:
- while (++index < length && result.length < maxLength) {
+ while (++index < length) {
var value = array[index],
computed = iteratee ? iteratee(value) : value;
- value = (comparator || value !== 0) ? value : 0;
if (!(seen
? cacheHas(seen, computed)
: includes(result, computed, comparator)
)) {
- othIndex = othLength;
+ var othIndex = othLength;
while (--othIndex) {
var cache = caches[othIndex];
if (!(cache
*/
function baseInvoke(object, path, args) {
if (!isKey(path, object)) {
- path = castPath(path);
+ path = baseCastPath(path);
object = parent(object, path);
path = last(path);
}
- var func = object == null ? object : object[toKey(path)];
+ var func = object == null ? object : object[path];
return func == null ? undefined : apply(func, object, args);
}
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Function} [customizer] The function to customize comparisons.
- * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`
- * for more details.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
* @param {Object} [stack] Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
if (!objIsArr) {
objTag = getTag(object);
- objTag = objTag == argsTag ? objectTag : objTag;
+ if (objTag == argsTag) {
+ objTag = objectTag;
+ } else if (objTag != objectTag) {
+ objIsArr = isTypedArray(object);
+ }
}
if (!othIsArr) {
othTag = getTag(other);
- othTag = othTag == argsTag ? objectTag : othTag;
+ if (othTag == argsTag) {
+ othTag = objectTag;
+ } else if (othTag != objectTag) {
+ othIsArr = isTypedArray(other);
+ }
}
var objIsObj = objTag == objectTag && !isHostObject(object),
othIsObj = othTag == objectTag && !isHostObject(other),
isSameTag = objTag == othTag;
- if (isSameTag && !objIsObj) {
- stack || (stack = new Stack);
- return (objIsArr || isTypedArray(object))
- ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)
- : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);
+ if (isSameTag && !(objIsArr || objIsObj)) {
+ return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
}
- if (!(bitmask & PARTIAL_COMPARE_FLAG)) {
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
+ if (!isPartial) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
- var objUnwrapped = objIsWrapped ? object.value() : object,
- othUnwrapped = othIsWrapped ? other.value() : other;
-
- stack || (stack = new Stack);
- return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);
+ return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
}
}
if (!isSameTag) {
return false;
}
stack || (stack = new Stack);
- return equalObjects(object, other, equalFunc, customizer, bitmask, stack);
+ return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
}
/**
return false;
}
} else {
- var stack = new Stack;
- if (customizer) {
- var result = customizer(objValue, srcValue, key, object, source, stack);
- }
+ var stack = new Stack,
+ result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
+
if (!(result === undefined
? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
: result
* @returns {Function} Returns the iteratee.
*/
function baseIteratee(value) {
- // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
- // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
- if (typeof value == 'function') {
+ var type = typeof value;
+ if (type == 'function') {
return value;
}
if (value == null) {
return identity;
}
- if (typeof value == 'object') {
+ if (type == 'object') {
return isArray(value)
? baseMatchesProperty(value[0], value[1])
: baseMatches(value);
}
/**
- * The base implementation of `_.lt` which doesn't coerce arguments to numbers.
- *
- * @private
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if `value` is less than `other`,
- * else `false`.
- */
- function baseLt(value, other) {
- return value < other;
- }
-
- /**
* The base implementation of `_.map` without support for iteratee shorthands.
*
* @private
function baseMatches(source) {
var matchData = getMatchData(source);
if (matchData.length == 1 && matchData[0][2]) {
- return matchesStrictComparable(matchData[0][0], matchData[0][1]);
+ var key = matchData[0][0],
+ value = matchData[0][1];
+
+ return function(object) {
+ if (object == null) {
+ return false;
+ }
+ return object[key] === value &&
+ (value !== undefined || (key in Object(object)));
+ };
}
return function(object) {
return object === source || baseIsMatch(object, source, matchData);
* @returns {Function} Returns the new function.
*/
function baseMatchesProperty(path, srcValue) {
- if (isKey(path) && isStrictComparable(srcValue)) {
- return matchesStrictComparable(toKey(path), srcValue);
- }
return function(object) {
var objValue = get(object, path);
return (objValue === undefined && objValue === srcValue)
* @param {Object} source The source object.
* @param {number} srcIndex The index of `source`.
* @param {Function} [customizer] The function to customize merged values.
- * @param {Object} [stack] Tracks traversed source values and their merged
- * counterparts.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
function baseMerge(object, source, srcIndex, customizer, stack) {
if (object === source) {
return;
}
- if (!(isArray(source) || isTypedArray(source))) {
- var props = keysIn(source);
- }
+ var props = (isArray(source) || isTypedArray(source))
+ ? undefined
+ : keysIn(source);
+
arrayEach(props || source, function(srcValue, key) {
if (props) {
key = srcValue;
* @param {number} srcIndex The index of `source`.
* @param {Function} mergeFunc The function to merge values.
* @param {Function} [customizer] The function to customize assigned values.
- * @param {Object} [stack] Tracks traversed source values and their merged
- * counterparts.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
var objValue = object[key],
// Recursively merge objects and arrays (susceptible to call stack limits).
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
}
- stack['delete'](srcValue);
assignMergeValue(object, key, newValue);
}
/**
- * The base implementation of `_.nth` which doesn't coerce `n` to an integer.
- *
- * @private
- * @param {Array} array The array to query.
- * @param {number} n The index of the element to return.
- * @returns {*} Returns the nth element of `array`.
- */
- function baseNth(array, n) {
- var length = array.length;
- if (!length) {
- return;
- }
- n += n < 0 ? length : 0;
- return isIndex(n, length) ? array[n] : undefined;
- }
-
- /**
* The base implementation of `_.orderBy` without param guards.
*
* @private
* @returns {Array} Returns the new sorted array.
*/
function baseOrderBy(collection, iteratees, orders) {
- var index = -1;
- iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
+ var index = -1,
+ toIteratee = getIteratee();
+
+ iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
+ return toIteratee(iteratee);
+ });
var result = baseMap(collection, function(value, key, collection) {
var criteria = arrayMap(iteratees, function(iteratee) {
/**
* The base implementation of `_.pick` without support for individual
- * property identifiers.
+ * property names.
*
* @private
* @param {Object} object The source object.
- * @param {string[]} props The property identifiers to pick.
+ * @param {string[]} props The property names to pick.
* @returns {Object} Returns the new object.
*/
function basePick(object, props) {
* @returns {Object} Returns the new object.
*/
function basePickBy(object, predicate) {
- var index = -1,
- props = getAllKeysIn(object),
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index],
- value = object[key];
-
+ var result = {};
+ baseForIn(object, function(value, key) {
if (predicate(value, key)) {
result[key] = value;
}
- }
+ });
return result;
}
}
/**
+ * The base implementation of `_.pullAll`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @returns {Array} Returns `array`.
+ */
+ function basePullAll(array, values) {
+ return basePullAllBy(array, values);
+ }
+
+ /**
* The base implementation of `_.pullAllBy` without support for iteratee
* shorthands.
*
* @param {Array} array The array to modify.
* @param {Array} values The values to remove.
* @param {Function} [iteratee] The iteratee invoked per element.
- * @param {Function} [comparator] The comparator invoked per element.
* @returns {Array} Returns `array`.
*/
- function basePullAll(array, values, iteratee, comparator) {
- var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
- index = -1,
+ function basePullAllBy(array, values, iteratee) {
+ var index = -1,
length = values.length,
seen = array;
if (iteratee) {
- seen = arrayMap(array, baseUnary(iteratee));
+ seen = arrayMap(array, function(value) { return iteratee(value); });
}
while (++index < length) {
var fromIndex = 0,
value = values[index],
computed = iteratee ? iteratee(value) : value;
- while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
+ while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
if (seen !== array) {
splice.call(seen, fromIndex, 1);
}
while (length--) {
var index = indexes[length];
- if (length == lastIndex || index !== previous) {
+ if (lastIndex == length || index != previous) {
var previous = index;
if (isIndex(index)) {
splice.call(array, index, 1);
}
else if (!isKey(index, array)) {
- var path = castPath(index),
+ var path = baseCastPath(index),
object = parent(array, path);
if (object != null) {
- delete object[toKey(last(path))];
+ delete object[last(path)];
}
}
else {
- delete array[toKey(index)];
+ delete array[index];
}
}
}
}
/**
- * The base implementation of `_.repeat` which doesn't coerce arguments.
- *
- * @private
- * @param {string} string The string to repeat.
- * @param {number} n The number of times to repeat the string.
- * @returns {string} Returns the repeated string.
- */
- function baseRepeat(string, n) {
- var result = '';
- if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
- return result;
- }
- // Leverage the exponentiation by squaring algorithm for a faster repeat.
- // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
- do {
- if (n % 2) {
- result += string;
- }
- n = nativeFloor(n / 2);
- if (n) {
- string += string;
- }
- } while (n);
-
- return result;
- }
-
- /**
* The base implementation of `_.set`.
*
* @private
* @returns {Object} Returns `object`.
*/
function baseSet(object, path, value, customizer) {
- path = isKey(path, object) ? [path] : castPath(path);
+ path = isKey(path, object) ? [path + ''] : baseCastPath(path);
var index = -1,
length = path.length,
nested = object;
while (nested != null && ++index < length) {
- var key = toKey(path[index]);
+ var key = path[index];
if (isObject(nested)) {
var newValue = value;
if (index != lastIndex) {
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
*/
function baseSome(collection, predicate) {
var result;
var mid = (low + high) >>> 1,
computed = array[mid];
- if (computed !== null && !isSymbol(computed) &&
- (retHighest ? (computed <= value) : (computed < value))) {
+ if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
low = mid + 1;
} else {
high = mid;
* @param {*} value The value to evaluate.
* @param {Function} iteratee The iteratee invoked per element.
* @param {boolean} [retHighest] Specify returning the highest qualified index.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
*/
function baseSortedIndexBy(array, value, iteratee, retHighest) {
value = iteratee(value);
high = array ? array.length : 0,
valIsNaN = value !== value,
valIsNull = value === null,
- valIsSymbol = isSymbol(value),
- valIsUndefined = value === undefined;
+ valIsUndef = value === undefined;
while (low < high) {
var mid = nativeFloor((low + high) / 2),
computed = iteratee(array[mid]),
- othIsDefined = computed !== undefined,
- othIsNull = computed === null,
- othIsReflexive = computed === computed,
- othIsSymbol = isSymbol(computed);
+ isDef = computed !== undefined,
+ isReflexive = computed === computed;
if (valIsNaN) {
- var setLow = retHighest || othIsReflexive;
- } else if (valIsUndefined) {
- setLow = othIsReflexive && (retHighest || othIsDefined);
+ var setLow = isReflexive || retHighest;
} else if (valIsNull) {
- setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
- } else if (valIsSymbol) {
- setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
- } else if (othIsNull || othIsSymbol) {
+ setLow = isReflexive && isDef && (retHighest || computed != null);
+ } else if (valIsUndef) {
+ setLow = isReflexive && (retHighest || isDef);
+ } else if (computed == null) {
setLow = false;
} else {
setLow = retHighest ? (computed <= value) : (computed < value);
}
/**
- * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
- * support for iteratee shorthands.
+ * The base implementation of `_.sortedUniq`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ */
+ function baseSortedUniq(array) {
+ return baseSortedUniqBy(array);
+ }
+
+ /**
+ * The base implementation of `_.sortedUniqBy` without support for iteratee
+ * shorthands.
*
* @private
* @param {Array} array The array to inspect.
* @param {Function} [iteratee] The iteratee invoked per element.
* @returns {Array} Returns the new duplicate free array.
*/
- function baseSortedUniq(array, iteratee) {
- var index = -1,
+ function baseSortedUniqBy(array, iteratee) {
+ var index = 0,
length = array.length,
+ value = array[0],
+ computed = iteratee ? iteratee(value) : value,
+ seen = computed,
resIndex = 0,
- result = [];
+ result = [value];
while (++index < length) {
- var value = array[index],
- computed = iteratee ? iteratee(value) : value;
+ value = array[index],
+ computed = iteratee ? iteratee(value) : value;
- if (!index || !eq(computed, seen)) {
- var seen = computed;
- result[resIndex++] = value === 0 ? 0 : value;
+ if (!eq(computed, seen)) {
+ seen = computed;
+ result[++resIndex] = value;
}
}
return result;
}
/**
- * The base implementation of `_.toNumber` which doesn't ensure correct
- * conversions of binary, hexadecimal, or octal string values.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {number} Returns the number.
- */
- function baseToNumber(value) {
- if (typeof value == 'number') {
- return value;
- }
- if (isSymbol(value)) {
- return NAN;
- }
- return +value;
- }
-
- /**
- * The base implementation of `_.toString` which doesn't convert nullish
- * values to empty strings.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {string} Returns the string.
- */
- function baseToString(value) {
- // Exit early for strings to avoid a performance hit in some environments.
- if (typeof value == 'string') {
- return value;
- }
- if (isSymbol(value)) {
- return symbolToString ? symbolToString.call(value) : '';
- }
- var result = (value + '');
- return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
- }
-
- /**
* The base implementation of `_.uniqBy` without support for iteratee shorthands.
*
* @private
var value = array[index],
computed = iteratee ? iteratee(value) : value;
- value = (comparator || value !== 0) ? value : 0;
if (isCommon && computed === computed) {
var seenIndex = seen.length;
while (seenIndex--) {
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
*/
function baseUnset(object, path) {
- path = isKey(path, object) ? [path] : castPath(path);
+ path = isKey(path, object) ? [path + ''] : baseCastPath(path);
object = parent(object, path);
-
- var key = toKey(last(path));
- return !(object != null && baseHas(object, key)) || delete object[key];
- }
-
- /**
- * The base implementation of `_.update`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} path The path of the property to update.
- * @param {Function} updater The function to produce the updated value.
- * @param {Function} [customizer] The function to customize path creation.
- * @returns {Object} Returns `object`.
- */
- function baseUpdate(object, path, updater, customizer) {
- return baseSet(object, path, updater(baseGet(object, path)), customizer);
+ var key = last(path);
+ return (object != null && has(object, key)) ? delete object[key] : true;
}
/**
* This base implementation of `_.zipObject` which assigns values using `assignFunc`.
*
* @private
- * @param {Array} props The property identifiers.
+ * @param {Array} props The property names.
* @param {Array} values The property values.
* @param {Function} assignFunc The function to assign values.
* @returns {Object} Returns the new object.
result = {};
while (++index < length) {
- var value = index < valsLength ? values[index] : undefined;
- assignFunc(result, props[index], value);
+ assignFunc(result, props[index], index < valsLength ? values[index] : undefined);
}
return result;
}
/**
- * Casts `value` to an empty array if it's not an array like object.
- *
- * @private
- * @param {*} value The value to inspect.
- * @returns {Array|Object} Returns the cast array-like object.
- */
- function castArrayLikeObject(value) {
- return isArrayLikeObject(value) ? value : [];
- }
-
- /**
- * Casts `value` to `identity` if it's not a function.
- *
- * @private
- * @param {*} value The value to inspect.
- * @returns {Function} Returns cast function.
- */
- function castFunction(value) {
- return typeof value == 'function' ? value : identity;
- }
-
- /**
- * Casts `value` to a path array if it's not one.
- *
- * @private
- * @param {*} value The value to inspect.
- * @returns {Array} Returns the cast property path array.
- */
- function castPath(value) {
- return isArray(value) ? value : stringToPath(value);
- }
-
- /**
- * Casts `array` to a slice if it's needed.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {number} start The start position.
- * @param {number} [end=array.length] The end position.
- * @returns {Array} Returns the cast slice.
- */
- function castSlice(array, start, end) {
- var length = array.length;
- end = end === undefined ? length : end;
- return (!start && end >= length) ? array : baseSlice(array, start, end);
- }
-
- /**
* Creates a clone of `buffer`.
*
* @private
if (isDeep) {
return buffer.slice();
}
- var result = new buffer.constructor(buffer.length);
+ var Ctor = buffer.constructor,
+ result = new Ctor(buffer.length);
+
buffer.copy(result);
return result;
}
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function cloneArrayBuffer(arrayBuffer) {
- var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
- new Uint8Array(result).set(new Uint8Array(arrayBuffer));
- return result;
- }
+ var Ctor = arrayBuffer.constructor,
+ result = new Ctor(arrayBuffer.byteLength),
+ view = new Uint8Array(result);
- /**
- * Creates a clone of `dataView`.
- *
- * @private
- * @param {Object} dataView The data view to clone.
- * @param {boolean} [isDeep] Specify a deep clone.
- * @returns {Object} Returns the cloned data view.
- */
- function cloneDataView(dataView, isDeep) {
- var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
- return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
+ view.set(new Uint8Array(arrayBuffer));
+ return result;
}
/**
*
* @private
* @param {Object} map The map to clone.
- * @param {Function} cloneFunc The function to clone values.
- * @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned map.
*/
- function cloneMap(map, isDeep, cloneFunc) {
- var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);
- return arrayReduce(array, addMapEntry, new map.constructor);
+ function cloneMap(map) {
+ var Ctor = map.constructor;
+ return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
}
/**
* @returns {Object} Returns the cloned regexp.
*/
function cloneRegExp(regexp) {
- var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
+ var Ctor = regexp.constructor,
+ result = new Ctor(regexp.source, reFlags.exec(regexp));
+
result.lastIndex = regexp.lastIndex;
return result;
}
*
* @private
* @param {Object} set The set to clone.
- * @param {Function} cloneFunc The function to clone values.
- * @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned set.
*/
- function cloneSet(set, isDeep, cloneFunc) {
- var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);
- return arrayReduce(array, addSetEntry, new set.constructor);
+ function cloneSet(set) {
+ var Ctor = set.constructor;
+ return arrayReduce(setToArray(set), addSetEntry, new Ctor);
}
/**
* @returns {Object} Returns the cloned symbol object.
*/
function cloneSymbol(symbol) {
- return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
+ return Symbol ? Object(symbolValueOf.call(symbol)) : {};
}
/**
* @returns {Object} Returns the cloned typed array.
*/
function cloneTypedArray(typedArray, isDeep) {
- var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
- return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
- }
+ var arrayBuffer = typedArray.buffer,
+ buffer = isDeep ? cloneArrayBuffer(arrayBuffer) : arrayBuffer,
+ Ctor = typedArray.constructor;
- /**
- * Compares values to sort them in ascending order.
- *
- * @private
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @returns {number} Returns the sort order indicator for `value`.
- */
- function compareAscending(value, other) {
- if (value !== other) {
- var valIsDefined = value !== undefined,
- valIsNull = value === null,
- valIsReflexive = value === value,
- valIsSymbol = isSymbol(value);
-
- var othIsDefined = other !== undefined,
- othIsNull = other === null,
- othIsReflexive = other === other,
- othIsSymbol = isSymbol(other);
-
- if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
- (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
- (valIsNull && othIsDefined && othIsReflexive) ||
- (!valIsDefined && othIsReflexive) ||
- !valIsReflexive) {
- return 1;
- }
- if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
- (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
- (othIsNull && valIsDefined && valIsReflexive) ||
- (!othIsDefined && valIsReflexive) ||
- !othIsReflexive) {
- return -1;
- }
- }
- return 0;
- }
-
- /**
- * Used by `_.orderBy` to compare multiple properties of a value to another
- * and stable sort them.
- *
- * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
- * specify an order of "desc" for descending or "asc" for ascending sort order
- * of corresponding values.
- *
- * @private
- * @param {Object} object The object to compare.
- * @param {Object} other The other object to compare.
- * @param {boolean[]|string[]} orders The order to sort by for each property.
- * @returns {number} Returns the sort order indicator for `object`.
- */
- function compareMultiple(object, other, orders) {
- var index = -1,
- objCriteria = object.criteria,
- othCriteria = other.criteria,
- length = objCriteria.length,
- ordersLength = orders.length;
-
- while (++index < length) {
- var result = compareAscending(objCriteria[index], othCriteria[index]);
- if (result) {
- if (index >= ordersLength) {
- return result;
- }
- var order = orders[index];
- return result * (order == 'desc' ? -1 : 1);
- }
- }
- // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
- // that causes it, under certain circumstances, to provide the same value for
- // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
- // for more details.
- //
- // This also ensures a stable sort in V8 and other engines.
- // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
- return object.index - other.index;
+ return new Ctor(buffer, typedArray.byteOffset, typedArray.length);
}
/**
*
* @private
* @param {Object} source The object to copy properties from.
- * @param {Array} props The property identifiers to copy.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @returns {Object} Returns `object`.
+ */
+ function copyObject(source, props, object) {
+ return copyObjectWith(source, props, object);
+ }
+
+ /**
+ * This function is like `copyObject` except that it accepts a function to
+ * customize copied values.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
* @param {Object} [object={}] The object to copy properties to.
* @param {Function} [customizer] The function to customize copied values.
* @returns {Object} Returns `object`.
*/
- function copyObject(source, props, object, customizer) {
+ function copyObjectWith(source, props, object, customizer) {
object || (object = {});
var index = -1,
}
/**
- * Creates a base function for methods like `_.forIn` and `_.forOwn`.
+ * Creates a base function for methods like `_.forIn`.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
*
* @private
* @param {Function} func The function to wrap.
- * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
- * for more details.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
* @returns {Function} Returns the new wrapped function.
*/
? stringToArray(string)
: undefined;
- var chr = strSymbols
- ? strSymbols[0]
- : string.charAt(0);
-
- var trailing = strSymbols
- ? castSlice(strSymbols, 1).join('')
- : string.slice(1);
+ var chr = strSymbols ? strSymbols[0] : string.charAt(0),
+ trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
return chr[methodName]() + trailing;
};
*/
function createCompounder(callback) {
return function(string) {
- return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
+ return arrayReduce(words(deburr(string)), callback, '');
};
}
*/
function createCtorWrapper(Ctor) {
return function() {
- // Use a `switch` statement to work with class constructors. See
- // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+ // Use a `switch` statement to work with class constructors.
+ // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
// for more details.
var args = arguments;
switch (args.length) {
*
* @private
* @param {Function} func The function to wrap.
- * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
- * for more details.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {number} arity The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
) {
wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
} else {
- wrapper = (func.length == 1 && isLaziable(func))
- ? wrapper[funcName]()
- : wrapper.thru(func);
+ wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
}
}
return function() {
*
* @private
* @param {Function|string} func The function or method name to wrap.
- * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
- * for more details.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
- * @param {Array} [partials] The arguments to prepend to those provided to
- * the new function.
+ * @param {Array} [partials] The arguments to prepend to those provided to the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
- * @param {Array} [partialsRight] The arguments to append to those provided
- * to the new function.
+ * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
* @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
}
/**
- * Creates a function that performs a mathematical operation on two values.
- *
- * @private
- * @param {Function} operator The function to perform the operation.
- * @returns {Function} Returns the new mathematical operation function.
- */
- function createMathOperation(operator) {
- return function(value, other) {
- var result;
- if (value === undefined && other === undefined) {
- return 0;
- }
- if (value !== undefined) {
- result = value;
- }
- if (other !== undefined) {
- if (result === undefined) {
- return other;
- }
- if (typeof value == 'string' || typeof other == 'string') {
- value = baseToString(value);
- other = baseToString(other);
- } else {
- value = baseToNumber(value);
- other = baseToNumber(other);
- }
- result = operator(value, other);
- }
- return result;
- };
- }
-
- /**
* Creates a function like `_.over`.
*
* @private
*/
function createOver(arrayFunc) {
return rest(function(iteratees) {
- iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
- ? arrayMap(iteratees[0], baseUnary(getIteratee()))
- : arrayMap(baseFlatten(iteratees, 1, isFlattenableIteratee), baseUnary(getIteratee()));
-
+ iteratees = arrayMap(baseFlatten(iteratees, 1), getIteratee());
return rest(function(args) {
var thisArg = this;
return arrayFunc(iteratees, function(iteratee) {
* is truncated if the number of characters exceeds `length`.
*
* @private
- * @param {number} length The padding length.
+ * @param {string} string The string to create padding for.
+ * @param {number} [length=0] The padding length.
* @param {string} [chars=' '] The string used as padding.
* @returns {string} Returns the padding for `string`.
*/
- function createPadding(length, chars) {
- chars = chars === undefined ? ' ' : baseToString(chars);
+ function createPadding(string, length, chars) {
+ length = toInteger(length);
- var charsLength = chars.length;
- if (charsLength < 2) {
- return charsLength ? baseRepeat(chars, length) : chars;
+ var strLength = stringSize(string);
+ if (!length || strLength >= length) {
+ return '';
}
- var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
+ var padLength = length - strLength;
+ chars = chars === undefined ? ' ' : (chars + '');
+
+ var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
return reHasComplexSymbol.test(chars)
- ? castSlice(stringToArray(result), 0, length).join('')
- : result.slice(0, length);
+ ? stringToArray(result).slice(0, padLength).join('')
+ : result.slice(0, padLength);
}
/**
- * Creates a function that wraps `func` to invoke it with the `this` binding
- * of `thisArg` and `partials` prepended to the arguments it receives.
+ * Creates a function that wraps `func` to invoke it with the optional `this`
+ * binding of `thisArg` and the `partials` prepended to those provided to
+ * the wrapper.
*
* @private
* @param {Function} func The function to wrap.
- * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
- * for more details.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {*} thisArg The `this` binding of `func`.
- * @param {Array} partials The arguments to prepend to those provided to
- * the new function.
+ * @param {Array} partials The arguments to prepend to those provided to the new function.
* @returns {Function} Returns the new wrapped function.
*/
function createPartialWrapper(func, bitmask, thisArg, partials) {
}
/**
- * Creates a function that performs a relational operation on two values.
- *
- * @private
- * @param {Function} operator The function to perform the operation.
- * @returns {Function} Returns the new relational operation function.
- */
- function createRelationalOperation(operator) {
- return function(value, other) {
- if (!(typeof value == 'string' && typeof other == 'string')) {
- value = toNumber(value);
- other = toNumber(other);
- }
- return operator(value, other);
- };
- }
-
- /**
* Creates a function that wraps `func` to continue currying.
*
* @private
* @param {Function} func The function to wrap.
- * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
- * for more details.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {Function} wrapFunc The function to create the `func` wrapper.
* @param {*} placeholder The placeholder value.
* @param {*} [thisArg] The `this` binding of `func`.
- * @param {Array} [partials] The arguments to prepend to those provided to
- * the new function.
+ * @param {Array} [partials] The arguments to prepend to those provided to the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
*/
function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
var isCurry = bitmask & CURRY_FLAG,
+ newArgPos = argPos ? copyArray(argPos) : undefined,
newHolders = isCurry ? holders : undefined,
newHoldersRight = isCurry ? undefined : holders,
newPartials = isCurry ? partials : undefined,
}
var newData = [
func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
- newHoldersRight, argPos, ary, arity
+ newHoldersRight, newArgPos, ary, arity
];
var result = wrapFunc.apply(undefined, newData);
* @param {Array} values The values to add to the set.
* @returns {Object} Returns the new set.
*/
- var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
+ var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
return new Set(values);
};
* @param {Array} array The array to compare.
* @param {Array} other The other array to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} customizer The function to customize comparisons.
- * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
- * for more details.
- * @param {Object} stack Tracks traversed `array` and `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `array` and `other` objects.
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
*/
function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
// Recursively compare arrays (susceptible to call stack limits).
if (isUnordered) {
if (!arraySome(other, function(othValue) {
- return arrValue === othValue ||
- equalFunc(arrValue, othValue, customizer, bitmask, stack);
+ return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
})) {
result = false;
break;
}
- } else if (!(
- arrValue === othValue ||
- equalFunc(arrValue, othValue, customizer, bitmask, stack)
- )) {
+ } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
result = false;
break;
}
* @param {Object} other The other object to compare.
* @param {string} tag The `toStringTag` of the objects to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} customizer The function to customize comparisons.
- * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
- * for more details.
- * @param {Object} stack Tracks traversed `object` and `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) {
+ function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
switch (tag) {
- case dataViewTag:
- if ((object.byteLength != other.byteLength) ||
- (object.byteOffset != other.byteOffset)) {
- return false;
- }
- object = object.buffer;
- other = other.buffer;
-
case arrayBufferTag:
if ((object.byteLength != other.byteLength) ||
!equalFunc(new Uint8Array(object), new Uint8Array(other))) {
case boolTag:
case dateTag:
- // Coerce dates and booleans to numbers, dates to milliseconds and
- // booleans to `1` or `0` treating invalid dates coerced to `NaN` as
- // not equal.
+ // Coerce dates and booleans to numbers, dates to milliseconds and booleans
+ // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
return +object == +other;
case errorTag:
case regexpTag:
case stringTag:
- // Coerce regexes to strings and treat strings, primitives and objects,
- // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring
- // for more details.
+ // Coerce regexes to strings and treat strings primitives and string
+ // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
return object == (other + '');
case mapTag:
var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
convert || (convert = setToArray);
- if (object.size != other.size && !isPartial) {
- return false;
- }
- // Assume cyclic values are equal.
- var stacked = stack.get(object);
- if (stacked) {
- return stacked == other;
- }
- bitmask |= UNORDERED_COMPARE_FLAG;
- stack.set(object, other);
-
// Recursively compare objects (susceptible to call stack limits).
- return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);
+ return (isPartial || object.size == other.size) &&
+ equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
case symbolTag:
- if (symbolValueOf) {
- return symbolValueOf.call(object) == symbolValueOf.call(other);
- }
+ return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
}
return false;
}
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} customizer The function to customize comparisons.
- * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
- * for more details.
- * @param {Object} stack Tracks traversed `object` and `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
}
/**
- * Creates an array of own enumerable property names and symbols of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names and symbols.
- */
- function getAllKeys(object) {
- return baseGetAllKeys(object, keys, getSymbols);
- }
-
- /**
- * Creates an array of own and inherited enumerable property names and
- * symbols of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names and symbols.
- */
- function getAllKeysIn(object) {
- return baseGetAllKeys(object, keysIn, getSymbolsIn);
- }
-
- /**
* Gets metadata for `func`.
*
* @private
}
/**
- * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
- * this function returns the custom method, otherwise it returns `baseIteratee`.
- * If arguments are provided, the chosen function is invoked with them and
- * its result is returned.
+ * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
+ * customized this function returns the custom method, otherwise it returns
+ * `baseIteratee`. If arguments are provided the chosen function is invoked
+ * with them and its result is returned.
*
* @private
* @param {*} [value] The value to convert to an iteratee.
/**
* Gets the "length" property value of `object`.
*
- * **Note:** This function is used to avoid a
- * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
- * Safari on at least iOS 8.1-8.3 ARM64.
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
*
* @private
* @param {Object} object The object to query.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
- var value = object[key];
+ var value = object == null ? undefined : object[key];
return isNative(value) ? value : undefined;
}
}
/**
- * Gets the `[[Prototype]]` of `value`.
- *
- * @private
- * @param {*} value The value to query.
- * @returns {null|Object} Returns the `[[Prototype]]`.
- */
- function getPrototype(value) {
- return nativeGetPrototype(Object(value));
- }
-
- /**
- * Creates an array of the own enumerable symbol properties of `object`.
+ * Creates an array of the own symbol properties of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of symbols.
*/
- function getSymbols(object) {
- // Coerce `object` to an object to avoid non-object errors in V8.
- // See https://bugs.chromium.org/p/v8/issues/detail?id=3443 for more details.
- return getOwnPropertySymbols(Object(object));
- }
-
- // Fallback for IE < 11.
- if (!getOwnPropertySymbols) {
- getSymbols = function() {
- return [];
- };
- }
-
- /**
- * Creates an array of the own and inherited enumerable symbol properties
- * of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of symbols.
- */
- var getSymbolsIn = !getOwnPropertySymbols ? getSymbols : function(object) {
- var result = [];
- while (object) {
- arrayPush(result, getSymbols(object));
- object = getPrototype(object);
- }
- return result;
+ var getSymbols = getOwnPropertySymbols || function() {
+ return [];
};
/**
return objectToString.call(value);
}
- // Fallback for data views, maps, sets, and weak maps in IE 11,
- // for data views in Edge, and promises in Node.js.
- if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
- (Map && getTag(new Map) != mapTag) ||
- (Promise && getTag(Promise.resolve()) != promiseTag) ||
+ // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps.
+ if ((Map && getTag(new Map) != mapTag) ||
(Set && getTag(new Set) != setTag) ||
(WeakMap && getTag(new WeakMap) != weakMapTag)) {
getTag = function(value) {
var result = objectToString.call(value),
- Ctor = result == objectTag ? value.constructor : undefined,
- ctorString = Ctor ? toSource(Ctor) : undefined;
+ Ctor = result == objectTag ? value.constructor : null,
+ ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
if (ctorString) {
switch (ctorString) {
- case dataViewCtorString: return dataViewTag;
case mapCtorString: return mapTag;
- case promiseCtorString: return promiseTag;
case setCtorString: return setTag;
case weakMapCtorString: return weakMapTag;
}
* @returns {boolean} Returns `true` if `path` exists, else `false`.
*/
function hasPath(object, path, hasFunc) {
- path = isKey(path, object) ? [path] : castPath(path);
-
- var result,
- index = -1,
- length = path.length;
-
- while (++index < length) {
- var key = toKey(path[index]);
- if (!(result = object != null && hasFunc(object, key))) {
- break;
- }
- object = object[key];
+ if (object == null) {
+ return false;
}
- if (result) {
- return result;
+ var result = hasFunc(object, path);
+ if (!result && !isKey(path)) {
+ path = baseCastPath(path);
+ object = parent(object, path);
+ if (object != null) {
+ path = last(path);
+ result = hasFunc(object, path);
+ }
}
- var length = object ? object.length : 0;
- return !!length && isLength(length) && isIndex(key, length) &&
- (isArray(object) || isString(object) || isArguments(object));
+ var length = object ? object.length : undefined;
+ return result || (
+ !!length && isLength(length) && isIndex(path, length) &&
+ (isArray(object) || isString(object) || isArguments(object))
+ );
}
/**
* @returns {Object} Returns the initialized clone.
*/
function initCloneObject(object) {
- return (typeof object.constructor == 'function' && !isPrototype(object))
- ? baseCreate(getPrototype(object))
+ return (isFunction(object.constructor) && !isPrototype(object))
+ ? baseCreate(getPrototypeOf(object))
: {};
}
* @private
* @param {Object} object The object to clone.
* @param {string} tag The `toStringTag` of the object to clone.
- * @param {Function} cloneFunc The function to clone values.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the initialized clone.
*/
- function initCloneByTag(object, tag, cloneFunc, isDeep) {
+ function initCloneByTag(object, tag, isDeep) {
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
case dateTag:
return new Ctor(+object);
- case dataViewTag:
- return cloneDataView(object, isDeep);
-
case float32Tag: case float64Tag:
case int8Tag: case int16Tag: case int32Tag:
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
return cloneTypedArray(object, isDeep);
case mapTag:
- return cloneMap(object, isDeep, cloneFunc);
+ return cloneMap(object);
case numberTag:
case stringTag:
return cloneRegExp(object);
case setTag:
- return cloneSet(object, isDeep, cloneFunc);
+ return cloneSet(object);
case symbolTag:
return cloneSymbol(object);
}
/**
- * Checks if `value` is a flattenable `arguments` object or array.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
- */
- function isFlattenable(value) {
- return isArrayLikeObject(value) && (isArray(value) || isArguments(value));
- }
-
- /**
- * Checks if `value` is a flattenable array and not a `_.matchesProperty`
- * iteratee shorthand.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
- */
- function isFlattenableIteratee(value) {
- return isArray(value) && !(value.length == 2 && !isFunction(value[0]));
- }
-
- /**
- * Checks if `value` is a valid array-like index.
- *
- * @private
- * @param {*} value The value to check.
- * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
- * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
- */
- function isIndex(value, length) {
- length = length == null ? MAX_SAFE_INTEGER : length;
- return !!length &&
- (typeof value == 'number' || reIsUint.test(value)) &&
- (value > -1 && value % 1 == 0 && value < length);
- }
-
- /**
* Checks if the given arguments are from an iteratee call.
*
* @private
* @param {*} value The potential iteratee value argument.
* @param {*} index The potential iteratee index or key argument.
* @param {*} object The potential iteratee object argument.
- * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
- * else `false`.
+ * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
*/
function isIterateeCall(value, index, object) {
if (!isObject(object)) {
}
var type = typeof index;
if (type == 'number'
- ? (isArrayLike(object) && isIndex(index, object.length))
- : (type == 'string' && index in object)
- ) {
+ ? (isArrayLike(object) && isIndex(index, object.length))
+ : (type == 'string' && index in object)) {
return eq(object[index], value);
}
return false;
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
*/
function isKey(value, object) {
- if (isArray(value)) {
- return false;
- }
- var type = typeof value;
- if (type == 'number' || type == 'symbol' || type == 'boolean' ||
- value == null || isSymbol(value)) {
+ if (typeof value == 'number') {
return true;
}
- return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
- (object != null && value in Object(object));
+ return !isArray(value) &&
+ (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+ (object != null && value in Object(object)));
}
/**
*/
function isKeyable(value) {
var type = typeof value;
- return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
- ? (value !== '__proto__')
- : (value === null);
+ return type == 'number' || type == 'boolean' ||
+ (type == 'string' && value != '__proto__') || value == null;
}
/**
*
* @private
* @param {Function} func The function to check.
- * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
- * else `false`.
+ * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
*/
function isLaziable(func) {
var funcName = getFuncName(func),
*/
function isPrototype(value) {
var Ctor = value && value.constructor,
- proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+ proto = (isFunction(Ctor) && Ctor.prototype) || objectProto;
return value === proto;
}
}
/**
- * A specialized version of `matchesProperty` for source values suitable
- * for strict equality comparisons, i.e. `===`.
- *
- * @private
- * @param {string} key The key of the property to get.
- * @param {*} srcValue The value to match.
- * @returns {Function} Returns the new function.
- */
- function matchesStrictComparable(key, srcValue) {
- return function(object) {
- if (object == null) {
- return false;
- }
- return object[key] === srcValue &&
- (srcValue !== undefined || (key in Object(object)));
- };
- }
-
- /**
* Merges the function metadata of `source` into `data`.
*
* Merging metadata reduces the number of wrappers used to invoke a function.
* This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
- * may be applied regardless of execution order. Methods like `_.ary` and
- * `_.rearg` modify function arguments, making the order in which they are
- * executed important, preventing the merging of metadata. However, we make
- * an exception for a safe combined case where curried functions have `_.ary`
- * and or `_.rearg` applied.
+ * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
+ * modify function arguments, making the order in which they are executed important,
+ * preventing the merging of metadata. However, we make an exception for a safe
+ * combined case where curried functions have `_.ary` and or `_.rearg` applied.
*
* @private
* @param {Array} data The destination metadata.
var value = source[3];
if (value) {
var partials = data[3];
- data[3] = partials ? composeArgs(partials, value, source[4]) : value;
- data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
+ data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
+ data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
}
// Compose partial right arguments.
value = source[5];
if (value) {
partials = data[5];
- data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
- data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
+ data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
+ data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
}
// Use source `argPos` if available.
value = source[7];
if (value) {
- data[7] = value;
+ data[7] = copyArray(value);
}
// Use source `ary` if it's smaller.
if (srcBitmask & ARY_FLAG) {
* @param {string} key The key of the property to merge.
* @param {Object} object The parent object of `objValue`.
* @param {Object} source The parent object of `srcValue`.
- * @param {Object} [stack] Tracks traversed source values and their merged
- * counterparts.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
* @returns {*} Returns the value to assign.
*/
function mergeDefaults(objValue, srcValue, key, object, source, stack) {
if (isObject(objValue) && isObject(srcValue)) {
- baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue));
+ stack.set(srcValue, objValue);
+ baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
}
return objValue;
}
* @returns {*} Returns the parent value.
*/
function parent(object, path) {
- return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
+ return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
}
/**
* Sets metadata for `func`.
*
* **Note:** If this function becomes hot, i.e. is invoked a lot in a short
- * period of time, it will trip its breaker and transition to an identity
- * function to avoid garbage collection pauses in V8. See
- * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
+ * period of time, it will trip its breaker and transition to an identity function
+ * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
* for more details.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the property path array.
*/
- var stringToPath = memoize(function(string) {
+ function stringToPath(string) {
var result = [];
toString(string).replace(rePropName, function(match, number, quote, string) {
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
});
return result;
- });
-
- /**
- * Converts `value` to a string key if it's not a string or symbol.
- *
- * @private
- * @param {*} value The value to inspect.
- * @returns {string|symbol} Returns the key.
- */
- function toKey(value) {
- if (typeof value == 'string' || isSymbol(value)) {
- return value;
- }
- var result = (value + '');
- return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
- }
-
- /**
- * Converts `func` to its source code.
- *
- * @private
- * @param {Function} func The function to process.
- * @returns {string} Returns the source code.
- */
- function toSource(func) {
- if (func != null) {
- try {
- return funcToString.call(func);
- } catch (e) {}
- try {
- return (func + '');
- } catch (e) {}
- }
- return '';
}
/**
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The array to process.
- * @param {number} [size=1] The length of each chunk
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param {number} [size=0] The length of each chunk.
* @returns {Array} Returns the new array containing chunks.
* @example
*
* _.chunk(['a', 'b', 'c', 'd'], 3);
* // => [['a', 'b', 'c'], ['d']]
*/
- function chunk(array, size, guard) {
- if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
- size = 1;
- } else {
- size = nativeMax(toInteger(size), 0);
- }
+ function chunk(array, size) {
+ size = nativeMax(toInteger(size), 0);
+
var length = array ? array.length : 0;
if (!length || size < 1) {
return [];
}
var index = 0,
- resIndex = 0,
+ resIndex = -1,
result = Array(nativeCeil(length / size));
while (index < length) {
- result[resIndex++] = baseSlice(array, index, (index += size));
+ result[++resIndex] = baseSlice(array, index, (index += size));
}
return result;
}
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to compact.
* @returns {Array} Returns the new array of filtered values.
function compact(array) {
var index = -1,
length = array ? array.length : 0,
- resIndex = 0,
+ resIndex = -1,
result = [];
while (++index < length) {
var value = array[index];
if (value) {
- result[resIndex++] = value;
+ result[++resIndex] = value;
}
}
return result;
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to concatenate.
* @param {...*} [values] The values to concatenate.
* console.log(array);
* // => [1]
*/
- function concat() {
- var length = arguments.length,
- array = castArray(arguments[0]);
-
- if (length < 2) {
- return length ? copyArray(array) : [];
+ var concat = rest(function(array, values) {
+ if (!isArray(array)) {
+ array = array == null ? [] : [Object(array)];
}
- var args = Array(length - 1);
- while (length--) {
- args[length - 1] = arguments[length];
- }
- return arrayConcat(array, baseFlatten(args, 1));
- }
+ values = baseFlatten(values, 1);
+ return arrayConcat(array, values);
+ });
/**
- * Creates an array of unique `array` values not included in the other given
- * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons. The order of result values is determined by the
- * order they occur in the first array.
+ * Creates an array of unique `array` values not included in the other
+ * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to inspect.
* @param {...Array} [values] The values to exclude.
* @returns {Array} Returns the new array of filtered values.
- * @see _.without, _.xor
* @example
*
* _.difference([3, 2, 1], [4, 2]);
*/
var difference = rest(function(array, values) {
return isArrayLikeObject(array)
- ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
+ ? baseDifference(array, baseFlatten(values, 1, true))
: [];
});
/**
* This method is like `_.difference` except that it accepts `iteratee` which
* is invoked for each element of `array` and `values` to generate the criterion
- * by which they're compared. Result values are chosen from the first array.
- * The iteratee is invoked with one argument: (value).
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {...Array} [values] The values to exclude.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns the new array of filtered values.
* @example
*
iteratee = undefined;
}
return isArrayLikeObject(array)
- ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee))
+ ? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee))
: [];
});
/**
* This method is like `_.difference` except that it accepts `comparator`
- * which is invoked to compare elements of `array` to `values`. Result values
- * are chosen from the first array. The comparator is invoked with two arguments:
- * (arrVal, othVal).
+ * which is invoked to compare elements of `array` to `values`. The comparator
+ * is invoked with two arguments: (arrVal, othVal).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {...Array} [values] The values to exclude.
comparator = undefined;
}
return isArrayLikeObject(array)
- ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
+ ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator)
: [];
});
*
* @static
* @memberOf _
- * @since 0.5.0
* @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 an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
*
* @static
* @memberOf _
- * @since 3.0.0
* @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 an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The array to query.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The array to query.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
*
* @static
* @memberOf _
- * @since 3.2.0
* @category Array
* @param {Array} array The array to fill.
* @param {*} value The value to fill `array` with.
*
* @static
* @memberOf _
- * @since 1.1.0
* @category Array
* @param {Array} array The array to search.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {number} Returns the index of the found element, else `-1`.
* @example
*
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Array
* @param {Array} array The array to search.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {number} Returns the index of the found element, else `-1`.
* @example
*
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to flatten.
* @returns {Array} Returns the new flattened array.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The array to flatten.
* @returns {Array} Returns the new flattened array.
*
* @static
* @memberOf _
- * @since 4.4.0
* @category Array
* @param {Array} array The array to flatten.
* @param {number} [depth=1] The maximum recursion depth.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} pairs The key-value pairs.
* @returns {Object} Returns the new object.
*
* @static
* @memberOf _
- * @since 0.1.0
* @alias first
* @category Array
* @param {Array} array The array to query.
* // => undefined
*/
function head(array) {
- return (array && array.length) ? array[0] : undefined;
+ return array ? array[0] : undefined;
}
/**
* Gets the index at which the first occurrence of `value` is found in `array`
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons. If `fromIndex` is negative, it's used as the
- * offset from the end of `array`.
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `array`.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to query.
* @returns {Array} Returns the slice of `array`.
/**
* Creates an array of unique values that are included in all given arrays
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons. The order of result values is determined by the
- * order they occur in the first array.
+ * for equality comparisons.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
- * @returns {Array} Returns the new array of intersecting values.
+ * @returns {Array} Returns the new array of shared values.
* @example
*
* _.intersection([2, 1], [4, 2], [1, 2]);
* // => [2]
*/
var intersection = rest(function(arrays) {
- var mapped = arrayMap(arrays, castArrayLikeObject);
+ var mapped = arrayMap(arrays, baseCastArrayLikeObject);
return (mapped.length && mapped[0] === arrays[0])
? baseIntersection(mapped)
: [];
/**
* This method is like `_.intersection` except that it accepts `iteratee`
* which is invoked for each element of each `arrays` to generate the criterion
- * by which they're compared. Result values are chosen from the first array.
- * The iteratee is invoked with one argument: (value).
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
- * @returns {Array} Returns the new array of intersecting values.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of shared values.
* @example
*
* _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
*/
var intersectionBy = rest(function(arrays) {
var iteratee = last(arrays),
- mapped = arrayMap(arrays, castArrayLikeObject);
+ mapped = arrayMap(arrays, baseCastArrayLikeObject);
if (iteratee === last(mapped)) {
iteratee = undefined;
/**
* This method is like `_.intersection` except that it accepts `comparator`
- * which is invoked to compare elements of `arrays`. Result values are chosen
- * from the first array. The comparator is invoked with two arguments:
- * (arrVal, othVal).
+ * which is invoked to compare elements of `arrays`. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @param {Function} [comparator] The comparator invoked per element.
- * @returns {Array} Returns the new array of intersecting values.
+ * @returns {Array} Returns the new array of shared values.
* @example
*
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
*/
var intersectionWith = rest(function(arrays) {
var comparator = last(arrays),
- mapped = arrayMap(arrays, castArrayLikeObject);
+ mapped = arrayMap(arrays, baseCastArrayLikeObject);
if (comparator === last(mapped)) {
comparator = undefined;
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to convert.
* @param {string} [separator=','] The element separator.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to query.
* @returns {*} Returns the last element of `array`.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
var index = length;
if (fromIndex !== undefined) {
index = toInteger(fromIndex);
- index = (
- index < 0
- ? nativeMax(length + index, 0)
- : nativeMin(index, length - 1)
- ) + 1;
+ index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
}
if (value !== value) {
return indexOfNaN(array, index, true);
}
/**
- * Gets the nth element of `array`. If `n` is negative, the nth element
- * from the end is returned.
- *
- * @static
- * @memberOf _
- * @since 4.11.0
- * @category Array
- * @param {Array} array The array to query.
- * @param {number} [n=0] The index of the element to return.
- * @returns {*} Returns the nth element of `array`.
- * @example
- *
- * var array = ['a', 'b', 'c', 'd'];
- *
- * _.nth(array, 1);
- * // => 'b'
- *
- * _.nth(array, -2);
- * // => 'c';
- */
- function nth(array, n) {
- return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
- }
-
- /**
* Removes all given values from `array` using
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {...*} [values] The values to remove.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {Array} values The values to remove.
/**
* This method is like `_.pullAll` except that it accepts `iteratee` which is
* invoked for each element of `array` and `values` to generate the criterion
- * by which they're compared. The iteratee is invoked with one argument: (value).
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
*
* **Note:** Unlike `_.differenceBy`, this method mutates `array`.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {Array} values The values to remove.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns `array`.
* @example
*
*/
function pullAllBy(array, values, iteratee) {
return (array && array.length && values && values.length)
- ? basePullAll(array, values, getIteratee(iteratee))
- : array;
- }
-
- /**
- * This method is like `_.pullAll` except that it accepts `comparator` which
- * is invoked to compare elements of `array` to `values`. The comparator is
- * invoked with two arguments: (arrVal, othVal).
- *
- * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
- *
- * @static
- * @memberOf _
- * @since 4.6.0
- * @category Array
- * @param {Array} array The array to modify.
- * @param {Array} values The values to remove.
- * @param {Function} [comparator] The comparator invoked per element.
- * @returns {Array} Returns `array`.
- * @example
- *
- * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
- *
- * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
- * console.log(array);
- * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
- */
- function pullAllWith(array, values, comparator) {
- return (array && array.length && values && values.length)
- ? basePullAll(array, values, undefined, comparator)
+ ? basePullAllBy(array, values, getIteratee(iteratee))
: array;
}
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The array to modify.
- * @param {...(number|number[])} [indexes] The indexes of elements to remove.
+ * @param {...(number|number[])} [indexes] The indexes of elements to remove,
+ * specified individually or in arrays.
* @returns {Array} Returns the new array of removed elements.
* @example
*
* // => [10, 20]
*/
var pullAt = rest(function(array, indexes) {
- indexes = baseFlatten(indexes, 1);
-
- var length = array ? array.length : 0,
- result = baseAt(array, indexes);
-
- basePullAt(array, arrayMap(indexes, function(index) {
- return isIndex(index, length) ? +index : index;
- }).sort(compareAscending));
+ indexes = arrayMap(baseFlatten(indexes, 1), String);
+ var result = baseAt(array, indexes);
+ basePullAt(array, indexes.sort(compareAscending));
return result;
});
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Array
* @param {Array} array The array to modify.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new array of removed elements.
* @example
*
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
- * @param {Array} array The array to modify.
* @returns {Array} Returns `array`.
* @example
*
/**
* Creates a slice of `array` from `start` up to, but not including, `end`.
*
- * **Note:** This method is used instead of
- * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
- * returned.
+ * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
+ * to ensure dense arrays are returned.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The array to slice.
* @param {number} [start=0] The start position.
}
/**
- * Uses a binary search to determine the lowest index at which `value`
- * should be inserted into `array` in order to maintain its sort order.
+ * Uses a binary search to determine the lowest index at which `value` should
+ * be inserted into `array` in order to maintain its sort order.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
* @example
*
* _.sortedIndex([30, 50], 40);
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
* @example
*
* var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
* @example
*
* _.sortedLastIndex([4, 5], 4);
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
* @example
*
* // The `_.property` iteratee shorthand.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @returns {Array} Returns the new duplicate free array.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {Function} [iteratee] The iteratee invoked per element.
*/
function sortedUniqBy(array, iteratee) {
return (array && array.length)
- ? baseSortedUniq(array, getIteratee(iteratee))
+ ? baseSortedUniqBy(array, getIteratee(iteratee))
: [];
}
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to query.
* @returns {Array} Returns the slice of `array`.
*
* @static
* @memberOf _
- * @since 0.1.0
* @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 an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
*
* @static
* @memberOf _
- * @since 3.0.0
* @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 an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
/**
* Creates a slice of `array` with elements taken from the end. Elements are
- * taken until `predicate` returns falsey. The predicate is invoked with
- * three arguments: (value, index, array).
+ * taken until `predicate` returns falsey. The predicate is invoked with three
+ * arguments: (value, index, array).
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The array to query.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Array
* @param {Array} array The array to query.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @returns {Array} Returns the new array of combined values.
* // => [2, 1, 4]
*/
var union = rest(function(arrays) {
- return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
+ return baseUniq(baseFlatten(arrays, 1, true));
});
/**
* This method is like `_.union` except that it accepts `iteratee` which is
- * invoked for each element of each `arrays` to generate the criterion by
- * which uniqueness is computed. The iteratee is invoked with one argument:
- * (value).
+ * invoked for each element of each `arrays` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns the new array of combined values.
* @example
*
if (isArrayLikeObject(iteratee)) {
iteratee = undefined;
}
- return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee));
+ return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee));
});
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @param {Function} [comparator] The comparator invoked per element.
if (isArrayLikeObject(comparator)) {
comparator = undefined;
}
- return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
+ return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator);
});
/**
* Creates a duplicate-free version of an array, using
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons, in which only the first occurrence of each
- * element is kept.
+ * for equality comparisons, in which only the first occurrence of each element
+ * is kept.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to inspect.
* @returns {Array} Returns the new duplicate free array.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns the new duplicate free array.
* @example
*
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {Function} [comparator] The comparator invoked per element.
*
* @static
* @memberOf _
- * @since 1.2.0
* @category Array
* @param {Array} array The array of grouped elements to process.
* @returns {Array} Returns the new array of regrouped elements.
*
* @static
* @memberOf _
- * @since 3.8.0
* @category Array
* @param {Array} array The array of grouped elements to process.
- * @param {Function} [iteratee=_.identity] The function to combine
- * regrouped values.
+ * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
* @returns {Array} Returns the new array of regrouped elements.
* @example
*
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {Array} array The array to filter.
* @param {...*} [values] The values to exclude.
* @returns {Array} Returns the new array of filtered values.
- * @see _.difference, _.xor
* @example
*
* _.without([1, 2, 1, 3], 1, 2);
});
/**
- * Creates an array of unique values that is the
- * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
- * of the given arrays. The order of result values is determined by the order
- * they occur in the arrays.
+ * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
+ * of the given arrays.
*
* @static
* @memberOf _
- * @since 2.4.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @returns {Array} Returns the new array of values.
- * @see _.difference, _.without
* @example
*
* _.xor([2, 1], [4, 2]);
/**
* This method is like `_.xor` except that it accepts `iteratee` which is
- * invoked for each element of each `arrays` to generate the criterion by
- * which by which they're compared. The iteratee is invoked with one argument:
- * (value).
+ * invoked for each element of each `arrays` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns the new array of values.
* @example
*
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @param {Function} [comparator] The comparator invoked per element.
});
/**
- * Creates an array of grouped elements, the first of which contains the
- * first elements of the given arrays, the second of which contains the
- * second elements of the given arrays, and so on.
+ * Creates an array of grouped elements, the first of which contains the first
+ * elements of the given arrays, the second of which contains the second elements
+ * of the given arrays, and so on.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Array
* @param {...Array} [arrays] The arrays to process.
* @returns {Array} Returns the new array of grouped elements.
/**
* This method is like `_.fromPairs` except that it accepts two arrays,
- * one of property identifiers and one of corresponding values.
+ * one of property names and one of corresponding values.
*
* @static
* @memberOf _
- * @since 0.4.0
* @category Array
- * @param {Array} [props=[]] The property identifiers.
+ * @param {Array} [props=[]] The property names.
* @param {Array} [values=[]] The property values.
* @returns {Object} Returns the new object.
* @example
*
* @static
* @memberOf _
- * @since 4.1.0
* @category Array
- * @param {Array} [props=[]] The property identifiers.
+ * @param {Array} [props=[]] The property names.
* @param {Array} [values=[]] The property values.
* @returns {Object} Returns the new object.
* @example
*
* @static
* @memberOf _
- * @since 3.8.0
* @category Array
* @param {...Array} [arrays] The arrays to process.
* @param {Function} [iteratee=_.identity] The function to combine grouped values.
/*------------------------------------------------------------------------*/
/**
- * Creates a `lodash` wrapper instance that wraps `value` with explicit method
- * chain sequences enabled. The result of such sequences must be unwrapped
- * with `_#value`.
+ * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
+ * The result of such method chaining must be unwrapped with `_#value`.
*
* @static
* @memberOf _
- * @since 1.3.0
* @category Seq
* @param {*} value The value to wrap.
* @returns {Object} Returns the new `lodash` wrapper instance.
/**
* This method invokes `interceptor` and returns `value`. The interceptor
* is invoked with one argument; (value). The purpose of this method is to
- * "tap into" a method chain sequence in order to modify intermediate results.
+ * "tap into" a method chain in order to modify intermediate results.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Seq
* @param {*} value The value to provide to `interceptor`.
* @param {Function} interceptor The function to invoke.
/**
* This method is like `_.tap` except that it returns the result of `interceptor`.
* The purpose of this method is to "pass thru" values replacing intermediate
- * results in a method chain sequence.
+ * results in a method chain.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Seq
* @param {*} value The value to provide to `interceptor`.
* @param {Function} interceptor The function to invoke.
*
* @name at
* @memberOf _
- * @since 1.0.0
* @category Seq
- * @param {...(string|string[])} [paths] The property paths of elements to pick.
+ * @param {...(string|string[])} [paths] The property paths of elements to pick,
+ * specified individually or in arrays.
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
});
/**
- * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
+ * Enables explicit method chaining on the wrapper object.
*
* @name chain
* @memberOf _
- * @since 0.1.0
* @category Seq
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
}
/**
- * Executes the chain sequence and returns the wrapped result.
+ * Executes the chained sequence and returns the wrapped result.
*
* @name commit
* @memberOf _
- * @since 3.2.0
* @category Seq
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
}
/**
+ * This method is the wrapper version of `_.flatMap`.
+ *
+ * @name flatMap
+ * @memberOf _
+ * @category Seq
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [n, n];
+ * }
+ *
+ * _([1, 2]).flatMap(duplicate).value();
+ * // => [1, 1, 2, 2]
+ */
+ function wrapperFlatMap(iteratee) {
+ return this.map(iteratee).flatten();
+ }
+
+ /**
* Gets the next value on a wrapped object following the
* [iterator protocol](https://mdn.io/iteration_protocols#iterator).
*
* @name next
* @memberOf _
- * @since 4.0.0
* @category Seq
* @returns {Object} Returns the next iterator value.
* @example
*
* @name Symbol.iterator
* @memberOf _
- * @since 4.0.0
* @category Seq
* @returns {Object} Returns the wrapper object.
* @example
}
/**
- * Creates a clone of the chain sequence planting `value` as the wrapped value.
+ * Creates a clone of the chained sequence planting `value` as the wrapped value.
*
* @name plant
* @memberOf _
- * @since 3.2.0
* @category Seq
* @param {*} value The value to plant.
* @returns {Object} Returns the new `lodash` wrapper instance.
*
* @name reverse
* @memberOf _
- * @since 0.1.0
* @category Seq
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
}
/**
- * Executes the chain sequence to resolve the unwrapped value.
+ * Executes the chained sequence to extract the unwrapped value.
*
* @name value
* @memberOf _
- * @since 0.1.0
* @alias toJSON, valueOf
* @category Seq
* @returns {*} Returns the resolved unwrapped value.
/**
* Creates an object composed of keys generated from the results of running
- * each element of `collection` thru `iteratee`. The corresponding value of
- * each key is the number of times the key was returned by `iteratee`. The
- * iteratee is invoked with one argument: (value).
+ * each element of `collection` through `iteratee`. The corresponding value
+ * of each key is the number of times the key was returned by `iteratee`.
+ * The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
- * @since 0.5.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee to transform keys.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
* @example
*
* _.every([true, 1, null, 'yes'], Boolean);
* // => false
*
* var users = [
- * { 'user': 'barney', 'age': 36, 'active': false },
- * { 'user': 'fred', 'age': 40, 'active': false }
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false }
* ];
*
* // The `_.matches` iteratee shorthand.
/**
* Iterates over elements of `collection`, returning an array of all elements
- * `predicate` returns truthy for. The predicate is invoked with three
- * arguments: (value, index|key, collection).
+ * `predicate` returns truthy for. The predicate is invoked with three arguments:
+ * (value, index|key, collection).
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
- * @see _.reject
* @example
*
* var users = [
/**
* Iterates over elements of `collection`, returning the first element
- * `predicate` returns truthy for. The predicate is invoked with three
- * arguments: (value, index|key, collection).
+ * `predicate` returns truthy for. The predicate is invoked with three arguments:
+ * (value, index|key, collection).
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to search.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {*} Returns the matched element, else `undefined`.
* @example
*
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Collection
* @param {Array|Object} collection The collection to search.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {*} Returns the matched element, else `undefined`.
* @example
*
}
/**
- * Creates a flattened array of values by running each element in `collection`
- * thru `iteratee` and flattening the mapped results. The iteratee is invoked
- * with three arguments: (value, index|key, collection).
+ * Creates an array of flattened values by running each element in `collection`
+ * through `iteratee` and concating its result to the other mapped values.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new flattened array.
* @example
*
}
/**
- * This method is like `_.flatMap` except that it recursively flattens the
- * mapped results.
- *
- * @static
- * @memberOf _
- * @since 4.7.0
- * @category Collection
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The function invoked per iteration.
- * @returns {Array} Returns the new flattened array.
- * @example
- *
- * function duplicate(n) {
- * return [[[n, n]]];
- * }
- *
- * _.flatMapDeep([1, 2], duplicate);
- * // => [1, 1, 2, 2]
- */
- function flatMapDeep(collection, iteratee) {
- return baseFlatten(map(collection, iteratee), INFINITY);
- }
-
- /**
- * This method is like `_.flatMap` except that it recursively flattens the
- * mapped results up to `depth` times.
- *
- * @static
- * @memberOf _
- * @since 4.7.0
- * @category Collection
- * @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The function invoked per iteration.
- * @param {number} [depth=1] The maximum recursion depth.
- * @returns {Array} Returns the new flattened array.
- * @example
- *
- * function duplicate(n) {
- * return [[[n, n]]];
- * }
- *
- * _.flatMapDepth([1, 2], duplicate, 2);
- * // => [[1, 1], [2, 2]]
- */
- function flatMapDepth(collection, iteratee, depth) {
- depth = depth === undefined ? 1 : toInteger(depth);
- return baseFlatten(map(collection, iteratee), depth);
- }
-
- /**
- * Iterates over elements of `collection` and invokes `iteratee` for each element.
+ * Iterates over elements of `collection` invoking `iteratee` for each element.
* The iteratee is invoked with three arguments: (value, index|key, collection).
* Iteratee 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 use `_.forIn`
- * or `_.forOwn` for object iteration.
+ * **Note:** As with other "Collections" methods, objects with a "length" property
+ * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
+ * for object iteration.
*
* @static
* @memberOf _
- * @since 0.1.0
* @alias each
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array|Object} Returns `collection`.
- * @see _.forEachRight
* @example
*
* _([1, 2]).forEach(function(value) {
* console.log(value);
* });
- * // => Logs `1` then `2`.
+ * // => logs `1` then `2`
*
* _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
* console.log(key);
* });
- * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
*/
function forEach(collection, iteratee) {
return (typeof iteratee == 'function' && isArray(collection))
? arrayEach(collection, iteratee)
- : baseEach(collection, getIteratee(iteratee));
+ : baseEach(collection, baseCastFunction(iteratee));
}
/**
*
* @static
* @memberOf _
- * @since 2.0.0
* @alias eachRight
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array|Object} Returns `collection`.
- * @see _.forEach
* @example
*
* _.forEachRight([1, 2], function(value) {
* console.log(value);
* });
- * // => Logs `2` then `1`.
+ * // => logs `2` then `1`
*/
function forEachRight(collection, iteratee) {
return (typeof iteratee == 'function' && isArray(collection))
? arrayEachRight(collection, iteratee)
- : baseEachRight(collection, getIteratee(iteratee));
+ : baseEachRight(collection, baseCastFunction(iteratee));
}
/**
* Creates an object composed of keys generated from the results of running
- * each element of `collection` thru `iteratee`. The order of grouped values
- * is determined by the order they occur in `collection`. The corresponding
- * value of each key is an array of elements responsible for generating the
- * key. The iteratee is invoked with one argument: (value).
+ * each element of `collection` through `iteratee`. The corresponding value
+ * of each key is an array of elements responsible for generating the key.
+ * The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee to transform keys.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
});
/**
- * Checks if `value` is in `collection`. If `collection` is a string, it's
- * checked for a substring of `value`, otherwise
- * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * Checks if `value` is in `collection`. If `collection` is a string it's checked
+ * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* is used for equality comparisons. If `fromIndex` is negative, it's used as
* the offset from the end of `collection`.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object|string} collection The collection to search.
* @param {*} value The value to search for.
* @param {number} [fromIndex=0] The index to search from.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
* @returns {boolean} Returns `true` if `value` is found, else `false`.
* @example
*
/**
* Invokes the method at `path` of each element in `collection`, returning
* an array of the results of each invoked method. Any additional arguments
- * are provided to each invoked method. If `methodName` is a function, it's
- * invoked for and `this` bound to, each element in `collection`.
+ * are provided to each invoked method. If `methodName` is a function it's
+ * invoked for, and `this` bound to, each element in `collection`.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Array|Function|string} path The path of the method to invoke or
/**
* Creates an object composed of keys generated from the results of running
- * each element of `collection` thru `iteratee`. The corresponding value of
- * each key is the last element responsible for generating the key. The
+ * each element of `collection` through `iteratee`. The corresponding value
+ * of each key is the last element responsible for generating the key. The
* iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee to transform keys.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
});
/**
- * Creates an array of values by running each element in `collection` thru
+ * Creates an array of values by running each element in `collection` through
* `iteratee`. The iteratee is invoked with three arguments:
* (value, index|key, collection).
*
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
*
* The guarded methods are:
- * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
- * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
- * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
- * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
+ * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
+ * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
+ * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
+ * and `words`
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
* @example
*
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
- * The iteratees to sort by.
+ * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
* @param {string[]} [orders] The sort orders of `iteratees`.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
* @returns {Array} Returns the new sorted array.
* @example
*
* var users = [
* { 'user': 'fred', 'age': 48 },
* { 'user': 'barney', 'age': 34 },
- * { 'user': 'fred', 'age': 40 },
+ * { 'user': 'fred', 'age': 42 },
* { 'user': 'barney', 'age': 36 }
* ];
*
* // Sort by `user` in ascending order and by `age` in descending order.
* _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
- * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
*/
function orderBy(collection, iteratees, orders, guard) {
if (collection == null) {
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the array of grouped elements.
* @example
*
/**
* Reduces `collection` to a value which is the accumulated result of running
- * each element in `collection` thru `iteratee`, where each successive
+ * each element in `collection` through `iteratee`, where each successive
* invocation is supplied the return value of the previous. If `accumulator`
- * is not given, the first element of `collection` is used as the initial
+ * is not given the first element of `collection` is used as the initial
* value. The iteratee is invoked with four arguments:
* (accumulator, value, index|key, collection).
*
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @returns {*} Returns the accumulated value.
- * @see _.reduceRight
* @example
*
* _.reduce([1, 2], function(sum, n) {
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @returns {*} Returns the accumulated value.
- * @see _.reduce
* @example
*
* var array = [[0, 1], [2, 3], [4, 5]];
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
- * @see _.filter
* @example
*
* var users = [
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Collection
* @param {Array|Object} collection The collection to sample.
* @returns {*} Returns the random element.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to sample.
- * @param {number} [n=1] The number of elements to sample.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param {number} [n=0] The number of elements to sample.
* @returns {Array} Returns the random elements.
* @example
*
* _.sampleSize([1, 2, 3], 4);
* // => [2, 3, 1]
*/
- function sampleSize(collection, n, guard) {
+ function sampleSize(collection, n) {
var index = -1,
result = toArray(collection),
length = result.length,
lastIndex = length - 1;
- if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
- n = 1;
- } else {
- n = baseClamp(toInteger(n), 0, length);
- }
+ n = baseClamp(toInteger(n), 0, length);
while (++index < n) {
var rand = baseRandom(index, lastIndex),
value = result[rand];
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to shuffle.
* @returns {Array} Returns the new shuffled array.
/**
* Gets the size of `collection` by returning its length for array-like
- * values or the number of own enumerable string keyed properties for objects.
+ * values or the number of own enumerable properties for objects.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to inspect.
* @returns {number} Returns the collection size.
var result = collection.length;
return (result && isString(collection)) ? stringSize(collection) : result;
}
- if (isObjectLike(collection)) {
- var tag = getTag(collection);
- if (tag == mapTag || tag == setTag) {
- return collection.size;
- }
- }
return keys(collection).length;
}
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
* @example
*
* _.some([null, 0, 'yes', false], Boolean);
/**
* Creates an array of elements, sorted in ascending order by the results of
- * running each element in a collection thru each iteratee. This method
+ * running each element in a collection through each iteratee. This method
* performs a stable sort, that is, it preserves the original sort order of
* equal elements. The iteratees are invoked with one argument: (value).
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
- * [iteratees=[_.identity]] The iteratees to sort by.
+ * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
+ * The iteratees to sort by, specified individually or in arrays.
* @returns {Array} Returns the new sorted array.
* @example
*
* var users = [
* { 'user': 'fred', 'age': 48 },
* { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 },
+ * { 'user': 'fred', 'age': 42 },
* { 'user': 'barney', 'age': 34 }
* ];
*
* _.sortBy(users, function(o) { return o.user; });
- * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
*
* _.sortBy(users, ['user', 'age']);
- * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
+ * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
*
* _.sortBy(users, 'user', function(o) {
* return Math.floor(o.age / 10);
* });
- * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
*/
var sortBy = rest(function(collection, iteratees) {
if (collection == null) {
if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
iteratees = [];
} else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
- iteratees = [iteratees[0]];
+ iteratees.length = 1;
}
- iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
- ? iteratees[0]
- : baseFlatten(iteratees, 1, isFlattenableIteratee);
-
- return baseOrderBy(collection, iteratees, []);
+ return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
});
/*------------------------------------------------------------------------*/
*
* @static
* @memberOf _
- * @since 2.4.0
* @type {Function}
* @category Date
* @returns {number} Returns the timestamp.
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
- * // => Logs the number of milliseconds it took for the deferred function to be invoked.
+ * // => logs the number of milliseconds it took for the deferred function to be invoked
*/
var now = Date.now;
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {number} n The number of calls before `func` is invoked.
* @param {Function} func The function to restrict.
* _.forEach(saves, function(type) {
* asyncSave({ 'type': type, 'complete': done });
* });
- * // => Logs 'done saving!' after the two async saves have completed.
+ * // => logs 'done saving!' after the two async saves have completed
*/
function after(n, func) {
if (typeof func != 'function') {
}
/**
- * Creates a function that invokes `func`, with up to `n` arguments,
- * ignoring any additional arguments.
+ * Creates a function that accepts up to `n` arguments, ignoring any
+ * additional arguments.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Function
* @param {Function} func The function to cap arguments for.
* @param {number} [n=func.length] The arity cap.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the new function.
* @example
*
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Function
* @param {number} n The number of calls at which `func` is no longer invoked.
* @param {Function} func The function to restrict.
/**
* Creates a function that invokes `func` with the `this` binding of `thisArg`
- * and `partials` prepended to the arguments it receives.
+ * and prepends any additional `_.bind` arguments to those provided to the
+ * bound function.
*
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for partially applied arguments.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {Function} func The function to bind.
* @param {*} thisArg The `this` binding of `func`.
});
/**
- * Creates a function that invokes the method at `object[key]` with `partials`
- * prepended to the arguments it receives.
+ * Creates a function that invokes the method at `object[key]` and prepends
+ * any additional `_.bindKey` arguments to those provided to the bound function.
*
* This method differs from `_.bind` by allowing bound functions to reference
- * methods that may be redefined or don't yet exist. See
- * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
+ * methods that may be redefined or don't yet exist.
+ * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
* for more details.
*
* The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
*
* @static
* @memberOf _
- * @since 0.10.0
* @category Function
* @param {Object} object The object to invoke the method on.
* @param {string} key The key of the method.
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Function
* @param {Function} func The function to curry.
* @param {number} [arity=func.length] The arity of `func`.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the new curried function.
* @example
*
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Function
* @param {Function} func The function to curry.
* @param {number} [arity=func.length] The arity of `func`.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the new curried function.
* @example
*
* on the trailing edge of the timeout only if the debounced function is
* invoked more than once during the `wait` timeout.
*
- * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+ * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
- * @param {Object} [options={}] The options object.
- * @param {boolean} [options.leading=false]
- * Specify invoking on the leading edge of the timeout.
- * @param {number} [options.maxWait]
- * The maximum time `func` is allowed to be delayed before it's invoked.
- * @param {boolean} [options.trailing=true]
- * Specify invoking on the trailing edge of the timeout.
+ * @param {Object} [options] The options object.
+ * @param {boolean} [options.leading=false] Specify invoking on the leading
+ * edge of the timeout.
+ * @param {number} [options.maxWait] The maximum time `func` is allowed to be
+ * delayed before it's invoked.
+ * @param {boolean} [options.trailing=true] Specify invoking on the trailing
+ * edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
- var lastArgs,
- lastThis,
- maxWait,
+ var args,
+ maxTimeoutId,
result,
- timerId,
- lastCallTime = 0,
- lastInvokeTime = 0,
+ stamp,
+ thisArg,
+ timeoutId,
+ trailingCall,
+ lastCalled = 0,
leading = false,
- maxing = false,
+ maxWait = false,
trailing = true;
if (typeof func != 'function') {
wait = toNumber(wait) || 0;
if (isObject(options)) {
leading = !!options.leading;
- maxing = 'maxWait' in options;
- maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
+ maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
- function invokeFunc(time) {
- var args = lastArgs,
- thisArg = lastThis;
-
- lastArgs = lastThis = undefined;
- lastInvokeTime = time;
- result = func.apply(thisArg, args);
- return result;
- }
-
- function leadingEdge(time) {
- // Reset any `maxWait` timer.
- lastInvokeTime = time;
- // Start the timer for the trailing edge.
- timerId = setTimeout(timerExpired, wait);
- // Invoke the leading edge.
- return leading ? invokeFunc(time) : result;
- }
-
- function remainingWait(time) {
- var timeSinceLastCall = time - lastCallTime,
- timeSinceLastInvoke = time - lastInvokeTime,
- result = wait - timeSinceLastCall;
-
- return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
- }
-
- function shouldInvoke(time) {
- var timeSinceLastCall = time - lastCallTime,
- timeSinceLastInvoke = time - lastInvokeTime;
-
- // Either this is the first call, activity has stopped and we're at the
- // trailing edge, the system time has gone backwards and we're treating
- // it as the trailing edge, or we've hit the `maxWait` limit.
- return (!lastCallTime || (timeSinceLastCall >= wait) ||
- (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
+ function cancel() {
+ if (timeoutId) {
+ clearTimeout(timeoutId);
+ }
+ if (maxTimeoutId) {
+ clearTimeout(maxTimeoutId);
+ }
+ lastCalled = 0;
+ args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
}
- function timerExpired() {
- var time = now();
- if (shouldInvoke(time)) {
- return trailingEdge(time);
+ function complete(isCalled, id) {
+ if (id) {
+ clearTimeout(id);
+ }
+ maxTimeoutId = timeoutId = trailingCall = undefined;
+ if (isCalled) {
+ lastCalled = now();
+ result = func.apply(thisArg, args);
+ if (!timeoutId && !maxTimeoutId) {
+ args = thisArg = undefined;
+ }
}
- // Restart the timer.
- timerId = setTimeout(timerExpired, remainingWait(time));
}
- function trailingEdge(time) {
- clearTimeout(timerId);
- timerId = undefined;
-
- // Only invoke if we have `lastArgs` which means `func` has been
- // debounced at least once.
- if (trailing && lastArgs) {
- return invokeFunc(time);
+ function delayed() {
+ var remaining = wait - (now() - stamp);
+ if (remaining <= 0 || remaining > wait) {
+ complete(trailingCall, maxTimeoutId);
+ } else {
+ timeoutId = setTimeout(delayed, remaining);
}
- lastArgs = lastThis = undefined;
- return result;
}
- function cancel() {
- if (timerId !== undefined) {
- clearTimeout(timerId);
+ function flush() {
+ if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
+ result = func.apply(thisArg, args);
}
- lastCallTime = lastInvokeTime = 0;
- lastArgs = lastThis = timerId = undefined;
+ cancel();
+ return result;
}
- function flush() {
- return timerId === undefined ? result : trailingEdge(now());
+ function maxDelayed() {
+ complete(trailing, timeoutId);
}
function debounced() {
- var time = now(),
- isInvoking = shouldInvoke(time);
+ args = arguments;
+ stamp = now();
+ thisArg = this;
+ trailingCall = trailing && (timeoutId || !leading);
- lastArgs = arguments;
- lastThis = this;
- lastCallTime = time;
+ if (maxWait === false) {
+ var leadingCall = leading && !timeoutId;
+ } else {
+ if (!lastCalled && !maxTimeoutId && !leading) {
+ lastCalled = stamp;
+ }
+ var remaining = maxWait - (stamp - lastCalled);
- if (isInvoking) {
- if (timerId === undefined) {
- return leadingEdge(lastCallTime);
+ var isCalled = (remaining <= 0 || remaining > maxWait) &&
+ (leading || maxTimeoutId);
+
+ if (isCalled) {
+ if (maxTimeoutId) {
+ maxTimeoutId = clearTimeout(maxTimeoutId);
+ }
+ lastCalled = stamp;
+ result = func.apply(thisArg, args);
}
- if (maxing) {
- // Handle invocations in a tight loop.
- clearTimeout(timerId);
- timerId = setTimeout(timerExpired, wait);
- return invokeFunc(lastCallTime);
+ else if (!maxTimeoutId) {
+ maxTimeoutId = setTimeout(maxDelayed, remaining);
}
}
- if (timerId === undefined) {
- timerId = setTimeout(timerExpired, wait);
+ if (isCalled && timeoutId) {
+ timeoutId = clearTimeout(timeoutId);
+ }
+ else if (!timeoutId && wait !== maxWait) {
+ timeoutId = setTimeout(delayed, wait);
+ }
+ if (leadingCall) {
+ isCalled = true;
+ result = func.apply(thisArg, args);
+ }
+ if (isCalled && !timeoutId && !maxTimeoutId) {
+ args = thisArg = undefined;
}
return result;
}
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {Function} func The function to defer.
* @param {...*} [args] The arguments to invoke `func` with.
* _.defer(function(text) {
* console.log(text);
* }, 'deferred');
- * // => Logs 'deferred' after one or more milliseconds.
+ * // => logs 'deferred' after one or more milliseconds
*/
var defer = rest(function(func, args) {
return baseDelay(func, 1, args);
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {Function} func The function to delay.
* @param {number} wait The number of milliseconds to delay invocation.
* _.delay(function(text) {
* console.log(text);
* }, 1000, 'later');
- * // => Logs 'later' after one second.
+ * // => logs 'later' after one second
*/
var delay = rest(function(func, wait, args) {
return baseDelay(func, toNumber(wait) || 0, args);
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Function
* @param {Function} func The function to flip arguments for.
* @returns {Function} Returns the new function.
/**
* Creates a function that memoizes the result of `func`. If `resolver` is
- * provided, it determines the cache key for storing the result based on the
+ * provided it determines the cache key for storing the result based on the
* arguments provided to the memoized function. By default, the first argument
* provided to the memoized function is used as the map cache key. The `func`
* is invoked with the `this` binding of the memoized function.
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
- * constructor with one whose instances implement the
- * [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
+ * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
* method interface of `delete`, `get`, `has`, and `set`.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {Function} func The function to have its output memoized.
* @param {Function} [resolver] The function to resolve the cache key.
memoized.cache = cache.set(key, result);
return result;
};
- memoized.cache = new (memoize.Cache || MapCache);
+ memoized.cache = new memoize.Cache;
return memoized;
}
- // Assign cache to `_.memoize`.
- memoize.Cache = MapCache;
-
/**
* Creates a function that negates the result of the predicate `func`. The
* `func` predicate is invoked with the `this` binding and arguments of the
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Function
* @param {Function} predicate The predicate to negate.
* @returns {Function} Returns the new function.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {Function} func The function to restrict.
* @returns {Function} Returns the new restricted function.
* corresponding `transforms`.
*
* @static
- * @since 4.0.0
* @memberOf _
* @category Function
* @param {Function} func The function to wrap.
- * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
- * [transforms[_.identity]] The functions to transform.
+ * @param {...(Function|Function[])} [transforms] The functions to transform
+ * arguments, specified individually or in arrays.
* @returns {Function} Returns the new function.
* @example
*
* // => [100, 10]
*/
var overArgs = rest(function(func, transforms) {
- transforms = (transforms.length == 1 && isArray(transforms[0]))
- ? arrayMap(transforms[0], baseUnary(getIteratee()))
- : arrayMap(baseFlatten(transforms, 1, isFlattenableIteratee), baseUnary(getIteratee()));
+ transforms = arrayMap(baseFlatten(transforms, 1), getIteratee());
var funcsLength = transforms.length;
return rest(function(args) {
});
/**
- * Creates a function that invokes `func` with `partials` prepended to the
- * arguments it receives. This method is like `_.bind` except it does **not**
- * alter the `this` binding.
+ * Creates a function that invokes `func` with `partial` arguments prepended
+ * to those provided to the new function. This method is like `_.bind` except
+ * it does **not** alter the `this` binding.
*
* The `_.partial.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
* @static
* @memberOf _
- * @since 0.2.0
* @category Function
* @param {Function} func The function to partially apply arguments to.
* @param {...*} [partials] The arguments to be partially applied.
/**
* This method is like `_.partial` except that partially applied arguments
- * are appended to the arguments it receives.
+ * are appended to those provided to the new function.
*
* The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
* @static
* @memberOf _
- * @since 1.0.0
* @category Function
* @param {Function} func The function to partially apply arguments to.
* @param {...*} [partials] The arguments to be partially applied.
/**
* Creates a function that invokes `func` with arguments arranged according
- * to the specified `indexes` where the argument value at the first index is
+ * to the specified indexes where the argument value at the first index is
* provided as the first argument, the argument value at the second index is
* provided as the second argument, and so on.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Function
* @param {Function} func The function to rearrange arguments for.
- * @param {...(number|number[])} indexes The arranged argument indexes.
+ * @param {...(number|number[])} indexes The arranged argument indexes,
+ * specified individually or in arrays.
* @returns {Function} Returns the new function.
* @example
*
/**
* Creates a function that invokes `func` with the `this` binding of the
- * created function and arguments from `start` and beyond provided as
- * an array.
+ * created function and arguments from `start` and beyond provided as an array.
*
- * **Note:** This method is based on the
- * [rest parameter](https://mdn.io/rest_parameters).
+ * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Function
* @param {Function} func The function to apply a rest parameter to.
* @param {number} [start=func.length-1] The start position of the rest parameter.
}
/**
- * Creates a function that invokes `func` with the `this` binding of the
- * create function and an array of arguments much like
- * [`Function#apply`](http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.apply).
+ * Creates a function that invokes `func` with the `this` binding of the created
+ * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
*
- * **Note:** This method is based on the
- * [spread operator](https://mdn.io/spread_operator).
+ * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
*
* @static
* @memberOf _
- * @since 3.2.0
* @category Function
* @param {Function} func The function to spread arguments over.
* @param {number} [start=0] The start position of the spread.
start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
return rest(function(args) {
var array = args[start],
- otherArgs = castSlice(args, 0, start);
+ otherArgs = args.slice(0, start);
if (array) {
arrayPush(otherArgs, array);
* throttled function. Subsequent calls to the throttled function return the
* result of the last `func` invocation.
*
- * **Note:** If `leading` and `trailing` options are `true`, `func` is
- * invoked on the trailing edge of the timeout only if the throttled function
- * is invoked more than once during the `wait` timeout.
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
+ * on the trailing edge of the timeout only if the throttled function is
+ * invoked more than once during the `wait` timeout.
*
- * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+ * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
* for details over the differences between `_.throttle` and `_.debounce`.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {Function} func The function to throttle.
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
- * @param {Object} [options={}] The options object.
- * @param {boolean} [options.leading=true]
- * Specify invoking on the leading edge of the timeout.
- * @param {boolean} [options.trailing=true]
- * Specify invoking on the trailing edge of the timeout.
+ * @param {Object} [options] The options object.
+ * @param {boolean} [options.leading=true] Specify invoking on the leading
+ * edge of the timeout.
+ * @param {boolean} [options.trailing=true] Specify invoking on the trailing
+ * edge of the timeout.
* @returns {Function} Returns the new throttled function.
* @example
*
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Function
* @param {Function} func The function to cap arguments for.
* @returns {Function} Returns the new function.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Function
* @param {*} value The value to wrap.
* @param {Function} [wrapper=identity] The wrapper function.
*
* @static
* @memberOf _
- * @since 4.4.0
* @category Lang
* @param {*} value The value to inspect.
* @returns {Array} Returns the cast array.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to clone.
* @returns {*} Returns the cloned value.
- * @see _.cloneDeep
* @example
*
* var objects = [{ 'a': 1 }, { 'b': 2 }];
* // => true
*/
function clone(value) {
- return baseClone(value, false, true);
+ return baseClone(value);
}
/**
* This method is like `_.clone` except that it accepts `customizer` which
- * is invoked to produce the cloned value. If `customizer` returns `undefined`,
+ * is invoked to produce the cloned value. If `customizer` returns `undefined`
* cloning is handled by the method instead. The `customizer` is invoked with
* up to four arguments; (value [, index|key, object, stack]).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to clone.
* @param {Function} [customizer] The function to customize cloning.
* @returns {*} Returns the cloned value.
- * @see _.cloneDeepWith
* @example
*
* function customizer(value) {
* // => 0
*/
function cloneWith(value, customizer) {
- return baseClone(value, false, true, customizer);
+ return baseClone(value, false, customizer);
}
/**
*
* @static
* @memberOf _
- * @since 1.0.0
* @category Lang
* @param {*} value The value to recursively clone.
* @returns {*} Returns the deep cloned value.
- * @see _.clone
* @example
*
* var objects = [{ 'a': 1 }, { 'b': 2 }];
* // => false
*/
function cloneDeep(value) {
- return baseClone(value, true, true);
+ return baseClone(value, true);
}
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to recursively clone.
* @param {Function} [customizer] The function to customize cloning.
* @returns {*} Returns the deep cloned value.
- * @see _.cloneWith
* @example
*
* function customizer(value) {
* // => 20
*/
function cloneDeepWith(value, customizer) {
- return baseClone(value, true, true, customizer);
+ return baseClone(value, true, customizer);
}
/**
- * Performs a
- * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
*
* @static
* @memberOf _
- * @since 3.9.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if `value` is greater than `other`,
- * else `false`.
- * @see _.lt
+ * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
* @example
*
* _.gt(3, 1);
* _.gt(1, 3);
* // => false
*/
- var gt = createRelationalOperation(baseGt);
+ function gt(value, other) {
+ return value > other;
+ }
/**
* Checks if `value` is greater than or equal to `other`.
*
* @static
* @memberOf _
- * @since 3.9.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if `value` is greater than or equal to
- * `other`, else `false`.
- * @see _.lte
+ * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
* @example
*
* _.gte(3, 1);
* _.gte(1, 3);
* // => false
*/
- var gte = createRelationalOperation(function(value, other) {
+ function gte(value, other) {
return value >= other;
- });
+ }
/**
* Checks if `value` is likely an `arguments` object.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isArguments(function() { return arguments; }());
*
* @static
* @memberOf _
- * @since 0.1.0
* @type {Function}
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
*
* @static
* @memberOf _
- * @since 4.3.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isArrayBuffer(new ArrayBuffer(2));
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* // => false
*/
function isArrayLike(value) {
- return value != null && isLength(getLength(value)) && !isFunction(value);
+ return value != null &&
+ !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
}
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an array-like object,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
* @example
*
* _.isArrayLikeObject([1, 2, 3]);
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isBoolean(false);
*
* @static
* @memberOf _
- * @since 4.3.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isDate(new Date);
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a DOM element,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
* @example
*
* _.isElement(document.body);
}
/**
- * Checks if `value` is an empty object, collection, map, or set.
- *
- * Objects are considered empty if they have no own enumerable string keyed
- * properties.
- *
- * Array-like values such as `arguments` objects, arrays, buffers, strings, or
- * jQuery-like collections are considered empty if they have a `length` of `0`.
- * Similarly, maps and sets are considered empty if they have a `size` of `0`.
+ * Checks if `value` is empty. A value is considered empty unless it's an
+ * `arguments` object, array, string, or jQuery-like collection with a length
+ * greater than `0` or an object with own enumerable properties.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
- * @param {*} value The value to check.
+ * @param {Array|Object|string} value The value to inspect.
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
* @example
*
*/
function isEmpty(value) {
if (isArrayLike(value) &&
- (isArray(value) || isString(value) || isFunction(value.splice) ||
- isArguments(value) || isBuffer(value))) {
+ (isArray(value) || isString(value) ||
+ isFunction(value.splice) || isArguments(value))) {
return !value.length;
}
- if (isObjectLike(value)) {
- var tag = getTag(value);
- if (tag == mapTag || tag == setTag) {
- return !value.size;
- }
- }
for (var key in value) {
if (hasOwnProperty.call(value, key)) {
return false;
}
}
- return !(nonEnumShadows && keys(value).length);
+ return true;
}
/**
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if the values are equivalent,
- * else `false`.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'user': 'fred' };
/**
* This method is like `_.isEqual` except that it accepts `customizer` which
- * is invoked to compare values. If `customizer` returns `undefined`, comparisons
+ * is invoked to compare values. If `customizer` returns `undefined` comparisons
* are handled by the method instead. The `customizer` is invoked with up to
* six arguments: (objValue, othValue [, index|key, object, other, stack]).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @param {Function} [customizer] The function to customize comparisons.
- * @returns {boolean} Returns `true` if the values are equivalent,
- * else `false`.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* function isGreeting(value) {
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an error object,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
* @example
*
* _.isError(new Error);
/**
* Checks if `value` is a finite primitive number.
*
- * **Note:** This method is based on
- * [`Number.isFinite`](https://mdn.io/Number/isFinite).
+ * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a finite number,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
* @example
*
* _.isFinite(3);
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isFunction(_);
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
- // in Safari 8 which returns 'object' for typed array and weak map constructors,
- // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+ // in Safari 8 which returns 'object' for typed array constructors, and
+ // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
var tag = isObject(value) ? objectToString.call(value) : '';
return tag == funcTag || tag == genTag;
}
/**
* Checks if `value` is an integer.
*
- * **Note:** This method is based on
- * [`Number.isInteger`](https://mdn.io/Number/isInteger).
+ * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an integer, else `false`.
/**
* Checks if `value` is a valid array-like length.
*
- * **Note:** This function is loosely based on
- * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a valid length,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
* @example
*
* _.isLength(3);
}
/**
- * Checks if `value` is the
- * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)
- * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
*
* @static
* @memberOf _
- * @since 4.3.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isMap(new Map);
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Lang
* @param {Object} object The object to inspect.
* @param {Object} source The object of property values to match.
/**
* This method is like `_.isMatch` except that it accepts `customizer` which
- * is invoked to compare values. If `customizer` returns `undefined`, comparisons
+ * is invoked to compare values. If `customizer` returns `undefined` comparisons
* are handled by the method instead. The `customizer` is invoked with five
* arguments: (objValue, srcValue, index|key, object, source).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {Object} object The object to inspect.
* @param {Object} source The object of property values to match.
/**
* Checks if `value` is `NaN`.
*
- * **Note:** This method is based on
- * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
- * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
- * `undefined` and other non-number values.
+ * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
+ * which returns `true` for `undefined` and other non-numeric values.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
*/
function isNaN(value) {
// An `NaN` primitive is the only value that is not equal to itself.
- // Perform the `toStringTag` check first to avoid errors with some
- // ActiveX objects in IE.
+ // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
return isNumber(value) && value != +value;
}
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a native function,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
* @example
*
* _.isNative(Array.prototype.push);
* // => false
*/
function isNative(value) {
- if (!isObject(value)) {
+ if (value == null) {
return false;
}
- var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
- return pattern.test(toSource(value));
+ if (isFunction(value)) {
+ return reIsNative.test(funcToString.call(value));
+ }
+ return isObjectLike(value) &&
+ (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
}
/**
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `null`, else `false`.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is nullish, else `false`.
/**
* Checks if `value` is classified as a `Number` primitive or object.
*
- * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
- * classified as numbers, use the `_.isFinite` method.
+ * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
+ * as numbers, use the `_.isFinite` method.
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isNumber(3);
*
* @static
* @memberOf _
- * @since 0.8.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
* function Foo() {
objectToString.call(value) != objectTag || isHostObject(value)) {
return false;
}
- var proto = getPrototype(value);
+ var proto = getPrototypeOf(value);
if (proto === null) {
return true;
}
- var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
+ var Ctor = proto.constructor;
return (typeof Ctor == 'function' &&
Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
}
*
* @static
* @memberOf _
- * @since 0.1.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isRegExp(/abc/);
* Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
* double precision number which isn't the result of a rounded unsafe integer.
*
- * **Note:** This method is based on
- * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
+ * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a safe integer,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
* @example
*
* _.isSafeInteger(3);
*
* @static
* @memberOf _
- * @since 4.3.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isSet(new Set);
* Checks if `value` is classified as a `String` primitive or object.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isString('abc');
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isTypedArray(new Uint8Array);
* Checks if `value` is `undefined`.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Lang
* @param {*} value The value to check.
*
* @static
* @memberOf _
- * @since 4.3.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isWeakMap(new WeakMap);
*
* @static
* @memberOf _
- * @since 4.3.0
* @category Lang
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified,
- * else `false`.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isWeakSet(new WeakSet);
*
* @static
* @memberOf _
- * @since 3.9.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if `value` is less than `other`,
- * else `false`.
- * @see _.gt
+ * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
* @example
*
* _.lt(1, 3);
* _.lt(3, 1);
* // => false
*/
- var lt = createRelationalOperation(baseLt);
+ function lt(value, other) {
+ return value < other;
+ }
/**
* Checks if `value` is less than or equal to `other`.
*
* @static
* @memberOf _
- * @since 3.9.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if `value` is less than or equal to
- * `other`, else `false`.
- * @see _.gte
+ * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
* @example
*
* _.lte(1, 3);
* _.lte(3, 1);
* // => false
*/
- var lte = createRelationalOperation(function(value, other) {
+ function lte(value, other) {
return value <= other;
- });
+ }
/**
* Converts `value` to an array.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Lang
* @param {*} value The value to convert.
/**
* Converts `value` to an integer.
*
- * **Note:** This function is loosely based on
- * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
+ * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted integer.
* Converts `value` to an integer suitable for use as the length of an
* array-like object.
*
- * **Note:** This method is based on
- * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted integer.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {number} Returns the number.
* // => 3
*/
function toNumber(value) {
- if (typeof value == 'number') {
- return value;
- }
- if (isSymbol(value)) {
- return NAN;
- }
if (isObject(value)) {
var other = isFunction(value.valueOf) ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
/**
- * Converts `value` to a plain object flattening inherited enumerable string
- * keyed properties of `value` to own properties of the plain object.
+ * Converts `value` to a plain object flattening inherited enumerable
+ * properties of `value` to own properties of the plain object.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {Object} Returns the converted plain object.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted integer.
}
/**
- * Converts `value` to a string. An empty string is returned for `null`
- * and `undefined` values. The sign of `-0` is preserved.
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {string} Returns the string.
* // => '1,2,3'
*/
function toString(value) {
- return value == null ? '' : baseToString(value);
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
+ }
+ if (value == null) {
+ return '';
+ }
+ if (isSymbol(value)) {
+ return Symbol ? symbolToString.call(value) : '';
+ }
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
/*------------------------------------------------------------------------*/
/**
- * Assigns own enumerable string keyed properties of source objects to the
- * destination object. Source objects are applied from left to right.
- * Subsequent sources overwrite property assignments of previous sources.
+ * Assigns own enumerable properties of source objects to the destination
+ * object. Source objects are applied from left to right. Subsequent sources
+ * overwrite property assignments of previous sources.
*
* **Note:** This method mutates `object` and is loosely based on
* [`Object.assign`](https://mdn.io/Object/assign).
*
* @static
* @memberOf _
- * @since 0.10.0
* @category Object
* @param {Object} object The destination object.
* @param {...Object} [sources] The source objects.
* @returns {Object} Returns `object`.
- * @see _.assignIn
* @example
*
* function Foo() {
* // => { 'a': 1, 'c': 3, 'e': 5 }
*/
var assign = createAssigner(function(object, source) {
- if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
- copyObject(source, keys(source), object);
- return;
- }
- for (var key in source) {
- if (hasOwnProperty.call(source, key)) {
- assignValue(object, key, source[key]);
- }
- }
+ copyObject(source, keys(source), object);
});
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @alias extend
* @category Object
* @param {Object} object The destination object.
* @param {...Object} [sources] The source objects.
* @returns {Object} Returns `object`.
- * @see _.assign
* @example
*
* function Foo() {
* // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
*/
var assignIn = createAssigner(function(object, source) {
- if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
- copyObject(source, keysIn(source), object);
- return;
- }
- for (var key in source) {
- assignValue(object, key, source[key]);
- }
+ copyObject(source, keysIn(source), object);
});
/**
- * This method is like `_.assignIn` except that it accepts `customizer`
- * which is invoked to produce the assigned values. If `customizer` returns
- * `undefined`, assignment is handled by the method instead. The `customizer`
- * is invoked with five arguments: (objValue, srcValue, key, object, source).
+ * This method is like `_.assignIn` except that it accepts `customizer` which
+ * is invoked to produce the assigned values. If `customizer` returns `undefined`
+ * assignment is handled by the method instead. The `customizer` is invoked
+ * with five arguments: (objValue, srcValue, key, object, source).
*
* **Note:** This method mutates `object`.
*
* @static
* @memberOf _
- * @since 4.0.0
* @alias extendWith
* @category Object
* @param {Object} object The destination object.
* @param {...Object} sources The source objects.
* @param {Function} [customizer] The function to customize assigned values.
* @returns {Object} Returns `object`.
- * @see _.assignWith
* @example
*
* function customizer(objValue, srcValue) {
* // => { 'a': 1, 'b': 2 }
*/
var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
- copyObject(source, keysIn(source), object, customizer);
+ copyObjectWith(source, keysIn(source), object, customizer);
});
/**
- * This method is like `_.assign` except that it accepts `customizer`
- * which is invoked to produce the assigned values. If `customizer` returns
- * `undefined`, assignment is handled by the method instead. The `customizer`
- * is invoked with five arguments: (objValue, srcValue, key, object, source).
+ * This method is like `_.assign` except that it accepts `customizer` which
+ * is invoked to produce the assigned values. If `customizer` returns `undefined`
+ * assignment is handled by the method instead. The `customizer` is invoked
+ * with five arguments: (objValue, srcValue, key, object, source).
*
* **Note:** This method mutates `object`.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The destination object.
* @param {...Object} sources The source objects.
* @param {Function} [customizer] The function to customize assigned values.
* @returns {Object} Returns `object`.
- * @see _.assignInWith
* @example
*
* function customizer(objValue, srcValue) {
* // => { 'a': 1, 'b': 2 }
*/
var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
- copyObject(source, keys(source), object, customizer);
+ copyObjectWith(source, keys(source), object, customizer);
});
/**
*
* @static
* @memberOf _
- * @since 1.0.0
* @category Object
* @param {Object} object The object to iterate over.
- * @param {...(string|string[])} [paths] The property paths of elements to pick.
+ * @param {...(string|string[])} [paths] The property paths of elements to pick,
+ * specified individually or in arrays.
* @returns {Array} Returns the new array of picked elements.
* @example
*
});
/**
- * Creates an object that inherits from the `prototype` object. If a
- * `properties` object is given, its own enumerable string keyed properties
- * are assigned to the created object.
+ * Creates an object that inherits from the `prototype` object. If a `properties`
+ * object is given its own enumerable properties are assigned to the created object.
*
* @static
* @memberOf _
- * @since 2.3.0
* @category Object
* @param {Object} prototype The object to inherit from.
* @param {Object} [properties] The properties to assign to the object.
}
/**
- * Assigns own and inherited enumerable string keyed properties of source
- * objects to the destination object for all destination properties that
- * resolve to `undefined`. Source objects are applied from left to right.
- * Once a property is set, additional values of the same property are ignored.
+ * Assigns own and inherited enumerable properties of source objects to the
+ * destination object for all destination properties that resolve to `undefined`.
+ * Source objects are applied from left to right. Once a property is set,
+ * additional values of the same property are ignored.
*
* **Note:** This method mutates `object`.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The destination object.
* @param {...Object} [sources] The source objects.
* @returns {Object} Returns `object`.
- * @see _.defaultsDeep
* @example
*
* _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
*
* @static
* @memberOf _
- * @since 3.10.0
* @category Object
* @param {Object} object The destination object.
* @param {...Object} [sources] The source objects.
* @returns {Object} Returns `object`.
- * @see _.defaults
* @example
*
* _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
*
* @static
* @memberOf _
- * @since 1.1.0
* @category Object
* @param {Object} object The object to search.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
- * @returns {string|undefined} Returns the key of the matched element,
- * else `undefined`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
* @example
*
* var users = {
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Object
* @param {Object} object The object to search.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per iteration.
- * @returns {string|undefined} Returns the key of the matched element,
- * else `undefined`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
* @example
*
* var users = {
}
/**
- * Iterates over own and inherited enumerable string keyed properties of an
- * object and invokes `iteratee` for each property. The iteratee is invoked
- * with three arguments: (value, key, object). Iteratee functions may exit
- * iteration early by explicitly returning `false`.
+ * Iterates over own and inherited enumerable properties of an object invoking
+ * `iteratee` for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
*
* @static
* @memberOf _
- * @since 0.3.0
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns `object`.
- * @see _.forInRight
* @example
*
* function Foo() {
* _.forIn(new Foo, function(value, key) {
* console.log(key);
* });
- * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
+ * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
*/
function forIn(object, iteratee) {
return object == null
? object
- : baseFor(object, getIteratee(iteratee), keysIn);
+ : baseFor(object, baseCastFunction(iteratee), keysIn);
}
/**
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns `object`.
- * @see _.forIn
* @example
*
* function Foo() {
* _.forInRight(new Foo, function(value, key) {
* console.log(key);
* });
- * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
+ * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
*/
function forInRight(object, iteratee) {
return object == null
? object
- : baseForRight(object, getIteratee(iteratee), keysIn);
+ : baseForRight(object, baseCastFunction(iteratee), keysIn);
}
/**
- * Iterates over own enumerable string keyed properties of an object and
- * invokes `iteratee` for each property. The iteratee is invoked with three
- * arguments: (value, key, object). Iteratee functions may exit iteration
- * early by explicitly returning `false`.
+ * Iterates over own enumerable properties of an object invoking `iteratee`
+ * for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by
+ * explicitly returning `false`.
*
* @static
* @memberOf _
- * @since 0.3.0
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns `object`.
- * @see _.forOwnRight
* @example
*
* function Foo() {
* _.forOwn(new Foo, function(value, key) {
* console.log(key);
* });
- * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
*/
function forOwn(object, iteratee) {
- return object && baseForOwn(object, getIteratee(iteratee));
+ return object && baseForOwn(object, baseCastFunction(iteratee));
}
/**
*
* @static
* @memberOf _
- * @since 2.0.0
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns `object`.
- * @see _.forOwn
* @example
*
* function Foo() {
* _.forOwnRight(new Foo, function(value, key) {
* console.log(key);
* });
- * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
+ * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
*/
function forOwnRight(object, iteratee) {
- return object && baseForOwnRight(object, getIteratee(iteratee));
+ return object && baseForOwnRight(object, baseCastFunction(iteratee));
}
/**
* of `object`.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The object to inspect.
* @returns {Array} Returns the new array of property names.
- * @see _.functionsIn
* @example
*
* function Foo() {
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The object to inspect.
* @returns {Array} Returns the new array of property names.
- * @see _.functions
* @example
*
* function Foo() {
/**
* Gets the value at `path` of `object`. If the resolved value is
- * `undefined`, the `defaultValue` is used in its place.
+ * `undefined` the `defaultValue` is used in its place.
*
* @static
* @memberOf _
- * @since 3.7.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
- * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+ * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
* @returns {*} Returns the resolved value.
* @example
*
* Checks if `path` is a direct property of `object`.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {boolean} Returns `true` if `path` exists, else `false`.
* @example
*
- * var object = { 'a': { 'b': 2 } };
- * var other = _.create({ 'a': _.create({ 'b': 2 }) });
+ * var object = { 'a': { 'b': { 'c': 3 } } };
+ * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
*
* _.has(object, 'a');
* // => true
*
- * _.has(object, 'a.b');
+ * _.has(object, 'a.b.c');
* // => true
*
- * _.has(object, ['a', 'b']);
+ * _.has(object, ['a', 'b', 'c']);
* // => true
*
* _.has(other, 'a');
* // => false
*/
function has(object, path) {
- return object != null && hasPath(object, path, baseHas);
+ return hasPath(object, path, baseHas);
}
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path to check.
* @returns {boolean} Returns `true` if `path` exists, else `false`.
* @example
*
- * var object = _.create({ 'a': _.create({ 'b': 2 }) });
+ * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
*
* _.hasIn(object, 'a');
* // => true
*
- * _.hasIn(object, 'a.b');
+ * _.hasIn(object, 'a.b.c');
* // => true
*
- * _.hasIn(object, ['a', 'b']);
+ * _.hasIn(object, ['a', 'b', 'c']);
* // => true
*
* _.hasIn(object, 'b');
* // => false
*/
function hasIn(object, path) {
- return object != null && hasPath(object, path, baseHasIn);
+ return hasPath(object, path, baseHasIn);
}
/**
* Creates an object composed of the inverted keys and values of `object`.
- * If `object` contains duplicate values, subsequent values overwrite
- * property assignments of previous values.
+ * If `object` contains duplicate values, subsequent values overwrite property
+ * assignments of previous values.
*
* @static
* @memberOf _
- * @since 0.7.0
* @category Object
* @param {Object} object The object to invert.
* @returns {Object} Returns the new inverted object.
/**
* This method is like `_.invert` except that the inverted object is generated
- * from the results of running each element of `object` thru `iteratee`. The
- * corresponding inverted value of each inverted key is an array of keys
+ * from the results of running each element of `object` through `iteratee`.
+ * The corresponding inverted value of each inverted key is an array of keys
* responsible for generating the inverted value. The iteratee is invoked
* with one argument: (value).
*
* @static
* @memberOf _
- * @since 4.1.0
* @category Object
* @param {Object} object The object to invert.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Object} Returns the new inverted object.
* @example
*
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path of the method to invoke.
* for more details.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The object to query.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
/**
* The opposite of `_.mapValues`; this method creates an object with the
* same values as `object` and keys generated by running each own enumerable
- * string keyed property of `object` thru `iteratee`. The iteratee is invoked
- * with three arguments: (value, key, object).
+ * property of `object` through `iteratee`. The iteratee is invoked with
+ * three arguments: (value, key, object).
*
* @static
* @memberOf _
- * @since 3.8.0
* @category Object
* @param {Object} object The object to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns the new mapped object.
- * @see _.mapValues
* @example
*
* _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
}
/**
- * Creates an object with the same keys as `object` and values generated
- * by running each own enumerable string keyed property of `object` thru
- * `iteratee`. The iteratee is invoked with three arguments:
- * (value, key, object).
+ * Creates an object with the same keys as `object` and values generated by
+ * running each own enumerable property of `object` through `iteratee`. The
+ * iteratee is invoked with three arguments: (value, key, object).
*
* @static
* @memberOf _
- * @since 2.4.0
* @category Object
* @param {Object} object The object to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The function invoked per iteration.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns the new mapped object.
- * @see _.mapKeys
* @example
*
* var users = {
}
/**
- * This method is like `_.assign` except that it recursively merges own and
- * inherited enumerable string keyed properties of source objects into the
- * destination object. Source properties that resolve to `undefined` are
- * skipped if a destination value exists. Array and plain object properties
- * are merged recursively.Other objects and value types are overridden by
+ * Recursively merges own and inherited enumerable properties of source objects
+ * into the destination object. Source properties that resolve to `undefined`
+ * are skipped if a destination value exists. Array and plain object properties
+ * are merged recursively. Other objects and value types are overridden by
* assignment. Source objects are applied from left to right. Subsequent
* sources overwrite property assignments of previous sources.
*
*
* @static
* @memberOf _
- * @since 0.5.0
* @category Object
* @param {Object} object The destination object.
* @param {...Object} [sources] The source objects.
/**
* This method is like `_.merge` except that it accepts `customizer` which
* is invoked to produce the merged values of the destination and source
- * properties. If `customizer` returns `undefined`, merging is handled by the
+ * properties. If `customizer` returns `undefined` merging is handled by the
* method instead. The `customizer` is invoked with seven arguments:
* (objValue, srcValue, key, object, source, stack).
*
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The destination object.
* @param {...Object} sources The source objects.
/**
* The opposite of `_.pick`; this method creates an object composed of the
- * own and inherited enumerable string keyed properties of `object` that are
- * not omitted.
+ * own and inherited enumerable properties of `object` that are not omitted.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The source object.
- * @param {...(string|string[])} [props] The property identifiers to omit.
+ * @param {...(string|string[])} [props] The property names to omit, specified
+ * individually or in arrays.
* @returns {Object} Returns the new object.
* @example
*
if (object == null) {
return {};
}
- props = arrayMap(baseFlatten(props, 1), toKey);
- return basePick(object, baseDifference(getAllKeysIn(object), props));
+ props = arrayMap(baseFlatten(props, 1), String);
+ return basePick(object, baseDifference(keysIn(object), props));
});
/**
* The opposite of `_.pickBy`; this method creates an object composed of
- * the own and inherited enumerable string keyed properties of `object` that
- * `predicate` doesn't return truthy for. The predicate is invoked with two
- * arguments: (value, key).
+ * the own and inherited enumerable properties of `object` that `predicate`
+ * doesn't return truthy for. The predicate is invoked with two arguments:
+ * (value, key).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The source object.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per property.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
* @returns {Object} Returns the new object.
* @example
*
* Creates an object composed of the picked `object` properties.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The source object.
- * @param {...(string|string[])} [props] The property identifiers to pick.
+ * @param {...(string|string[])} [props] The property names to pick, specified
+ * individually or in arrays.
* @returns {Object} Returns the new object.
* @example
*
* // => { 'a': 1, 'c': 3 }
*/
var pick = rest(function(object, props) {
- return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
+ return object == null ? {} : basePick(object, baseFlatten(props, 1));
});
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The source object.
- * @param {Array|Function|Object|string} [predicate=_.identity]
- * The function invoked per property.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
* @returns {Object} Returns the new object.
* @example
*
}
/**
- * This method is like `_.get` except that if the resolved value is a
- * function it's invoked with the `this` binding of its parent object and
- * its result is returned.
+ * This method is like `_.get` except that if the resolved value is a function
+ * it's invoked with the `this` binding of its parent object and its result
+ * is returned.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to resolve.
- * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+ * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
* @returns {*} Returns the resolved value.
* @example
*
* // => 'default'
*/
function result(object, path, defaultValue) {
- path = isKey(path, object) ? [path] : castPath(path);
-
- var index = -1,
- length = path.length;
-
- // Ensure the loop is entered when path is empty.
- if (!length) {
- object = undefined;
- length = 1;
+ if (!isKey(path, object)) {
+ path = baseCastPath(path);
+ var result = get(object, path);
+ object = parent(object, path);
+ } else {
+ result = object == null ? undefined : object[path];
}
- while (++index < length) {
- var value = object == null ? undefined : object[toKey(path[index])];
- if (value === undefined) {
- index = length;
- value = defaultValue;
- }
- object = isFunction(value) ? value.call(object) : value;
+ if (result === undefined) {
+ result = defaultValue;
}
- return object;
+ return isFunction(result) ? result.call(object) : result;
}
/**
- * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
+ * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
* it's created. Arrays are created for missing index properties while objects
* are created for all other missing properties. Use `_.setWith` to customize
* `path` creation.
*
* @static
* @memberOf _
- * @since 3.7.0
* @category Object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* console.log(object.a[0].b.c);
* // => 4
*
- * _.set(object, ['x', '0', 'y', 'z'], 5);
+ * _.set(object, 'x[0].y.z', 5);
* console.log(object.x[0].y.z);
* // => 5
*/
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @returns {Object} Returns `object`.
* @example
*
- * var object = {};
- *
- * _.setWith(object, '[0][1]', 'a', Object);
- * // => { '0': { '1': 'a' } }
+ * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
+ * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
*/
function setWith(object, path, value, customizer) {
customizer = typeof customizer == 'function' ? customizer : undefined;
}
/**
- * Creates an array of own enumerable string keyed-value pairs for `object`
- * which can be consumed by `_.fromPairs`.
+ * Creates an array of own enumerable key-value pairs for `object` which
+ * can be consumed by `_.fromPairs`.
*
* @static
* @memberOf _
- * @since 4.0.0
- * @alias entries
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the new array of key-value pairs.
}
/**
- * Creates an array of own and inherited enumerable string keyed-value pairs
- * for `object` which can be consumed by `_.fromPairs`.
+ * Creates an array of own and inherited enumerable key-value pairs for
+ * `object` which can be consumed by `_.fromPairs`.
*
* @static
* @memberOf _
- * @since 4.0.0
- * @alias entriesIn
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the new array of key-value pairs.
/**
* An alternative to `_.reduce`; this method transforms `object` to a new
- * `accumulator` object which is the result of running each of its own
- * enumerable string keyed properties thru `iteratee`, with each invocation
- * potentially mutating the `accumulator` object. The iteratee is invoked
- * with four arguments: (accumulator, value, key, object). Iteratee functions
- * may exit iteration early by explicitly returning `false`.
+ * `accumulator` object which is the result of running each of its own enumerable
+ * properties through `iteratee`, with each invocation potentially mutating
+ * the `accumulator` object. The iteratee is invoked with four arguments:
+ * (accumulator, value, key, object). Iteratee functions may exit iteration
+ * early by explicitly returning `false`.
*
* @static
* @memberOf _
- * @since 1.3.0
* @category Object
* @param {Array|Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
if (isArr) {
accumulator = isArray(object) ? new Ctor : [];
} else {
- accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
+ accumulator = isFunction(Ctor) ? baseCreate(getPrototypeOf(object)) : {};
}
} else {
accumulator = {};
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Object
* @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to unset.
* console.log(object);
* // => { 'a': [{ 'b': {} }] };
*
- * _.unset(object, ['a', '0', 'b', 'c']);
+ * _.unset(object, 'a[0].b.c');
* // => true
*
* console.log(object);
}
/**
- * This method is like `_.set` except that accepts `updater` to produce the
- * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
- * is invoked with one argument: (value).
- *
- * **Note:** This method mutates `object`.
- *
- * @static
- * @memberOf _
- * @since 4.6.0
- * @category Object
- * @param {Object} object The object to modify.
- * @param {Array|string} path The path of the property to set.
- * @param {Function} updater The function to produce the updated value.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var object = { 'a': [{ 'b': { 'c': 3 } }] };
- *
- * _.update(object, 'a[0].b.c', function(n) { return n * n; });
- * console.log(object.a[0].b.c);
- * // => 9
- *
- * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
- * console.log(object.x[0].y.z);
- * // => 0
- */
- function update(object, path, updater) {
- return object == null ? object : baseUpdate(object, path, castFunction(updater));
- }
-
- /**
- * This method is like `_.update` except that it accepts `customizer` which is
- * invoked to produce the objects of `path`. If `customizer` returns `undefined`
- * path creation is handled by the method instead. The `customizer` is invoked
- * with three arguments: (nsValue, key, nsObject).
- *
- * **Note:** This method mutates `object`.
- *
- * @static
- * @memberOf _
- * @since 4.6.0
- * @category Object
- * @param {Object} object The object to modify.
- * @param {Array|string} path The path of the property to set.
- * @param {Function} updater The function to produce the updated value.
- * @param {Function} [customizer] The function to customize assigned values.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var object = {};
- *
- * _.updateWith(object, '[0][1]', _.constant('a'), Object);
- * // => { '0': { '1': 'a' } }
- */
- function updateWith(object, path, updater, customizer) {
- customizer = typeof customizer == 'function' ? customizer : undefined;
- return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
- }
-
- /**
- * Creates an array of the own enumerable string keyed property values of `object`.
+ * Creates an array of the own enumerable property values of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The object to query.
}
/**
- * Creates an array of the own and inherited enumerable string keyed property
- * values of `object`.
+ * Creates an array of the own and inherited enumerable property values of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property values.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Number
* @param {number} number The number to clamp.
* @param {number} [lower] The lower bound.
}
/**
- * Checks if `n` is between `start` and up to, but not including, `end`. If
- * `end` is not specified, it's set to `start` with `start` then set to `0`.
+ * Checks if `n` is between `start` and up to but not including, `end`. If
+ * `end` is not specified it's set to `start` with `start` then set to `0`.
* If `start` is greater than `end` the params are swapped to support
* negative ranges.
*
* @static
* @memberOf _
- * @since 3.3.0
* @category Number
* @param {number} number The number to check.
* @param {number} [start=0] The start of the range.
* @param {number} end The end of the range.
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
- * @see _.range, _.rangeRight
* @example
*
* _.inRange(3, 2, 4);
/**
* Produces a random number between the inclusive `lower` and `upper` bounds.
* If only one argument is provided a number between `0` and the given number
- * is returned. If `floating` is `true`, or either `lower` or `upper` are
- * floats, a floating-point number is returned instead of an integer.
+ * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
+ * a floating-point number is returned instead of an integer.
*
* **Note:** JavaScript follows the IEEE-754 standard for resolving
* floating-point values which can produce unexpected results.
*
* @static
* @memberOf _
- * @since 0.7.0
* @category Number
* @param {number} [lower=0] The lower bound.
* @param {number} [upper=1] The upper bound.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the camel cased string.
* _.camelCase('Foo Bar');
* // => 'fooBar'
*
- * _.camelCase('--foo-bar--');
+ * _.camelCase('--foo-bar');
* // => 'fooBar'
*
- * _.camelCase('__FOO_BAR__');
+ * _.camelCase('__foo_bar__');
* // => 'fooBar'
*/
var camelCase = createCompounder(function(result, word, index) {
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to capitalize.
* @returns {string} Returns the capitalized string.
}
/**
- * Deburrs `string` by converting
- * [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
- * to basic latin letters and removing
- * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+ * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+ * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to deburr.
* @returns {string} Returns the deburred string.
*
* @static
* @memberOf _
- * @since 3.0.0
* @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.
- * @returns {boolean} Returns `true` if `string` ends with `target`,
- * else `false`.
+ * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
* @example
*
* _.endsWith('abc', 'c');
*/
function endsWith(string, target, position) {
string = toString(string);
- target = baseToString(target);
+ target = typeof target == 'string' ? target : (target + '');
var length = string.length;
position = position === undefined
*
* Though the ">" character is escaped for symmetry, characters like
* ">" and "/" don't need escaping in HTML and have no special meaning
- * unless they're part of a tag or unquoted attribute value. See
- * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
+ * unless they're part of a tag or unquoted attribute value.
+ * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
* (under "semi-related fun fact") for more details.
*
* Backticks are escaped because in IE < 9, they can break out of
* attribute values or HTML comments. See [#59](https://html5sec.org/#59),
* [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
- * [#133](https://html5sec.org/#133) of the
- * [HTML5 Security Cheatsheet](https://html5sec.org/) for more details.
+ * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
+ * for more details.
*
- * When working with HTML you should always
- * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
- * XSS vectors.
+ * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
+ * to reduce XSS vectors.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category String
* @param {string} [string=''] The string to escape.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to escape.
* @returns {string} Returns the escaped string.
}
/**
- * Converts `string` to
- * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
+ * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the kebab cased string.
* _.kebabCase('fooBar');
* // => 'foo-bar'
*
- * _.kebabCase('__FOO_BAR__');
+ * _.kebabCase('__foo_bar__');
* // => 'foo-bar'
*/
var kebabCase = createCompounder(function(result, word, index) {
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the lower cased string.
* @example
*
- * _.lowerCase('--Foo-Bar--');
+ * _.lowerCase('--Foo-Bar');
* // => 'foo bar'
*
* _.lowerCase('fooBar');
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the converted string.
var lowerFirst = createCaseFirst('toLowerCase');
/**
+ * Converts the first character of `string` to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.upperFirst('fred');
+ * // => 'Fred'
+ *
+ * _.upperFirst('FRED');
+ * // => 'FRED'
+ */
+ var upperFirst = createCaseFirst('toUpperCase');
+
+ /**
* Pads `string` on the left and right sides if it's shorter than `length`.
* Padding characters are truncated if they can't be evenly divided by `length`.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to pad.
* @param {number} [length=0] The padding length.
string = toString(string);
length = toInteger(length);
- var strLength = length ? stringSize(string) : 0;
+ var strLength = stringSize(string);
if (!length || strLength >= length) {
return string;
}
- var mid = (length - strLength) / 2;
- return (
- createPadding(nativeFloor(mid), chars) +
- string +
- createPadding(nativeCeil(mid), chars)
- );
+ var mid = (length - strLength) / 2,
+ leftLength = nativeFloor(mid),
+ rightLength = nativeCeil(mid);
+
+ return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
}
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to pad.
* @param {number} [length=0] The padding length.
*/
function padEnd(string, length, chars) {
string = toString(string);
- length = toInteger(length);
-
- var strLength = length ? stringSize(string) : 0;
- return (length && strLength < length)
- ? (string + createPadding(length - strLength, chars))
- : string;
+ return string + createPadding(string, length, chars);
}
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to pad.
* @param {number} [length=0] The padding length.
*/
function padStart(string, length, chars) {
string = toString(string);
- length = toInteger(length);
-
- var strLength = length ? stringSize(string) : 0;
- return (length && strLength < length)
- ? (createPadding(length - strLength, chars) + string)
- : string;
+ return createPadding(string, length, chars) + string;
}
/**
* Converts `string` to an integer of the specified radix. If `radix` is
- * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
- * hexadecimal, in which case a `radix` of `16` is used.
+ * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
+ * in which case a `radix` of `16` is used.
*
- * **Note:** This method aligns with the
- * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
+ * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
+ * of `parseInt`.
*
* @static
* @memberOf _
- * @since 1.1.0
* @category String
* @param {string} string The string to convert.
* @param {number} [radix=10] The radix to interpret `value` by.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {number} Returns the converted integer.
* @example
*
*/
function parseInt(string, radix, guard) {
// Chrome fails to trim leading <BOM> whitespace characters.
- // See https://bugs.chromium.org/p/v8/issues/detail?id=3109 for more details.
+ // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
if (guard || radix == null) {
radix = 0;
} else if (radix) {
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to repeat.
- * @param {number} [n=1] The number of times to repeat the string.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param {number} [n=0] The number of times to repeat the string.
* @returns {string} Returns the repeated string.
* @example
*
* _.repeat('abc', 0);
* // => ''
*/
- function repeat(string, n, guard) {
- if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
- n = 1;
- } else {
- n = toInteger(n);
+ function repeat(string, n) {
+ string = toString(string);
+ n = toInteger(n);
+
+ var result = '';
+ if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
+ return result;
}
- return baseRepeat(toString(string), n);
+ // Leverage the exponentiation by squaring algorithm for a faster repeat.
+ // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
+ do {
+ if (n % 2) {
+ result += string;
+ }
+ n = nativeFloor(n / 2);
+ string += string;
+ } while (n);
+
+ return result;
}
/**
* Replaces matches for `pattern` in `string` with `replacement`.
*
- * **Note:** This method is based on
- * [`String#replace`](https://mdn.io/String/replace).
+ * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to modify.
* @param {RegExp|string} pattern The pattern to replace.
var args = arguments,
string = toString(args[0]);
- return args.length < 3 ? string : nativeReplace.call(string, args[1], args[2]);
+ return args.length < 3 ? string : string.replace(args[1], args[2]);
}
/**
- * Converts `string` to
- * [snake case](https://en.wikipedia.org/wiki/Snake_case).
+ * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the snake cased string.
* _.snakeCase('fooBar');
* // => 'foo_bar'
*
- * _.snakeCase('--FOO-BAR--');
+ * _.snakeCase('--foo-bar');
* // => 'foo_bar'
*/
var snakeCase = createCompounder(function(result, word, index) {
/**
* Splits `string` by `separator`.
*
- * **Note:** This method is based on
- * [`String#split`](https://mdn.io/String/split).
+ * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to split.
* @param {RegExp|string} separator The separator pattern to split by.
* // => ['a', 'b']
*/
function split(string, separator, limit) {
- if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
- separator = limit = undefined;
- }
- limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
- if (!limit) {
- return [];
- }
- string = toString(string);
- if (string && (
- typeof separator == 'string' ||
- (separator != null && !isRegExp(separator))
- )) {
- separator = baseToString(separator);
- if (separator == '' && reHasComplexSymbol.test(string)) {
- return castSlice(stringToArray(string), 0, limit);
- }
- }
- return nativeSplit.call(string, separator, limit);
+ return toString(string).split(separator, limit);
}
/**
- * Converts `string` to
- * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
+ * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
*
* @static
* @memberOf _
- * @since 3.1.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the start cased string.
* @example
*
- * _.startCase('--foo-bar--');
+ * _.startCase('--foo-bar');
* // => 'Foo Bar'
*
* _.startCase('fooBar');
* // => 'Foo Bar'
*
- * _.startCase('__FOO_BAR__');
- * // => 'FOO BAR'
+ * _.startCase('__foo_bar__');
+ * // => 'Foo Bar'
*/
var startCase = createCompounder(function(result, word, index) {
- return result + (index ? ' ' : '') + upperFirst(word);
+ return result + (index ? ' ' : '') + capitalize(word);
});
/**
*
* @static
* @memberOf _
- * @since 3.0.0
* @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.
- * @returns {boolean} Returns `true` if `string` starts with `target`,
- * else `false`.
+ * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
* @example
*
* _.startsWith('abc', 'a');
function startsWith(string, target, position) {
string = toString(string);
position = baseClamp(toInteger(position), 0, string.length);
- return string.lastIndexOf(baseToString(target), position) == position;
+ return string.lastIndexOf(target, position) == position;
}
/**
* 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 given, it takes precedence over `_.templateSettings` values.
+ * object is given it takes precedence over `_.templateSettings` values.
*
* **Note:** In the development build `_.template` utilizes
* [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
* [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
*
* @static
- * @since 0.1.0
* @memberOf _
* @category String
* @param {string} [string=''] The template string.
- * @param {Object} [options={}] The options object.
- * @param {RegExp} [options.escape=_.templateSettings.escape]
- * The HTML "escape" delimiter.
- * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
- * The "evaluate" delimiter.
- * @param {Object} [options.imports=_.templateSettings.imports]
- * An object to import into the template as free variables.
- * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
- * The "interpolate" delimiter.
- * @param {string} [options.sourceURL='lodash.templateSources[n]']
- * The sourceURL of the compiled template.
- * @param {string} [options.variable='obj']
- * The data object variable name.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param {Object} [options] The options object.
+ * @param {RegExp} [options.escape] The HTML "escape" delimiter.
+ * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
+ * @param {Object} [options.imports] An object to import into the template as free variables.
+ * @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.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the compiled template function.
* @example
*
* // Use the `sourceURL` option to specify a custom sourceURL for the template.
* var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
* compiled(data);
- * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
+ * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
*
* // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
* var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
* ');
*/
function template(string, options, guard) {
- // Based on John Resig's `tmpl` implementation
- // (http://ejohn.org/blog/javascript-micro-templating/)
+ // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
// and Laura Doktorova's doT.js (https://github.com/olado/doT).
var settings = lodash.templateSettings;
}
/**
- * Converts `string`, as a whole, to lower case just like
- * [String#toLowerCase](https://mdn.io/toLowerCase).
+ * Converts `string`, as a whole, to lower case.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the lower cased string.
* @example
*
- * _.toLower('--Foo-Bar--');
- * // => '--foo-bar--'
+ * _.toLower('--Foo-Bar');
+ * // => '--foo-bar'
*
* _.toLower('fooBar');
* // => 'foobar'
}
/**
- * Converts `string`, as a whole, to upper case just like
- * [String#toUpperCase](https://mdn.io/toUpperCase).
+ * Converts `string`, as a whole, to upper case.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the upper cased string.
* @example
*
- * _.toUpper('--foo-bar--');
- * // => '--FOO-BAR--'
+ * _.toUpper('--foo-bar');
+ * // => '--FOO-BAR'
*
* _.toUpper('fooBar');
* // => 'FOOBAR'
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to trim.
* @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {string} Returns the trimmed string.
* @example
*
*/
function trim(string, chars, guard) {
string = toString(string);
- if (string && (guard || chars === undefined)) {
+ if (!string) {
+ return string;
+ }
+ if (guard || chars === undefined) {
return string.replace(reTrim, '');
}
- if (!string || !(chars = baseToString(chars))) {
+ chars = (chars + '');
+ if (!chars) {
return string;
}
var strSymbols = stringToArray(string),
- chrSymbols = stringToArray(chars),
- start = charsStartIndex(strSymbols, chrSymbols),
- end = charsEndIndex(strSymbols, chrSymbols) + 1;
+ chrSymbols = stringToArray(chars);
- return castSlice(strSymbols, start, end).join('');
+ return strSymbols
+ .slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1)
+ .join('');
}
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to trim.
* @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {string} Returns the trimmed string.
* @example
*
*/
function trimEnd(string, chars, guard) {
string = toString(string);
- if (string && (guard || chars === undefined)) {
+ if (!string) {
+ return string;
+ }
+ if (guard || chars === undefined) {
return string.replace(reTrimEnd, '');
}
- if (!string || !(chars = baseToString(chars))) {
+ chars = (chars + '');
+ if (!chars) {
return string;
}
- var strSymbols = stringToArray(string),
- end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
-
- return castSlice(strSymbols, 0, end).join('');
+ var strSymbols = stringToArray(string);
+ return strSymbols
+ .slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1)
+ .join('');
}
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to trim.
* @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {string} Returns the trimmed string.
* @example
*
*/
function trimStart(string, chars, guard) {
string = toString(string);
- if (string && (guard || chars === undefined)) {
+ if (!string) {
+ return string;
+ }
+ if (guard || chars === undefined) {
return string.replace(reTrimStart, '');
}
- if (!string || !(chars = baseToString(chars))) {
+ chars = (chars + '');
+ if (!chars) {
return string;
}
- var strSymbols = stringToArray(string),
- start = charsStartIndex(strSymbols, stringToArray(chars));
-
- return castSlice(strSymbols, start).join('');
+ var strSymbols = stringToArray(string);
+ return strSymbols
+ .slice(charsStartIndex(strSymbols, stringToArray(chars)))
+ .join('');
}
/**
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to truncate.
- * @param {Object} [options={}] The options object.
+ * @param {Object} [options=({})] The options object.
* @param {number} [options.length=30] The maximum string length.
* @param {string} [options.omission='...'] The string to indicate text is omitted.
* @param {RegExp|string} [options.separator] The separator pattern to truncate to.
if (isObject(options)) {
var separator = 'separator' in options ? options.separator : separator;
length = 'length' in options ? toInteger(options.length) : length;
- omission = 'omission' in options ? baseToString(options.omission) : omission;
+ omission = 'omission' in options ? toString(options.omission) : omission;
}
string = toString(string);
return omission;
}
var result = strSymbols
- ? castSlice(strSymbols, 0, end).join('')
+ ? strSymbols.slice(0, end).join('')
: string.slice(0, end);
if (separator === undefined) {
}
result = result.slice(0, newEnd === undefined ? end : newEnd);
}
- } else if (string.indexOf(baseToString(separator), end) != end) {
+ } else if (string.indexOf(separator, end) != end) {
var index = result.lastIndexOf(separator);
if (index > -1) {
result = result.slice(0, index);
/**
* The inverse of `_.escape`; this method converts the HTML entities
- * `&`, `<`, `>`, `"`, `'`, and ``` in `string` to
- * their corresponding characters.
+ * `&`, `<`, `>`, `"`, `'`, and ``` in `string` to their
+ * corresponding characters.
*
- * **Note:** No other HTML entities are unescaped. To unescape additional
- * HTML entities use a third-party library like [_he_](https://mths.be/he).
+ * **Note:** No other HTML entities are unescaped. To unescape additional HTML
+ * entities use a third-party library like [_he_](https://mths.be/he).
*
* @static
* @memberOf _
- * @since 0.6.0
* @category String
* @param {string} [string=''] The string to unescape.
* @returns {string} Returns the unescaped string.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category String
* @param {string} [string=''] The string to convert.
* @returns {string} Returns the upper cased string.
});
/**
- * Converts the first character of `string` to upper case.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category String
- * @param {string} [string=''] The string to convert.
- * @returns {string} Returns the converted string.
- * @example
- *
- * _.upperFirst('fred');
- * // => 'Fred'
- *
- * _.upperFirst('FRED');
- * // => 'FRED'
- */
- var upperFirst = createCaseFirst('toUpperCase');
-
- /**
* Splits `string` into an array of its words.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category String
* @param {string} [string=''] The string to inspect.
* @param {RegExp|string} [pattern] The pattern to match words.
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the words of `string`.
* @example
*
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Util
* @param {Function} func The function to attempt.
- * @param {...*} [args] The arguments to invoke `func` with.
* @returns {*} Returns the `func` result or error object.
* @example
*
* **Note:** This method doesn't set the "length" property of bound functions.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Util
* @param {Object} object The object to bind and assign the bound methods to.
- * @param {...(string|string[])} methodNames The object method names to bind.
+ * @param {...(string|string[])} methodNames The object method names to bind,
+ * specified individually or in arrays.
* @returns {Object} Returns `object`.
* @example
*
*
* _.bindAll(view, 'onClick');
* jQuery(element).on('click', view.onClick);
- * // => Logs 'clicked docs' when clicked.
+ * // => logs 'clicked docs' when clicked
*/
var bindAll = rest(function(object, methodNames) {
arrayEach(baseFlatten(methodNames, 1), function(key) {
- key = toKey(key);
object[key] = bind(object[key], object);
});
return object;
});
/**
- * Creates a function that iterates over `pairs` and invokes the corresponding
+ * Creates a function that iterates over `pairs` invoking the corresponding
* function of the first predicate to return truthy. The predicate-function
* pairs are invoked with the `this` binding and arguments of the created
* function.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Util
* @param {Array} pairs The predicate-function pairs.
* @returns {Function} Returns the new function.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Util
* @param {Object} source The object of property predicates to conform to.
* @returns {Function} Returns the new function.
*
* @static
* @memberOf _
- * @since 2.4.0
* @category Util
* @param {*} value The value to return from the new function.
* @returns {Function} Returns the new function.
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Util
* @param {...(Function|Function[])} [funcs] Functions to invoke.
* @returns {Function} Returns the new function.
- * @see _.flowRight
* @example
*
* function square(n) {
* invokes the given functions from right to left.
*
* @static
- * @since 3.0.0
* @memberOf _
* @category Util
* @param {...(Function|Function[])} [funcs] Functions to invoke.
* @returns {Function} Returns the new function.
- * @see _.flow
* @example
*
* function square(n) {
* This method returns the first argument given to it.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Util
* @param {*} value Any value.
/**
* Creates a function that invokes `func` with the arguments of the created
- * function. If `func` is a property name, the created function returns the
- * property value for a given element. If `func` is an array or object, the
- * created function returns `true` for elements that contain the equivalent
- * source properties, otherwise it returns `false`.
+ * function. If `func` is a property name the created callback returns the
+ * property value for a given element. If `func` is an object the created
+ * callback returns `true` for elements that contain the equivalent object
+ * properties, otherwise it returns `false`.
*
* @static
- * @since 4.0.0
* @memberOf _
* @category Util
* @param {*} [func=_.identity] The value to convert to a callback.
* @example
*
* var users = [
- * { 'user': 'barney', 'age': 36, 'active': true },
- * { 'user': 'fred', 'age': 40, 'active': false }
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 }
* ];
*
- * // The `_.matches` iteratee shorthand.
- * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
- * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
- *
- * // The `_.matchesProperty` iteratee shorthand.
- * _.filter(users, _.iteratee(['user', 'fred']));
- * // => [{ 'user': 'fred', 'age': 40 }]
- *
- * // The `_.property` iteratee shorthand.
- * _.map(users, _.iteratee('user'));
- * // => ['barney', 'fred']
- *
* // Create custom iteratee shorthands.
- * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
- * return !_.isRegExp(func) ? iteratee(func) : function(string) {
- * return func.test(string);
+ * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
+ * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
+ * return !p ? callback(func) : function(object) {
+ * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
* };
* });
*
- * _.filter(['abc', 'def'], /ef/);
- * // => ['def']
+ * _.filter(users, 'age > 36');
+ * // => [{ 'user': 'fred', 'age': 40 }]
*/
function iteratee(func) {
return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Util
* @param {Object} source The object of property values to match.
* @returns {Function} Returns the new function.
*
* @static
* @memberOf _
- * @since 3.2.0
* @category Util
* @param {Array|string} path The path of the property to get.
* @param {*} srcValue The value to match.
*
* @static
* @memberOf _
- * @since 3.7.0
* @category Util
* @param {Array|string} path The path of the method to invoke.
* @param {...*} [args] The arguments to invoke the method with.
* @example
*
* var objects = [
- * { 'a': { 'b': _.constant(2) } },
- * { 'a': { 'b': _.constant(1) } }
+ * { 'a': { 'b': { 'c': _.constant(2) } } },
+ * { 'a': { 'b': { 'c': _.constant(1) } } }
* ];
*
- * _.map(objects, _.method('a.b'));
+ * _.map(objects, _.method('a.b.c'));
* // => [2, 1]
*
- * _.map(objects, _.method(['a', 'b']));
- * // => [2, 1]
+ * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
+ * // => [1, 2]
*/
var method = rest(function(path, args) {
return function(object) {
*
* @static
* @memberOf _
- * @since 3.7.0
* @category Util
* @param {Object} object The object to query.
* @param {...*} [args] The arguments to invoke the method with.
});
/**
- * Adds all own enumerable string keyed function properties of a source
- * object to the destination object. If `object` is a function, then methods
- * are added to its prototype as well.
+ * Adds all own enumerable function properties of a source object to the
+ * destination object. If `object` is a function then methods are added to
+ * its prototype as well.
*
* **Note:** Use `_.runInContext` to create a pristine `lodash` function to
* avoid conflicts caused by modifying the original.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Util
* @param {Function|Object} [object=lodash] The destination object.
* @param {Object} source The object of functions to add.
- * @param {Object} [options={}] The options object.
- * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
+ * @param {Object} [options] The options object.
+ * @param {boolean} [options.chain=true] Specify whether the functions added
+ * are chainable.
* @returns {Function|Object} Returns `object`.
* @example
*
object = this;
methodNames = baseFunctions(source, keys(source));
}
- var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
+ var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
isFunc = isFunction(object);
arrayEach(methodNames, function(methodName) {
* the `lodash` function.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Util
* @returns {Function} Returns the `lodash` function.
*
* @static
* @memberOf _
- * @since 2.3.0
* @category Util
* @example
*
}
/**
- * Creates a function that returns its nth argument. If `n` is negative,
- * the nth argument from the end is returned.
+ * Creates a function that returns its nth argument.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Util
* @param {number} [n=0] The index of the argument to return.
* @returns {Function} Returns the new function.
* @example
*
* var func = _.nthArg(1);
- * func('a', 'b', 'c', 'd');
- * // => 'b'
*
- * var func = _.nthArg(-2);
- * func('a', 'b', 'c', 'd');
- * // => 'c'
+ * func('a', 'b', 'c');
+ * // => 'b'
*/
function nthArg(n) {
n = toInteger(n);
- return rest(function(args) {
- return baseNth(args, n);
- });
+ return function() {
+ return arguments[n];
+ };
}
/**
- * Creates a function that invokes `iteratees` with the arguments it receives
- * and returns their results.
+ * Creates a function that invokes `iteratees` with the arguments provided
+ * to the created function and returns their results.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Util
- * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
- * [iteratees=[_.identity]] The iteratees to invoke.
+ * @param {...(Function|Function[])} iteratees The iteratees to invoke.
* @returns {Function} Returns the new function.
* @example
*
/**
* Creates a function that checks if **all** of the `predicates` return
- * truthy when invoked with the arguments it receives.
+ * truthy when invoked with the arguments provided to the created function.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Util
- * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
- * [predicates=[_.identity]] The predicates to check.
+ * @param {...(Function|Function[])} predicates The predicates to check.
* @returns {Function} Returns the new function.
* @example
*
/**
* Creates a function that checks if **any** of the `predicates` return
- * truthy when invoked with the arguments it receives.
+ * truthy when invoked with the arguments provided to the created function.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Util
- * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
- * [predicates=[_.identity]] The predicates to check.
+ * @param {...(Function|Function[])} predicates The predicates to check.
* @returns {Function} Returns the new function.
* @example
*
*
* @static
* @memberOf _
- * @since 2.4.0
* @category Util
* @param {Array|string} path The path of the property to get.
* @returns {Function} Returns the new function.
* @example
*
* var objects = [
- * { 'a': { 'b': 2 } },
- * { 'a': { 'b': 1 } }
+ * { 'a': { 'b': { 'c': 2 } } },
+ * { 'a': { 'b': { 'c': 1 } } }
* ];
*
- * _.map(objects, _.property('a.b'));
+ * _.map(objects, _.property('a.b.c'));
* // => [2, 1]
*
- * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
+ * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
* // => [1, 2]
*/
function property(path) {
- return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
+ return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
}
/**
*
* @static
* @memberOf _
- * @since 3.0.0
* @category Util
* @param {Object} object The object to query.
* @returns {Function} Returns the new function.
/**
* Creates an array of numbers (positive and/or negative) progressing from
* `start` up to, but not including, `end`. A step of `-1` is used if a negative
- * `start` is specified without an `end` or `step`. If `end` is not specified,
+ * `start` is specified without an `end` or `step`. If `end` is not specified
* it's set to `start` with `start` then set to `0`.
*
* **Note:** JavaScript follows the IEEE-754 standard for resolving
* floating-point values which can produce unexpected results.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Util
* @param {number} [start=0] The start of the range.
* @param {number} end The end of the range.
* @param {number} [step=1] The value to increment or decrement by.
* @returns {Array} Returns the new array of numbers.
- * @see _.inRange, _.rangeRight
* @example
*
* _.range(4);
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Util
* @param {number} [start=0] The start of the range.
* @param {number} end The end of the range.
* @param {number} [step=1] The value to increment or decrement by.
* @returns {Array} Returns the new array of numbers.
- * @see _.inRange, _.range
* @example
*
* _.rangeRight(4);
* each invocation. The iteratee is invoked with one argument; (index).
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Util
* @param {number} n The number of times to invoke `iteratee`.
var index = MAX_ARRAY_LENGTH,
length = nativeMin(n, MAX_ARRAY_LENGTH);
- iteratee = getIteratee(iteratee);
+ iteratee = baseCastFunction(iteratee);
n -= MAX_ARRAY_LENGTH;
var result = baseTimes(length, iteratee);
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Util
* @param {*} value The value to convert.
* @returns {Array} Returns the new property path array.
* // => false
*/
function toPath(value) {
- if (isArray(value)) {
- return arrayMap(value, toKey);
- }
- return isSymbol(value) ? [value] : copyArray(stringToPath(value));
+ return isArray(value) ? arrayMap(value, String) : stringToPath(value);
}
/**
- * Generates a unique ID. If `prefix` is given, the ID is appended to it.
+ * Generates a unique ID. If `prefix` is given the ID is appended to it.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Util
* @param {string} [prefix=''] The value to prefix the ID with.
*
* @static
* @memberOf _
- * @since 3.4.0
* @category Math
* @param {number} augend The first number in an addition.
* @param {number} addend The second number in an addition.
* _.add(6, 4);
* // => 10
*/
- var add = createMathOperation(function(augend, addend) {
- return augend + addend;
- });
+ function add(augend, addend) {
+ var result;
+ if (augend === undefined && addend === undefined) {
+ return 0;
+ }
+ if (augend !== undefined) {
+ result = augend;
+ }
+ if (addend !== undefined) {
+ result = result === undefined ? addend : (result + addend);
+ }
+ return result;
+ }
/**
* Computes `number` rounded up to `precision`.
*
* @static
* @memberOf _
- * @since 3.10.0
* @category Math
* @param {number} number The number to round up.
* @param {number} [precision=0] The precision to round up to.
var ceil = createRound('ceil');
/**
- * Divide two numbers.
- *
- * @static
- * @memberOf _
- * @since 4.7.0
- * @category Math
- * @param {number} dividend The first number in a division.
- * @param {number} divisor The second number in a division.
- * @returns {number} Returns the quotient.
- * @example
- *
- * _.divide(6, 4);
- * // => 1.5
- */
- var divide = createMathOperation(function(dividend, divisor) {
- return dividend / divisor;
- });
-
- /**
* Computes `number` rounded down to `precision`.
*
* @static
* @memberOf _
- * @since 3.10.0
* @category Math
* @param {number} number The number to round down.
* @param {number} [precision=0] The precision to round down to.
var floor = createRound('floor');
/**
- * Computes the maximum value of `array`. If `array` is empty or falsey,
+ * Computes the maximum value of `array`. If `array` is empty or falsey
* `undefined` is returned.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Math
* @param {Array} array The array to iterate over.
*/
function max(array) {
return (array && array.length)
- ? baseExtremum(array, identity, baseGt)
+ ? baseExtremum(array, identity, gt)
: undefined;
}
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Math
* @param {Array} array The array to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {*} Returns the maximum value.
* @example
*
*/
function maxBy(array, iteratee) {
return (array && array.length)
- ? baseExtremum(array, getIteratee(iteratee), baseGt)
+ ? baseExtremum(array, getIteratee(iteratee), gt)
: undefined;
}
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Math
* @param {Array} array The array to iterate over.
* @returns {number} Returns the mean.
* // => 5
*/
function mean(array) {
- return baseMean(array, identity);
+ return sum(array) / (array ? array.length : 0);
}
/**
- * This method is like `_.mean` except that it accepts `iteratee` which is
- * invoked for each element in `array` to generate the value to be averaged.
- * The iteratee is invoked with one argument: (value).
- *
- * @static
- * @memberOf _
- * @since 4.7.0
- * @category Math
- * @param {Array} array The array to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
- * @returns {number} Returns the mean.
- * @example
- *
- * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
- *
- * _.meanBy(objects, function(o) { return o.n; });
- * // => 5
- *
- * // The `_.property` iteratee shorthand.
- * _.meanBy(objects, 'n');
- * // => 5
- */
- function meanBy(array, iteratee) {
- return baseMean(array, getIteratee(iteratee));
- }
-
- /**
- * Computes the minimum value of `array`. If `array` is empty or falsey,
+ * Computes the minimum value of `array`. If `array` is empty or falsey
* `undefined` is returned.
*
* @static
- * @since 0.1.0
* @memberOf _
* @category Math
* @param {Array} array The array to iterate over.
*/
function min(array) {
return (array && array.length)
- ? baseExtremum(array, identity, baseLt)
+ ? baseExtremum(array, identity, lt)
: undefined;
}
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Math
* @param {Array} array The array to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {*} Returns the minimum value.
* @example
*
*/
function minBy(array, iteratee) {
return (array && array.length)
- ? baseExtremum(array, getIteratee(iteratee), baseLt)
+ ? baseExtremum(array, getIteratee(iteratee), lt)
: undefined;
}
/**
- * Multiply two numbers.
- *
- * @static
- * @memberOf _
- * @since 4.7.0
- * @category Math
- * @param {number} multiplier The first number in a multiplication.
- * @param {number} multiplicand The second number in a multiplication.
- * @returns {number} Returns the product.
- * @example
- *
- * _.multiply(6, 4);
- * // => 24
- */
- var multiply = createMathOperation(function(multiplier, multiplicand) {
- return multiplier * multiplicand;
- });
-
- /**
* Computes `number` rounded to `precision`.
*
* @static
* @memberOf _
- * @since 3.10.0
* @category Math
* @param {number} number The number to round.
* @param {number} [precision=0] The precision to round to.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Math
* @param {number} minuend The first number in a subtraction.
* @param {number} subtrahend The second number in a subtraction.
* _.subtract(6, 4);
* // => 2
*/
- var subtract = createMathOperation(function(minuend, subtrahend) {
- return minuend - subtrahend;
- });
+ function subtract(minuend, subtrahend) {
+ var result;
+ if (minuend === undefined && subtrahend === undefined) {
+ return 0;
+ }
+ if (minuend !== undefined) {
+ result = minuend;
+ }
+ if (subtrahend !== undefined) {
+ result = result === undefined ? subtrahend : (result - subtrahend);
+ }
+ return result;
+ }
/**
* Computes the sum of the values in `array`.
*
* @static
* @memberOf _
- * @since 3.4.0
* @category Math
* @param {Array} array The array to iterate over.
* @returns {number} Returns the sum.
*
* @static
* @memberOf _
- * @since 4.0.0
* @category Math
* @param {Array} array The array to iterate over.
- * @param {Array|Function|Object|string} [iteratee=_.identity]
- * The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {number} Returns the sum.
* @example
*
/*------------------------------------------------------------------------*/
- // Add methods that return wrapped values in chain sequences.
+ // Ensure wrappers are instances of `baseLodash`.
+ lodash.prototype = baseLodash.prototype;
+
+ LodashWrapper.prototype = baseCreate(baseLodash.prototype);
+ LodashWrapper.prototype.constructor = LodashWrapper;
+
+ LazyWrapper.prototype = baseCreate(baseLodash.prototype);
+ LazyWrapper.prototype.constructor = LazyWrapper;
+
+ // Avoid inheriting from `Object.prototype` when possible.
+ Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
+
+ // Add functions to the `MapCache`.
+ MapCache.prototype.clear = mapClear;
+ MapCache.prototype['delete'] = mapDelete;
+ MapCache.prototype.get = mapGet;
+ MapCache.prototype.has = mapHas;
+ MapCache.prototype.set = mapSet;
+
+ // Add functions to the `SetCache`.
+ SetCache.prototype.push = cachePush;
+
+ // Add functions to the `Stack` cache.
+ Stack.prototype.clear = stackClear;
+ Stack.prototype['delete'] = stackDelete;
+ Stack.prototype.get = stackGet;
+ Stack.prototype.has = stackHas;
+ Stack.prototype.set = stackSet;
+
+ // Assign cache to `_.memoize`.
+ memoize.Cache = MapCache;
+
+ // Add functions that return wrapped values when chaining.
lodash.after = after;
lodash.ary = ary;
lodash.assign = assign;
lodash.fill = fill;
lodash.filter = filter;
lodash.flatMap = flatMap;
- lodash.flatMapDeep = flatMapDeep;
- lodash.flatMapDepth = flatMapDepth;
lodash.flatten = flatten;
lodash.flattenDeep = flattenDeep;
lodash.flattenDepth = flattenDepth;
lodash.pull = pull;
lodash.pullAll = pullAll;
lodash.pullAllBy = pullAllBy;
- lodash.pullAllWith = pullAllWith;
lodash.pullAt = pullAt;
lodash.range = range;
lodash.rangeRight = rangeRight;
lodash.unset = unset;
lodash.unzip = unzip;
lodash.unzipWith = unzipWith;
- lodash.update = update;
- lodash.updateWith = updateWith;
lodash.values = values;
lodash.valuesIn = valuesIn;
lodash.without = without;
lodash.zipWith = zipWith;
// Add aliases.
- lodash.entries = toPairs;
- lodash.entriesIn = toPairsIn;
lodash.extend = assignIn;
lodash.extendWith = assignInWith;
- // Add methods to `lodash.prototype`.
+ // Add functions to `lodash.prototype`.
mixin(lodash, lodash);
/*------------------------------------------------------------------------*/
- // Add methods that return unwrapped values in chain sequences.
+ // Add functions that return unwrapped values when chaining.
lodash.add = add;
lodash.attempt = attempt;
lodash.camelCase = camelCase;
lodash.cloneDeepWith = cloneDeepWith;
lodash.cloneWith = cloneWith;
lodash.deburr = deburr;
- lodash.divide = divide;
lodash.endsWith = endsWith;
lodash.eq = eq;
lodash.escape = escape;
lodash.max = max;
lodash.maxBy = maxBy;
lodash.mean = mean;
- lodash.meanBy = meanBy;
lodash.min = min;
lodash.minBy = minBy;
- lodash.multiply = multiply;
- lodash.nth = nth;
lodash.noConflict = noConflict;
lodash.noop = noop;
lodash.now = now;
};
});
- // Add `Array` methods to `lodash.prototype`.
+ // Add `Array` and `String` methods to `lodash.prototype`.
arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
var func = arrayProto[methodName],
chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
lodash.prototype[methodName] = function() {
var args = arguments;
if (retUnwrapped && !this.__chain__) {
- var value = this.value();
- return func.apply(isArray(value) ? value : [], args);
+ return func.apply(this.value(), args);
}
return this[chainName](function(value) {
- return func.apply(isArray(value) ? value : [], args);
+ return func.apply(value, args);
});
};
});
- // Map minified method names to their real names.
+ // Map minified function names to their real names.
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
var lodashFunc = lodash[methodName];
if (lodashFunc) {
'func': undefined
}];
- // Add methods to `LazyWrapper`.
+ // Add functions to the lazy wrapper.
LazyWrapper.prototype.clone = lazyClone;
LazyWrapper.prototype.reverse = lazyReverse;
LazyWrapper.prototype.value = lazyValue;
- // Add chain sequence methods to the `lodash` wrapper.
+ // Add chaining functions to the `lodash` wrapper.
lodash.prototype.at = wrapperAt;
lodash.prototype.chain = wrapperChain;
lodash.prototype.commit = wrapperCommit;
+ lodash.prototype.flatMap = wrapperFlatMap;
lodash.prototype.next = wrapperNext;
lodash.prototype.plant = wrapperPlant;
lodash.prototype.reverse = wrapperReverse;
// Export lodash.
var _ = runInContext();
- // Expose Lodash on the free variable `window` or `self` when available so it's
- // globally accessible, even when bundled with Browserify, Webpack, etc. This
- // also prevents errors in cases where Lodash is loaded by a script tag in the
- // presence of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch
- // for more details. Use `_.noConflict` to remove Lodash from the global object.
+ // Expose lodash on the free variable `window` or `self` when available. This
+ // prevents errors in cases where lodash is loaded by a script tag in the presence
+ // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
(freeWindow || freeSelf || {})._ = _;
// Some AMD build optimizers like r.js check for condition patterns like the following: