diff --git a/README.md b/README.md index 2d6f4f44d..89962f8a4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash-amd v4.11.1 +# lodash-amd v4.11.2 The [Lodash](https://lodash.com/) library exported as [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules. @@ -27,4 +27,4 @@ require({ }); ``` -See the [package source](https://github.com/lodash/lodash/tree/4.11.1-amd) for more details. +See the [package source](https://github.com/lodash/lodash/tree/4.11.2-amd) for more details. diff --git a/_baseDifference.js b/_baseDifference.js index b35fe02a9..f495160fe 100644 --- a/_baseDifference.js +++ b/_baseDifference.js @@ -42,6 +42,7 @@ define(['./_SetCache', './_arrayIncludes', './_arrayIncludesWith', './_arrayMap' var value = array[index], computed = iteratee ? iteratee(value) : value; + value = (comparator || value !== 0) ? value : 0; if (isCommon && computed === computed) { var valuesIndex = valuesLength; while (valuesIndex--) { diff --git a/_baseExtremum.js b/_baseExtremum.js index 6f2e9a235..0a0afabc8 100644 --- a/_baseExtremum.js +++ b/_baseExtremum.js @@ -1,4 +1,4 @@ -define([], function() { +define(['./isSymbol'], function(isSymbol) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -22,7 +22,7 @@ define([], function() { current = iteratee(value); if (current != null && (computed === undefined - ? current === current + ? (current === current && !isSymbol(current)) : comparator(current, computed) )) { var computed = current, diff --git a/_baseGet.js b/_baseGet.js index 3ca58cb4f..6a78fac32 100644 --- a/_baseGet.js +++ b/_baseGet.js @@ -1,4 +1,4 @@ -define(['./_castPath', './_isKey'], function(castPath, isKey) { +define(['./_castPath', './_isKey', './_toKey'], function(castPath, isKey, toKey) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -18,7 +18,7 @@ define(['./_castPath', './_isKey'], function(castPath, isKey) { length = path.length; while (object != null && index < length) { - object = object[path[index++]]; + object = object[toKey(path[index++])]; } return (index && index == length) ? object : undefined; } diff --git a/_baseGt.js b/_baseGt.js new file mode 100644 index 000000000..905376ed5 --- /dev/null +++ b/_baseGt.js @@ -0,0 +1,17 @@ +define([], function() { + + /** + * 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; + } + + return baseGt; +}); diff --git a/_baseIntersection.js b/_baseIntersection.js index 820ccb133..36713e09e 100644 --- a/_baseIntersection.js +++ b/_baseIntersection.js @@ -45,6 +45,7 @@ define(['./_SetCache', './_arrayIncludes', './_arrayIncludesWith', './_arrayMap' var value = array[index], computed = iteratee ? iteratee(value) : value; + value = (comparator || value !== 0) ? value : 0; if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator) diff --git a/_baseInvoke.js b/_baseInvoke.js index 64455126f..4e30bab85 100644 --- a/_baseInvoke.js +++ b/_baseInvoke.js @@ -1,4 +1,4 @@ -define(['./_apply', './_castPath', './_isKey', './last', './_parent'], function(apply, castPath, isKey, last, parent) { +define(['./_apply', './_castPath', './_isKey', './last', './_parent', './_toKey'], function(apply, castPath, isKey, last, parent, toKey) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -19,7 +19,7 @@ define(['./_apply', './_castPath', './_isKey', './last', './_parent'], function( object = parent(object, path); path = last(path); } - var func = object == null ? object : object[path]; + var func = object == null ? object : object[toKey(path)]; return func == null ? undefined : apply(func, object, args); } diff --git a/_baseLt.js b/_baseLt.js new file mode 100644 index 000000000..a06cd13b9 --- /dev/null +++ b/_baseLt.js @@ -0,0 +1,17 @@ +define([], function() { + + /** + * 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; + } + + return baseLt; +}); diff --git a/_baseMatchesProperty.js b/_baseMatchesProperty.js index 76f3fabf0..6fc476000 100644 --- a/_baseMatchesProperty.js +++ b/_baseMatchesProperty.js @@ -1,4 +1,4 @@ -define(['./_baseIsEqual', './get', './hasIn', './_isKey', './_isStrictComparable', './_matchesStrictComparable'], function(baseIsEqual, get, hasIn, isKey, isStrictComparable, matchesStrictComparable) { +define(['./_baseIsEqual', './get', './hasIn', './_isKey', './_isStrictComparable', './_matchesStrictComparable', './_toKey'], function(baseIsEqual, get, hasIn, isKey, isStrictComparable, matchesStrictComparable, toKey) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -17,7 +17,7 @@ define(['./_baseIsEqual', './get', './hasIn', './_isKey', './_isStrictComparable */ function baseMatchesProperty(path, srcValue) { if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(path, srcValue); + return matchesStrictComparable(toKey(path), srcValue); } return function(object) { var objValue = get(object, path); diff --git a/_basePullAt.js b/_basePullAt.js index cf0f5d924..7bb00f33c 100644 --- a/_basePullAt.js +++ b/_basePullAt.js @@ -1,4 +1,4 @@ -define(['./_castPath', './_isIndex', './_isKey', './last', './_parent'], function(castPath, isIndex, isKey, last, parent) { +define(['./_castPath', './_isIndex', './_isKey', './last', './_parent', './_toKey'], function(castPath, isIndex, isKey, last, parent, toKey) { /** Used for built-in method references. */ var arrayProto = Array.prototype; @@ -21,7 +21,7 @@ define(['./_castPath', './_isIndex', './_isKey', './last', './_parent'], functio while (length--) { var index = indexes[length]; - if (lastIndex == length || index != previous) { + if (length == lastIndex || index !== previous) { var previous = index; if (isIndex(index)) { splice.call(array, index, 1); @@ -31,11 +31,11 @@ define(['./_castPath', './_isIndex', './_isKey', './last', './_parent'], functio object = parent(array, path); if (object != null) { - delete object[last(path)]; + delete object[toKey(last(path))]; } } else { - delete array[index]; + delete array[toKey(index)]; } } } diff --git a/_baseSet.js b/_baseSet.js index e5c4d6328..112cd3ab2 100644 --- a/_baseSet.js +++ b/_baseSet.js @@ -1,4 +1,4 @@ -define(['./_assignValue', './_castPath', './_isIndex', './_isKey', './isObject'], function(assignValue, castPath, isIndex, isKey, isObject) { +define(['./_assignValue', './_castPath', './_isIndex', './_isKey', './isObject', './_toKey'], function(assignValue, castPath, isIndex, isKey, isObject, toKey) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -22,7 +22,7 @@ define(['./_assignValue', './_castPath', './_isIndex', './_isKey', './isObject'] nested = object; while (nested != null && ++index < length) { - var key = path[index]; + var key = toKey(path[index]); if (isObject(nested)) { var newValue = value; if (index != lastIndex) { diff --git a/_baseSortedIndex.js b/_baseSortedIndex.js index ecbba61d8..3c00940f4 100644 --- a/_baseSortedIndex.js +++ b/_baseSortedIndex.js @@ -1,4 +1,4 @@ -define(['./_baseSortedIndexBy', './identity'], function(baseSortedIndexBy, identity) { +define(['./_baseSortedIndexBy', './identity', './isSymbol'], function(baseSortedIndexBy, identity, isSymbol) { /** Used as references for the maximum length and index of an array. */ var MAX_ARRAY_LENGTH = 4294967295, @@ -25,7 +25,8 @@ define(['./_baseSortedIndexBy', './identity'], function(baseSortedIndexBy, ident var mid = (low + high) >>> 1, computed = array[mid]; - if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + if (computed !== null && !isSymbol(computed) && + (retHighest ? (computed <= value) : (computed < value))) { low = mid + 1; } else { high = mid; diff --git a/_baseSortedIndexBy.js b/_baseSortedIndexBy.js index 45600db89..e62accfd7 100644 --- a/_baseSortedIndexBy.js +++ b/_baseSortedIndexBy.js @@ -1,4 +1,4 @@ -define([], function() { +define(['./isSymbol'], function(isSymbol) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -31,21 +31,26 @@ define([], function() { high = array ? array.length : 0, valIsNaN = value !== value, valIsNull = value === null, - valIsUndef = value === undefined; + valIsSymbol = isSymbol(value), + valIsUndefined = value === undefined; while (low < high) { var mid = nativeFloor((low + high) / 2), computed = iteratee(array[mid]), - isDef = computed !== undefined, - isReflexive = computed === computed; + othIsDefined = computed !== undefined, + othIsNull = computed === null, + othIsReflexive = computed === computed, + othIsSymbol = isSymbol(computed); if (valIsNaN) { - var setLow = isReflexive || retHighest; + var setLow = retHighest || othIsReflexive; + } else if (valIsUndefined) { + setLow = othIsReflexive && (retHighest || othIsDefined); } else if (valIsNull) { - setLow = isReflexive && isDef && (retHighest || computed != null); - } else if (valIsUndef) { - setLow = isReflexive && (retHighest || isDef); - } else if (computed == null) { + setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); + } else if (valIsSymbol) { + setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); + } else if (othIsNull || othIsSymbol) { setLow = false; } else { setLow = retHighest ? (computed <= value) : (computed < value); diff --git a/_baseSortedUniq.js b/_baseSortedUniq.js index 618622529..abc4baef3 100644 --- a/_baseSortedUniq.js +++ b/_baseSortedUniq.js @@ -1,14 +1,30 @@ -define(['./_baseSortedUniqBy'], function(baseSortedUniqBy) { +define(['./eq'], function(eq) { /** - * The base implementation of `_.sortedUniq`. + * The base implementation of `_.sortedUniq` and `_.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) { - return baseSortedUniqBy(array); + function baseSortedUniq(array, iteratee) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!index || !eq(computed, seen)) { + var seen = computed; + result[resIndex++] = value === 0 ? 0 : value; + } + } + return result; } return baseSortedUniq; diff --git a/_baseSortedUniqBy.js b/_baseSortedUniqBy.js deleted file mode 100644 index 56b665e63..000000000 --- a/_baseSortedUniqBy.js +++ /dev/null @@ -1,34 +0,0 @@ -define(['./eq'], function(eq) { - - /** - * 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 baseSortedUniqBy(array, iteratee) { - var index = 0, - length = array.length, - value = array[0], - computed = iteratee ? iteratee(value) : value, - seen = computed, - resIndex = 1, - result = [value]; - - while (++index < length) { - value = array[index], - computed = iteratee ? iteratee(value) : value; - - if (!eq(computed, seen)) { - seen = computed; - result[resIndex++] = value; - } - } - return result; - } - - return baseSortedUniqBy; -}); diff --git a/_baseToNumber.js b/_baseToNumber.js new file mode 100644 index 000000000..cc9fdc79d --- /dev/null +++ b/_baseToNumber.js @@ -0,0 +1,25 @@ +define(['./isSymbol'], function(isSymbol) { + + /** Used as references for various `Number` constants. */ + var NAN = 0 / 0; + + /** + * 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; + } + + return baseToNumber; +}); diff --git a/_baseToString.js b/_baseToString.js new file mode 100644 index 000000000..f075901cb --- /dev/null +++ b/_baseToString.js @@ -0,0 +1,34 @@ +define(['./_Symbol', './isSymbol'], function(Symbol, isSymbol) { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * 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; + } + + return baseToString; +}); diff --git a/_baseUniq.js b/_baseUniq.js index 426b414cc..7688179a7 100644 --- a/_baseUniq.js +++ b/_baseUniq.js @@ -41,6 +41,7 @@ define(['./_SetCache', './_arrayIncludes', './_arrayIncludesWith', './_cacheHas' 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--) { diff --git a/_baseUnset.js b/_baseUnset.js index c819af7b6..8db380046 100644 --- a/_baseUnset.js +++ b/_baseUnset.js @@ -1,4 +1,4 @@ -define(['./_castPath', './has', './_isKey', './last', './_parent'], function(castPath, has, isKey, last, parent) { +define(['./_baseHas', './_castPath', './_isKey', './last', './_parent', './_toKey'], function(baseHas, castPath, isKey, last, parent, toKey) { /** * The base implementation of `_.unset`. @@ -11,8 +11,9 @@ define(['./_castPath', './has', './_isKey', './last', './_parent'], function(cas function baseUnset(object, path) { path = isKey(path, object) ? [path] : castPath(path); object = parent(object, path); - var key = last(path); - return (object != null && has(object, key)) ? delete object[key] : true; + + var key = toKey(last(path)); + return !(object != null && baseHas(object, key)) || delete object[key]; } return baseUnset; diff --git a/_compareAscending.js b/_compareAscending.js index e122875ab..96f8b0609 100644 --- a/_compareAscending.js +++ b/_compareAscending.js @@ -1,4 +1,4 @@ -define([], function() { +define(['./isSymbol'], function(isSymbol) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -13,22 +13,28 @@ define([], function() { */ function compareAscending(value, other) { if (value !== other) { - var valIsNull = value === null, - valIsUndef = value === undefined, - valIsReflexive = value === value; + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = isSymbol(value); - var othIsNull = other === null, - othIsUndef = other === undefined, - othIsReflexive = other === other; + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = isSymbol(other); - if ((value > other && !othIsNull) || !valIsReflexive || - (valIsNull && !othIsUndef && othIsReflexive) || - (valIsUndef && othIsReflexive)) { + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { return 1; } - if ((value < other && !valIsNull) || !othIsReflexive || - (othIsNull && !valIsUndef && valIsReflexive) || - (othIsUndef && valIsReflexive)) { + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { return -1; } } diff --git a/_createMathOperation.js b/_createMathOperation.js index 43adc37a9..1aea44d5c 100644 --- a/_createMathOperation.js +++ b/_createMathOperation.js @@ -1,4 +1,4 @@ -define([], function() { +define(['./_baseToNumber', './_baseToString'], function(baseToNumber, baseToString) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -20,7 +20,17 @@ define([], function() { result = value; } if (other !== undefined) { - result = result === undefined ? other : operator(result, other); + 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; }; diff --git a/_createPadding.js b/_createPadding.js index 75acb8c52..740026c84 100644 --- a/_createPadding.js +++ b/_createPadding.js @@ -1,4 +1,4 @@ -define(['./_baseRepeat', './_castSlice', './_reHasComplexSymbol', './_stringSize', './_stringToArray'], function(baseRepeat, castSlice, reHasComplexSymbol, stringSize, stringToArray) { +define(['./_baseRepeat', './_baseToString', './_castSlice', './_reHasComplexSymbol', './_stringSize', './_stringToArray'], function(baseRepeat, baseToString, castSlice, reHasComplexSymbol, stringSize, stringToArray) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -16,7 +16,7 @@ define(['./_baseRepeat', './_castSlice', './_reHasComplexSymbol', './_stringSize * @returns {string} Returns the padding for `string`. */ function createPadding(length, chars) { - chars = chars === undefined ? ' ' : (chars + ''); + chars = chars === undefined ? ' ' : baseToString(chars); var charsLength = chars.length; if (charsLength < 2) { diff --git a/_createRelationalOperation.js b/_createRelationalOperation.js new file mode 100644 index 000000000..3672c451b --- /dev/null +++ b/_createRelationalOperation.js @@ -0,0 +1,21 @@ +define(['./toNumber'], function(toNumber) { + + /** + * 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); + }; + } + + return createRelationalOperation; +}); diff --git a/_createSet.js b/_createSet.js index d0e2b2188..e79cf1046 100644 --- a/_createSet.js +++ b/_createSet.js @@ -1,4 +1,7 @@ -define(['./_Set', './noop'], function(Set, noop) { +define(['./_Set', './noop', './_setToArray'], function(Set, noop, setToArray) { + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; /** * Creates a set of `values`. @@ -7,7 +10,7 @@ define(['./_Set', './noop'], function(Set, noop) { * @param {Array} values The values to add to the set. * @returns {Object} Returns the new set. */ - var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) { + var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { return new Set(values); }; diff --git a/_hasPath.js b/_hasPath.js index f9f6a87c2..6be909bfc 100644 --- a/_hasPath.js +++ b/_hasPath.js @@ -1,4 +1,4 @@ -define(['./_castPath', './isArguments', './isArray', './_isIndex', './_isKey', './isLength', './isString'], function(castPath, isArguments, isArray, isIndex, isKey, isLength, isString) { +define(['./_castPath', './isArguments', './isArray', './_isIndex', './_isKey', './isLength', './isString', './_toKey'], function(castPath, isArguments, isArray, isIndex, isKey, isLength, isString, toKey) { /** * Checks if `path` exists on `object`. @@ -17,7 +17,7 @@ define(['./_castPath', './isArguments', './isArray', './_isIndex', './_isKey', ' length = path.length; while (++index < length) { - var key = path[index]; + var key = toKey(path[index]); if (!(result = object != null && hasFunc(object, key))) { break; } diff --git a/_isIndex.js b/_isIndex.js index 7644bb037..5ad28ac4c 100644 --- a/_isIndex.js +++ b/_isIndex.js @@ -15,9 +15,10 @@ define([], function() { * @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; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); } return isIndex; diff --git a/_isKey.js b/_isKey.js index 2f45c3ca0..d54bca855 100644 --- a/_isKey.js +++ b/_isKey.js @@ -13,13 +13,16 @@ define(['./isArray', './isSymbol'], function(isArray, isSymbol) { * @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') { + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { return true; } - return !isArray(value) && - (isSymbol(value) || reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object))); + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); } return isKey; diff --git a/_isKeyable.js b/_isKeyable.js index 0ed5cabce..95f1c3614 100644 --- a/_isKeyable.js +++ b/_isKeyable.js @@ -9,8 +9,9 @@ define([], function() { */ function isKeyable(value) { var type = typeof value; - return type == 'number' || type == 'boolean' || - (type == 'string' && value != '__proto__') || value == null; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); } return isKeyable; diff --git a/_toKey.js b/_toKey.js index 965d6ef76..ffe349aca 100644 --- a/_toKey.js +++ b/_toKey.js @@ -1,5 +1,8 @@ define(['./isSymbol'], function(isSymbol) { + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + /** * Converts `value` to a string key if it's not a string or symbol. * @@ -7,8 +10,12 @@ define(['./isSymbol'], function(isSymbol) { * @param {*} value The value to inspect. * @returns {string|symbol} Returns the key. */ - function toKey(key) { - return (typeof key == 'string' || isSymbol(key)) ? key : (key + ''); + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } return toKey; diff --git a/assign.js b/assign.js index 6d5e5e935..438b5c3d4 100644 --- a/assign.js +++ b/assign.js @@ -27,6 +27,7 @@ define(['./_assignValue', './_copyObject', './_createAssigner', './isArrayLike', * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. + * @see _.assignIn * @example * * function Foo() { diff --git a/assignIn.js b/assignIn.js index 2a6986d4a..cd4e1013e 100644 --- a/assignIn.js +++ b/assignIn.js @@ -23,6 +23,7 @@ define(['./_assignValue', './_copyObject', './_createAssigner', './isArrayLike', * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. + * @see _.assign * @example * * function Foo() { diff --git a/assignInWith.js b/assignInWith.js index 228249f6e..6c8f6d4fe 100644 --- a/assignInWith.js +++ b/assignInWith.js @@ -17,6 +17,7 @@ define(['./_copyObject', './_createAssigner', './keysIn'], function(copyObject, * @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) { diff --git a/assignWith.js b/assignWith.js index 5e0fe3212..c687da97a 100644 --- a/assignWith.js +++ b/assignWith.js @@ -16,6 +16,7 @@ define(['./_copyObject', './_createAssigner', './keys'], function(copyObject, cr * @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) { diff --git a/bindAll.js b/bindAll.js index 56b15c78a..0ff8c8a30 100644 --- a/bindAll.js +++ b/bindAll.js @@ -1,4 +1,4 @@ -define(['./_arrayEach', './_baseFlatten', './bind', './rest'], function(arrayEach, baseFlatten, bind, rest) { +define(['./_arrayEach', './_baseFlatten', './bind', './rest', './_toKey'], function(arrayEach, baseFlatten, bind, rest, toKey) { /** * Binds methods of an object to the object itself, overwriting the existing @@ -28,6 +28,7 @@ define(['./_arrayEach', './_baseFlatten', './bind', './rest'], function(arrayEac */ var bindAll = rest(function(object, methodNames) { arrayEach(baseFlatten(methodNames, 1), function(key) { + key = toKey(key); object[key] = bind(object[key], object); }); return object; diff --git a/clone.js b/clone.js index a0efe3a58..37caad72d 100644 --- a/clone.js +++ b/clone.js @@ -17,6 +17,7 @@ define(['./_baseClone'], function(baseClone) { * @category Lang * @param {*} value The value to clone. * @returns {*} Returns the cloned value. + * @see _.cloneDeep * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; diff --git a/cloneDeep.js b/cloneDeep.js index b693fd57c..013c222f5 100644 --- a/cloneDeep.js +++ b/cloneDeep.js @@ -9,6 +9,7 @@ define(['./_baseClone'], function(baseClone) { * @category Lang * @param {*} value The value to recursively clone. * @returns {*} Returns the deep cloned value. + * @see _.clone * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; diff --git a/cloneDeepWith.js b/cloneDeepWith.js index ba5ed4a50..02bb835df 100644 --- a/cloneDeepWith.js +++ b/cloneDeepWith.js @@ -10,6 +10,7 @@ define(['./_baseClone'], function(baseClone) { * @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) { diff --git a/cloneWith.js b/cloneWith.js index f84f1a35a..c0dce3b7c 100644 --- a/cloneWith.js +++ b/cloneWith.js @@ -13,6 +13,7 @@ define(['./_baseClone'], function(baseClone) { * @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) { diff --git a/defaults.js b/defaults.js index 3aaf60141..48ab10866 100644 --- a/defaults.js +++ b/defaults.js @@ -18,6 +18,7 @@ define(['./_apply', './_assignInDefaults', './assignInWith', './rest'], function * @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' }); diff --git a/defaultsDeep.js b/defaultsDeep.js index 45adb30a3..8ef77f116 100644 --- a/defaultsDeep.js +++ b/defaultsDeep.js @@ -16,6 +16,7 @@ define(['./_apply', './_mergeDefaults', './mergeWith', './rest'], function(apply * @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 } }); diff --git a/difference.js b/difference.js index 90e09c7cb..e536198fa 100644 --- a/difference.js +++ b/difference.js @@ -13,6 +13,7 @@ define(['./_baseDifference', './_baseFlatten', './isArrayLikeObject', './rest'], * @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]); diff --git a/endsWith.js b/endsWith.js index a5cb26656..611c26219 100644 --- a/endsWith.js +++ b/endsWith.js @@ -1,4 +1,4 @@ -define(['./_baseClamp', './toInteger', './toString'], function(baseClamp, toInteger, toString) { +define(['./_baseClamp', './_baseToString', './toInteger', './toString'], function(baseClamp, baseToString, toInteger, toString) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -28,7 +28,7 @@ define(['./_baseClamp', './toInteger', './toString'], function(baseClamp, toInte */ function endsWith(string, target, position) { string = toString(string); - target = typeof target == 'string' ? target : (target + ''); + target = baseToString(target); var length = string.length; position = position === undefined diff --git a/filter.js b/filter.js index b4553f4d5..dd2372f90 100644 --- a/filter.js +++ b/filter.js @@ -13,6 +13,7 @@ define(['./_arrayFilter', './_baseFilter', './_baseIteratee', './isArray'], func * @param {Array|Function|Object|string} [predicate=_.identity] * The function invoked per iteration. * @returns {Array} Returns the new filtered array. + * @see _.reject * @example * * var users = [ diff --git a/flow.js b/flow.js index 3111d4411..e0fe8fa8c 100644 --- a/flow.js +++ b/flow.js @@ -11,6 +11,7 @@ define(['./_createFlow'], function(createFlow) { * @category Util * @param {...(Function|Function[])} [funcs] Functions to invoke. * @returns {Function} Returns the new function. + * @see _.flowRight * @example * * function square(n) { diff --git a/flowRight.js b/flowRight.js index 1fc431968..8dbc692ea 100644 --- a/flowRight.js +++ b/flowRight.js @@ -5,11 +5,12 @@ define(['./_createFlow'], function(createFlow) { * invokes the given functions from right to left. * * @static - * @since 0.1.0 + * @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) { diff --git a/forEach.js b/forEach.js index cdbd3dc12..bbbd9e660 100644 --- a/forEach.js +++ b/forEach.js @@ -17,6 +17,7 @@ define(['./_arrayEach', './_baseEach', './_baseIteratee', './isArray'], function * @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) { diff --git a/forEachRight.js b/forEachRight.js index f08a9243a..6ad25a29f 100644 --- a/forEachRight.js +++ b/forEachRight.js @@ -12,6 +12,7 @@ define(['./_arrayEachRight', './_baseEachRight', './_baseIteratee', './isArray'] * @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) { diff --git a/forIn.js b/forIn.js index 8f380bafa..0b4e67a85 100644 --- a/forIn.js +++ b/forIn.js @@ -13,6 +13,7 @@ define(['./_baseFor', './_baseIteratee', './keysIn'], function(baseFor, baseIter * @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() { diff --git a/forInRight.js b/forInRight.js index 525f6f443..4817a0d49 100644 --- a/forInRight.js +++ b/forInRight.js @@ -11,6 +11,7 @@ define(['./_baseForRight', './_baseIteratee', './keysIn'], function(baseForRight * @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() { diff --git a/forOwn.js b/forOwn.js index 4090b2752..50ba223c4 100644 --- a/forOwn.js +++ b/forOwn.js @@ -13,6 +13,7 @@ define(['./_baseForOwn', './_baseIteratee'], function(baseForOwn, baseIteratee) * @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() { diff --git a/forOwnRight.js b/forOwnRight.js index d1ca29db4..927f18927 100644 --- a/forOwnRight.js +++ b/forOwnRight.js @@ -11,6 +11,7 @@ define(['./_baseForOwnRight', './_baseIteratee'], function(baseForOwnRight, base * @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() { diff --git a/functions.js b/functions.js index 4338ad553..ed2b43b2b 100644 --- a/functions.js +++ b/functions.js @@ -10,6 +10,7 @@ define(['./_baseFunctions', './keys'], function(baseFunctions, keys) { * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the new array of property names. + * @see _.functionsIn * @example * * function Foo() { diff --git a/functionsIn.js b/functionsIn.js index 4347a7e79..a0ac3f943 100644 --- a/functionsIn.js +++ b/functionsIn.js @@ -10,6 +10,7 @@ define(['./_baseFunctions', './keysIn'], function(baseFunctions, keysIn) { * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the new array of property names. + * @see _.functions * @example * * function Foo() { diff --git a/gt.js b/gt.js index c83bcd6ec..ef976ddc5 100644 --- a/gt.js +++ b/gt.js @@ -1,4 +1,4 @@ -define([], function() { +define(['./_baseGt', './_createRelationalOperation'], function(baseGt, createRelationalOperation) { /** * Checks if `value` is greater than `other`. @@ -11,6 +11,7 @@ define([], function() { * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than `other`, * else `false`. + * @see _.lt * @example * * _.gt(3, 1); @@ -22,9 +23,7 @@ define([], function() { * _.gt(1, 3); * // => false */ - function gt(value, other) { - return value > other; - } + var gt = createRelationalOperation(baseGt); return gt; }); diff --git a/gte.js b/gte.js index 99dd311f1..576b4c9ff 100644 --- a/gte.js +++ b/gte.js @@ -1,4 +1,4 @@ -define([], function() { +define(['./_createRelationalOperation'], function(createRelationalOperation) { /** * Checks if `value` is greater than or equal to `other`. @@ -11,6 +11,7 @@ define([], function() { * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than or equal to * `other`, else `false`. + * @see _.lte * @example * * _.gte(3, 1); @@ -22,9 +23,9 @@ define([], function() { * _.gte(1, 3); * // => false */ - function gte(value, other) { + var gte = createRelationalOperation(function(value, other) { return value >= other; - } + }); return gte; }); diff --git a/inRange.js b/inRange.js index be6c625c2..ceeaf0499 100644 --- a/inRange.js +++ b/inRange.js @@ -4,7 +4,7 @@ define(['./_baseInRange', './toNumber'], function(baseInRange, toNumber) { var undefined; /** - * Checks if `n` is between `start` and up to but not including, `end`. If + * 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. @@ -17,6 +17,7 @@ define(['./_baseInRange', './toNumber'], function(baseInRange, toNumber) { * @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); diff --git a/lt.js b/lt.js index 2d939ee9e..597446e1c 100644 --- a/lt.js +++ b/lt.js @@ -1,4 +1,4 @@ -define([], function() { +define(['./_baseLt', './_createRelationalOperation'], function(baseLt, createRelationalOperation) { /** * Checks if `value` is less than `other`. @@ -11,6 +11,7 @@ define([], function() { * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than `other`, * else `false`. + * @see _.gt * @example * * _.lt(1, 3); @@ -22,9 +23,7 @@ define([], function() { * _.lt(3, 1); * // => false */ - function lt(value, other) { - return value < other; - } + var lt = createRelationalOperation(baseLt); return lt; }); diff --git a/lte.js b/lte.js index fa5fe65a2..6d127db7a 100644 --- a/lte.js +++ b/lte.js @@ -1,4 +1,4 @@ -define([], function() { +define(['./_createRelationalOperation'], function(createRelationalOperation) { /** * Checks if `value` is less than or equal to `other`. @@ -11,6 +11,7 @@ define([], function() { * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than or equal to * `other`, else `false`. + * @see _.gte * @example * * _.lte(1, 3); @@ -22,9 +23,9 @@ define([], function() { * _.lte(3, 1); * // => false */ - function lte(value, other) { + var lte = createRelationalOperation(function(value, other) { return value <= other; - } + }); return lte; }); diff --git a/main.js b/main.js index dfbcf52a7..e97feac7d 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,6 @@ /** * @license - * lodash 4.11.1 (Custom Build) + * lodash 4.11.2 (Custom Build) * Build: `lodash exports="amd" -d -o ./main.js` * Copyright jQuery Foundation and other contributors * Released under MIT license @@ -13,7 +13,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '4.11.1'; + var VERSION = '4.11.2'; /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; @@ -181,11 +181,11 @@ rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', - rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d', + rsPunctuationRange = '\\u2000-\\u206f', 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 + rsQuoteRange + rsSpaceRange; + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; /** Used to compose unicode capture groups. */ var rsApos = "['\u2019]", @@ -711,35 +711,6 @@ return false; } - /** - * 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 @@ -1018,79 +989,6 @@ return (value && value.Object === Object) ? value : null; } - /** - * 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://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } - /** * Gets the number of `placeholder` occurrences in `array`. * @@ -1111,29 +1009,6 @@ return result; } - /** - * 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) { - result = result === undefined ? other : operator(result, other); - } - return result; - }; - } - /** * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. * @@ -1208,20 +1083,6 @@ return result; } - /** - * 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. * @@ -2560,6 +2421,7 @@ var value = array[index], computed = iteratee ? iteratee(value) : value; + value = (comparator || value !== 0) ? value : 0; if (isCommon && computed === computed) { var valuesIndex = valuesLength; while (valuesIndex--) { @@ -2614,6 +2476,35 @@ return result; } + /** + * 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. * @@ -2773,7 +2664,7 @@ length = path.length; while (object != null && index < length) { - object = object[path[index++]]; + object = object[toKey(path[index++])]; } return (index && index == length) ? object : undefined; } @@ -2796,6 +2687,19 @@ : 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. * @@ -2876,6 +2780,7 @@ var value = array[index], computed = iteratee ? iteratee(value) : value; + value = (comparator || value !== 0) ? value : 0; if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator) @@ -2933,7 +2838,7 @@ object = parent(object, path); path = last(path); } - var func = object == null ? object : object[path]; + var func = object == null ? object : object[toKey(path)]; return func == null ? undefined : apply(func, object, args); } @@ -3135,6 +3040,19 @@ }; } + /** + * 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. * @@ -3180,7 +3098,7 @@ */ function baseMatchesProperty(path, srcValue) { if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(path, srcValue); + return matchesStrictComparable(toKey(path), srcValue); } return function(object) { var objValue = get(object, path); @@ -3462,7 +3380,7 @@ while (length--) { var index = indexes[length]; - if (lastIndex == length || index != previous) { + if (length == lastIndex || index !== previous) { var previous = index; if (isIndex(index)) { splice.call(array, index, 1); @@ -3472,11 +3390,11 @@ object = parent(array, path); if (object != null) { - delete object[last(path)]; + delete object[toKey(last(path))]; } } else { - delete array[index]; + delete array[toKey(index)]; } } } @@ -3566,7 +3484,7 @@ nested = object; while (nested != null && ++index < length) { - var key = path[index]; + var key = toKey(path[index]); if (isObject(nested)) { var newValue = value; if (index != lastIndex) { @@ -3668,7 +3586,8 @@ var mid = (low + high) >>> 1, computed = array[mid]; - if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + if (computed !== null && !isSymbol(computed) && + (retHighest ? (computed <= value) : (computed < value))) { low = mid + 1; } else { high = mid; @@ -3699,21 +3618,26 @@ high = array ? array.length : 0, valIsNaN = value !== value, valIsNull = value === null, - valIsUndef = value === undefined; + valIsSymbol = isSymbol(value), + valIsUndefined = value === undefined; while (low < high) { var mid = nativeFloor((low + high) / 2), computed = iteratee(array[mid]), - isDef = computed !== undefined, - isReflexive = computed === computed; + othIsDefined = computed !== undefined, + othIsNull = computed === null, + othIsReflexive = computed === computed, + othIsSymbol = isSymbol(computed); if (valIsNaN) { - var setLow = isReflexive || retHighest; + var setLow = retHighest || othIsReflexive; + } else if (valIsUndefined) { + setLow = othIsReflexive && (retHighest || othIsDefined); } else if (valIsNull) { - setLow = isReflexive && isDef && (retHighest || computed != null); - } else if (valIsUndef) { - setLow = isReflexive && (retHighest || isDef); - } else if (computed == null) { + setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); + } else if (valIsSymbol) { + setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); + } else if (othIsNull || othIsSymbol) { setLow = false; } else { setLow = retHighest ? (computed <= value) : (computed < value); @@ -3728,46 +3652,70 @@ } /** - * 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. + * The base implementation of `_.sortedUniq` and `_.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 baseSortedUniqBy(array, iteratee) { - var index = 0, + function baseSortedUniq(array, iteratee) { + var index = -1, length = array.length, - value = array[0], - computed = iteratee ? iteratee(value) : value, - seen = computed, - resIndex = 1, - result = [value]; + resIndex = 0, + result = []; while (++index < length) { - value = array[index], - computed = iteratee ? iteratee(value) : value; + var value = array[index], + computed = iteratee ? iteratee(value) : value; - if (!eq(computed, seen)) { - seen = computed; - result[resIndex++] = value; + if (!index || !eq(computed, seen)) { + var seen = computed; + result[resIndex++] = value === 0 ? 0 : 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. * @@ -3806,6 +3754,7 @@ 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--) { @@ -3839,8 +3788,9 @@ function baseUnset(object, path) { path = isKey(path, object) ? [path] : castPath(path); object = parent(object, path); - var key = last(path); - return (object != null && has(object, key)) ? delete object[key] : true; + + var key = toKey(last(path)); + return !(object != null && baseHas(object, key)) || delete object[key]; } /** @@ -4103,6 +4053,85 @@ return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); } + /** + * 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; + } + /** * Creates an array that is the composition of partially applied arguments, * placeholders, and provided arguments into a single array of arguments. @@ -4622,6 +4651,39 @@ }; } + /** + * 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`. * @@ -4654,7 +4716,7 @@ * @returns {string} Returns the padding for `string`. */ function createPadding(length, chars) { - chars = chars === undefined ? ' ' : (chars + ''); + chars = chars === undefined ? ' ' : baseToString(chars); var charsLength = chars.length; if (charsLength < 2) { @@ -4728,6 +4790,23 @@ }; } + /** + * 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. * @@ -4804,7 +4883,7 @@ * @param {Array} values The values to add to the set. * @returns {Object} Returns the new set. */ - var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) { + var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { return new Set(values); }; @@ -5376,7 +5455,7 @@ length = path.length; while (++index < length) { - var key = path[index]; + var key = toKey(path[index]); if (!(result = object != null && hasFunc(object, key))) { break; } @@ -5511,6 +5590,21 @@ 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. * @@ -5544,13 +5638,16 @@ * @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') { + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { return true; } - return !isArray(value) && - (isSymbol(value) || reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object))); + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); } /** @@ -5562,8 +5659,9 @@ */ function isKeyable(value) { var type = typeof value; - return type == 'number' || type == 'boolean' || - (type == 'string' && value != '__proto__') || value == null; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); } /** @@ -5814,8 +5912,12 @@ * @param {*} value The value to inspect. * @returns {string|symbol} Returns the key. */ - function toKey(key) { - return (typeof key == 'string' || isSymbol(key)) ? key : (key + ''); + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } /** @@ -5977,6 +6079,7 @@ * @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]); @@ -6838,10 +6941,15 @@ * // => [10, 20] */ var pullAt = rest(function(array, indexes) { - indexes = arrayMap(baseFlatten(indexes, 1), String); + 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)); - var result = baseAt(array, indexes); - basePullAt(array, indexes.sort(compareAscending)); return result; }); @@ -7148,7 +7256,7 @@ */ function sortedUniqBy(array, iteratee) { return (array && array.length) - ? baseSortedUniqBy(array, getIteratee(iteratee)) + ? baseSortedUniq(array, getIteratee(iteratee)) : []; } @@ -7558,6 +7666,7 @@ * @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); @@ -7581,6 +7690,7 @@ * @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]); @@ -8170,6 +8280,7 @@ * @param {Array|Function|Object|string} [predicate=_.identity] * The function invoked per iteration. * @returns {Array} Returns the new filtered array. + * @see _.reject * @example * * var users = [ @@ -8365,6 +8476,7 @@ * @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) { @@ -8395,6 +8507,7 @@ * @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) { @@ -8707,6 +8820,7 @@ * @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) { @@ -8739,6 +8853,7 @@ * @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]]; @@ -8767,6 +8882,7 @@ * @param {Array|Function|Object|string} [predicate=_.identity] * The function invoked per iteration. * @returns {Array} Returns the new filtered array. + * @see _.filter * @example * * var users = [ @@ -10098,6 +10214,7 @@ * @category Lang * @param {*} value The value to clone. * @returns {*} Returns the cloned value. + * @see _.cloneDeep * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; @@ -10123,6 +10240,7 @@ * @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) { @@ -10153,6 +10271,7 @@ * @category Lang * @param {*} value The value to recursively clone. * @returns {*} Returns the deep cloned value. + * @see _.clone * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; @@ -10175,6 +10294,7 @@ * @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) { @@ -10243,6 +10363,7 @@ * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than `other`, * else `false`. + * @see _.lt * @example * * _.gt(3, 1); @@ -10254,9 +10375,7 @@ * _.gt(1, 3); * // => false */ - function gt(value, other) { - return value > other; - } + var gt = createRelationalOperation(baseGt); /** * Checks if `value` is greater than or equal to `other`. @@ -10269,6 +10388,7 @@ * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than or equal to * `other`, else `false`. + * @see _.lte * @example * * _.gte(3, 1); @@ -10280,9 +10400,9 @@ * _.gte(1, 3); * // => false */ - function gte(value, other) { + var gte = createRelationalOperation(function(value, other) { return value >= other; - } + }); /** * Checks if `value` is likely an `arguments` object. @@ -11321,6 +11441,7 @@ * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than `other`, * else `false`. + * @see _.gt * @example * * _.lt(1, 3); @@ -11332,9 +11453,7 @@ * _.lt(3, 1); * // => false */ - function lt(value, other) { - return value < other; - } + var lt = createRelationalOperation(baseLt); /** * Checks if `value` is less than or equal to `other`. @@ -11347,6 +11466,7 @@ * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than or equal to * `other`, else `false`. + * @see _.gte * @example * * _.lte(1, 3); @@ -11358,9 +11478,9 @@ * _.lte(3, 1); * // => false */ - function lte(value, other) { + var lte = createRelationalOperation(function(value, other) { return value <= other; - } + }); /** * Converts `value` to an array. @@ -11593,18 +11713,7 @@ * // => '1,2,3' */ function toString(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 symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + return value == null ? '' : baseToString(value); } /*------------------------------------------------------------------------*/ @@ -11624,6 +11733,7 @@ * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. + * @see _.assignIn * @example * * function Foo() { @@ -11666,6 +11776,7 @@ * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. + * @see _.assign * @example * * function Foo() { @@ -11709,6 +11820,7 @@ * @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) { @@ -11740,6 +11852,7 @@ * @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) { @@ -11833,6 +11946,7 @@ * @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' }); @@ -11856,6 +11970,7 @@ * @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 } }); @@ -11960,6 +12075,7 @@ * @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() { @@ -11991,6 +12107,7 @@ * @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() { @@ -12024,6 +12141,7 @@ * @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() { @@ -12053,6 +12171,7 @@ * @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() { @@ -12081,6 +12200,7 @@ * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the new array of property names. + * @see _.functionsIn * @example * * function Foo() { @@ -12107,6 +12227,7 @@ * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the new array of property names. + * @see _.functions * @example * * function Foo() { @@ -12396,6 +12517,7 @@ * @param {Array|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) { @@ -12427,6 +12549,7 @@ * @param {Array|Function|Object|string} [iteratee=_.identity] * The function invoked per iteration. * @returns {Object} Returns the new mapped object. + * @see _.mapKeys * @example * * var users = { @@ -12601,7 +12724,7 @@ * // => { 'a': 1, 'c': 3 } */ var pick = rest(function(object, props) { - return object == null ? {} : basePick(object, baseFlatten(props, 1)); + return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey)); }); /** @@ -12668,7 +12791,7 @@ length = 1; } while (++index < length) { - var value = object == null ? undefined : object[path[index]]; + var value = object == null ? undefined : object[toKey(path[index])]; if (value === undefined) { index = length; value = defaultValue; @@ -13031,7 +13154,7 @@ } /** - * Checks if `n` is between `start` and up to but not including, `end`. If + * 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. @@ -13044,6 +13167,7 @@ * @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); @@ -13242,7 +13366,7 @@ */ function endsWith(string, target, position) { string = toString(string); - target = typeof target == 'string' ? target : (target + ''); + target = baseToString(target); var length = string.length; position = position === undefined @@ -13639,7 +13763,7 @@ typeof separator == 'string' || (separator != null && !isRegExp(separator)) )) { - separator += ''; + separator = baseToString(separator); if (separator == '' && reHasComplexSymbol.test(string)) { return castSlice(stringToArray(string), 0, limit); } @@ -13698,7 +13822,7 @@ function startsWith(string, target, position) { string = toString(string); position = baseClamp(toInteger(position), 0, string.length); - return string.lastIndexOf(target, position) == position; + return string.lastIndexOf(baseToString(target), position) == position; } /** @@ -13986,13 +14110,10 @@ */ function trim(string, chars, guard) { string = toString(string); - if (!string) { - return string; - } - if (guard || chars === undefined) { + if (string && (guard || chars === undefined)) { return string.replace(reTrim, ''); } - if (!(chars += '')) { + if (!string || !(chars = baseToString(chars))) { return string; } var strSymbols = stringToArray(string), @@ -14024,13 +14145,10 @@ */ function trimEnd(string, chars, guard) { string = toString(string); - if (!string) { - return string; - } - if (guard || chars === undefined) { + if (string && (guard || chars === undefined)) { return string.replace(reTrimEnd, ''); } - if (!(chars += '')) { + if (!string || !(chars = baseToString(chars))) { return string; } var strSymbols = stringToArray(string), @@ -14060,13 +14178,10 @@ */ function trimStart(string, chars, guard) { string = toString(string); - if (!string) { - return string; - } - if (guard || chars === undefined) { + if (string && (guard || chars === undefined)) { return string.replace(reTrimStart, ''); } - if (!(chars += '')) { + if (!string || !(chars = baseToString(chars))) { return string; } var strSymbols = stringToArray(string), @@ -14119,7 +14234,7 @@ if (isObject(options)) { var separator = 'separator' in options ? options.separator : separator; length = 'length' in options ? toInteger(options.length) : length; - omission = 'omission' in options ? toString(options.omission) : omission; + omission = 'omission' in options ? baseToString(options.omission) : omission; } string = toString(string); @@ -14159,7 +14274,7 @@ } result = result.slice(0, newEnd === undefined ? end : newEnd); } - } else if (string.indexOf(separator, end) != end) { + } else if (string.indexOf(baseToString(separator), end) != end) { var index = result.lastIndexOf(separator); if (index > -1) { result = result.slice(0, index); @@ -14326,6 +14441,7 @@ */ var bindAll = rest(function(object, methodNames) { arrayEach(baseFlatten(methodNames, 1), function(key) { + key = toKey(key); object[key] = bind(object[key], object); }); return object; @@ -14441,6 +14557,7 @@ * @category Util * @param {...(Function|Function[])} [funcs] Functions to invoke. * @returns {Function} Returns the new function. + * @see _.flowRight * @example * * function square(n) { @@ -14458,11 +14575,12 @@ * invokes the given functions from right to left. * * @static - * @since 0.1.0 + * @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) { @@ -14889,7 +15007,7 @@ * // => [1, 2] */ function property(path) { - return isKey(path) ? baseProperty(path) : basePropertyDeep(path); + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); } /** @@ -14936,6 +15054,7 @@ * @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); @@ -14973,6 +15092,7 @@ * @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); @@ -15196,7 +15316,7 @@ */ function max(array) { return (array && array.length) - ? baseExtremum(array, identity, gt) + ? baseExtremum(array, identity, baseGt) : undefined; } @@ -15226,7 +15346,7 @@ */ function maxBy(array, iteratee) { return (array && array.length) - ? baseExtremum(array, getIteratee(iteratee), gt) + ? baseExtremum(array, getIteratee(iteratee), baseGt) : undefined; } @@ -15296,7 +15416,7 @@ */ function min(array) { return (array && array.length) - ? baseExtremum(array, identity, lt) + ? baseExtremum(array, identity, baseLt) : undefined; } @@ -15326,7 +15446,7 @@ */ function minBy(array, iteratee) { return (array && array.length) - ? baseExtremum(array, getIteratee(iteratee), lt) + ? baseExtremum(array, getIteratee(iteratee), baseLt) : undefined; } @@ -15998,9 +16118,11 @@ // Export lodash. var _ = runInContext(); - // 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. + // 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. (freeWindow || freeSelf || {})._ = _; // Some AMD build optimizers like r.js check for condition patterns like the following: diff --git a/mapKeys.js b/mapKeys.js index a305d0f1d..18808948c 100644 --- a/mapKeys.js +++ b/mapKeys.js @@ -14,6 +14,7 @@ define(['./_baseForOwn', './_baseIteratee'], function(baseForOwn, baseIteratee) * @param {Array|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) { diff --git a/mapValues.js b/mapValues.js index d24360775..5406aeb32 100644 --- a/mapValues.js +++ b/mapValues.js @@ -14,6 +14,7 @@ define(['./_baseForOwn', './_baseIteratee'], function(baseForOwn, baseIteratee) * @param {Array|Function|Object|string} [iteratee=_.identity] * The function invoked per iteration. * @returns {Object} Returns the new mapped object. + * @see _.mapKeys * @example * * var users = { diff --git a/max.js b/max.js index f0d7579db..070ce9282 100644 --- a/max.js +++ b/max.js @@ -1,4 +1,4 @@ -define(['./_baseExtremum', './gt', './identity'], function(baseExtremum, gt, identity) { +define(['./_baseExtremum', './_baseGt', './identity'], function(baseExtremum, baseGt, identity) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -23,7 +23,7 @@ define(['./_baseExtremum', './gt', './identity'], function(baseExtremum, gt, ide */ function max(array) { return (array && array.length) - ? baseExtremum(array, identity, gt) + ? baseExtremum(array, identity, baseGt) : undefined; } diff --git a/maxBy.js b/maxBy.js index 0f5e9e608..36230a3f8 100644 --- a/maxBy.js +++ b/maxBy.js @@ -1,4 +1,4 @@ -define(['./_baseExtremum', './_baseIteratee', './gt'], function(baseExtremum, baseIteratee, gt) { +define(['./_baseExtremum', './_baseGt', './_baseIteratee'], function(baseExtremum, baseGt, baseIteratee) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -29,7 +29,7 @@ define(['./_baseExtremum', './_baseIteratee', './gt'], function(baseExtremum, ba */ function maxBy(array, iteratee) { return (array && array.length) - ? baseExtremum(array, baseIteratee(iteratee), gt) + ? baseExtremum(array, baseIteratee(iteratee), baseGt) : undefined; } diff --git a/min.js b/min.js index f6722baed..b6b35bec5 100644 --- a/min.js +++ b/min.js @@ -1,4 +1,4 @@ -define(['./_baseExtremum', './identity', './lt'], function(baseExtremum, identity, lt) { +define(['./_baseExtremum', './_baseLt', './identity'], function(baseExtremum, baseLt, identity) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -23,7 +23,7 @@ define(['./_baseExtremum', './identity', './lt'], function(baseExtremum, identit */ function min(array) { return (array && array.length) - ? baseExtremum(array, identity, lt) + ? baseExtremum(array, identity, baseLt) : undefined; } diff --git a/minBy.js b/minBy.js index 99cdb108d..9b74a4ade 100644 --- a/minBy.js +++ b/minBy.js @@ -1,4 +1,4 @@ -define(['./_baseExtremum', './_baseIteratee', './lt'], function(baseExtremum, baseIteratee, lt) { +define(['./_baseExtremum', './_baseIteratee', './_baseLt'], function(baseExtremum, baseIteratee, baseLt) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -29,7 +29,7 @@ define(['./_baseExtremum', './_baseIteratee', './lt'], function(baseExtremum, ba */ function minBy(array, iteratee) { return (array && array.length) - ? baseExtremum(array, baseIteratee(iteratee), lt) + ? baseExtremum(array, baseIteratee(iteratee), baseLt) : undefined; } diff --git a/package.json b/package.json index 68ae9ff7c..131f325dc 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,19 @@ { "name": "lodash-amd", - "version": "4.11.1", + "version": "4.11.2", "description": "Lodash exported as AMD modules.", + "keywords": "amd, modules, stdlib, util", "homepage": "https://lodash.com/custom-builds", + "bugs": "https://github.com/lodash/lodash-cli/issues", + "repository": "lodash/lodash", "license": "MIT", "private": true, "main": "main.js", - "keywords": "amd, modules, stdlib, util", "author": "John-David Dalton (http://allyoucanleet.com/)", "contributors": [ "John-David Dalton (http://allyoucanleet.com/)", "Blaine Bublitz (https://github.com/phated)", "Mathias Bynens (https://mathiasbynens.be/)" ], - "bugs": "https://github.com/lodash/lodash-cli/issues", - "repository": "lodash/lodash", "scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" } } diff --git a/pick.js b/pick.js index 14c45b3d1..c3e9694a8 100644 --- a/pick.js +++ b/pick.js @@ -1,4 +1,4 @@ -define(['./_baseFlatten', './_basePick', './rest'], function(baseFlatten, basePick, rest) { +define(['./_arrayMap', './_baseFlatten', './_basePick', './rest', './_toKey'], function(arrayMap, baseFlatten, basePick, rest, toKey) { /** * Creates an object composed of the picked `object` properties. @@ -18,7 +18,7 @@ define(['./_baseFlatten', './_basePick', './rest'], function(baseFlatten, basePi * // => { 'a': 1, 'c': 3 } */ var pick = rest(function(object, props) { - return object == null ? {} : basePick(object, baseFlatten(props, 1)); + return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey)); }); return pick; diff --git a/property.js b/property.js index 7a433dad8..3b189ab63 100644 --- a/property.js +++ b/property.js @@ -1,4 +1,4 @@ -define(['./_baseProperty', './_basePropertyDeep', './_isKey'], function(baseProperty, basePropertyDeep, isKey) { +define(['./_baseProperty', './_basePropertyDeep', './_isKey', './_toKey'], function(baseProperty, basePropertyDeep, isKey, toKey) { /** * Creates a function that returns the value at `path` of a given object. @@ -23,7 +23,7 @@ define(['./_baseProperty', './_basePropertyDeep', './_isKey'], function(baseProp * // => [1, 2] */ function property(path) { - return isKey(path) ? baseProperty(path) : basePropertyDeep(path); + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); } return property; diff --git a/pullAt.js b/pullAt.js index 763370356..438c6106f 100644 --- a/pullAt.js +++ b/pullAt.js @@ -1,4 +1,4 @@ -define(['./_arrayMap', './_baseAt', './_baseFlatten', './_basePullAt', './_compareAscending', './rest'], function(arrayMap, baseAt, baseFlatten, basePullAt, compareAscending, rest) { +define(['./_arrayMap', './_baseAt', './_baseFlatten', './_basePullAt', './_compareAscending', './_isIndex', './rest'], function(arrayMap, baseAt, baseFlatten, basePullAt, compareAscending, isIndex, rest) { /** * Removes elements from `array` corresponding to `indexes` and returns an @@ -25,10 +25,15 @@ define(['./_arrayMap', './_baseAt', './_baseFlatten', './_basePullAt', './_compa * // => [10, 20] */ var pullAt = rest(function(array, indexes) { - indexes = arrayMap(baseFlatten(indexes, 1), String); + 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)); - var result = baseAt(array, indexes); - basePullAt(array, indexes.sort(compareAscending)); return result; }); diff --git a/range.js b/range.js index 1637f2ea2..81097ec30 100644 --- a/range.js +++ b/range.js @@ -17,6 +17,7 @@ define(['./_createRange'], function(createRange) { * @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); diff --git a/rangeRight.js b/rangeRight.js index aff1f286b..4b84e9903 100644 --- a/rangeRight.js +++ b/rangeRight.js @@ -12,6 +12,7 @@ define(['./_createRange'], function(createRange) { * @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); diff --git a/reduce.js b/reduce.js index f4b00e35a..32ef31ace 100644 --- a/reduce.js +++ b/reduce.js @@ -23,6 +23,7 @@ define(['./_arrayReduce', './_baseEach', './_baseIteratee', './_baseReduce', './ * @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) { diff --git a/reduceRight.js b/reduceRight.js index 5d4af66cb..368654816 100644 --- a/reduceRight.js +++ b/reduceRight.js @@ -12,6 +12,7 @@ define(['./_arrayReduceRight', './_baseEachRight', './_baseIteratee', './_baseRe * @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]]; diff --git a/reject.js b/reject.js index 0b2844214..8c3678ef6 100644 --- a/reject.js +++ b/reject.js @@ -12,6 +12,7 @@ define(['./_arrayFilter', './_baseFilter', './_baseIteratee', './isArray'], func * @param {Array|Function|Object|string} [predicate=_.identity] * The function invoked per iteration. * @returns {Array} Returns the new filtered array. + * @see _.filter * @example * * var users = [ diff --git a/result.js b/result.js index 7e5fee6ac..d8cb8c000 100644 --- a/result.js +++ b/result.js @@ -1,4 +1,4 @@ -define(['./_castPath', './isFunction', './_isKey'], function(castPath, isFunction, isKey) { +define(['./_castPath', './isFunction', './_isKey', './_toKey'], function(castPath, isFunction, isKey, toKey) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -44,7 +44,7 @@ define(['./_castPath', './isFunction', './_isKey'], function(castPath, isFunctio length = 1; } while (++index < length) { - var value = object == null ? undefined : object[path[index]]; + var value = object == null ? undefined : object[toKey(path[index])]; if (value === undefined) { index = length; value = defaultValue; diff --git a/sortedUniqBy.js b/sortedUniqBy.js index 0a0b80690..39d3e8d4b 100644 --- a/sortedUniqBy.js +++ b/sortedUniqBy.js @@ -1,4 +1,4 @@ -define(['./_baseIteratee', './_baseSortedUniqBy'], function(baseIteratee, baseSortedUniqBy) { +define(['./_baseIteratee', './_baseSortedUniq'], function(baseIteratee, baseSortedUniq) { /** * This method is like `_.uniqBy` except that it's designed and optimized @@ -18,7 +18,7 @@ define(['./_baseIteratee', './_baseSortedUniqBy'], function(baseIteratee, baseSo */ function sortedUniqBy(array, iteratee) { return (array && array.length) - ? baseSortedUniqBy(array, baseIteratee(iteratee)) + ? baseSortedUniq(array, baseIteratee(iteratee)) : []; } diff --git a/split.js b/split.js index 6021f7ad8..8ce767f6e 100644 --- a/split.js +++ b/split.js @@ -1,4 +1,4 @@ -define(['./_castSlice', './_isIterateeCall', './isRegExp', './_reHasComplexSymbol', './_stringToArray', './toString'], function(castSlice, isIterateeCall, isRegExp, reHasComplexSymbol, stringToArray, toString) { +define(['./_baseToString', './_castSlice', './_isIterateeCall', './isRegExp', './_reHasComplexSymbol', './_stringToArray', './toString'], function(baseToString, castSlice, isIterateeCall, isRegExp, reHasComplexSymbol, stringToArray, toString) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -44,7 +44,7 @@ define(['./_castSlice', './_isIterateeCall', './isRegExp', './_reHasComplexSymbo typeof separator == 'string' || (separator != null && !isRegExp(separator)) )) { - separator += ''; + separator = baseToString(separator); if (separator == '' && reHasComplexSymbol.test(string)) { return castSlice(stringToArray(string), 0, limit); } diff --git a/startsWith.js b/startsWith.js index b40763b9e..35eb46ecc 100644 --- a/startsWith.js +++ b/startsWith.js @@ -1,4 +1,4 @@ -define(['./_baseClamp', './toInteger', './toString'], function(baseClamp, toInteger, toString) { +define(['./_baseClamp', './_baseToString', './toInteger', './toString'], function(baseClamp, baseToString, toInteger, toString) { /** * Checks if `string` starts with the given target string. @@ -26,7 +26,7 @@ define(['./_baseClamp', './toInteger', './toString'], function(baseClamp, toInte function startsWith(string, target, position) { string = toString(string); position = baseClamp(toInteger(position), 0, string.length); - return string.lastIndexOf(target, position) == position; + return string.lastIndexOf(baseToString(target), position) == position; } return startsWith; diff --git a/toString.js b/toString.js index 56947e097..ab181a95c 100644 --- a/toString.js +++ b/toString.js @@ -1,14 +1,4 @@ -define(['./_Symbol', './isSymbol'], function(Symbol, isSymbol) { - - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0; - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +define(['./_baseToString'], function(baseToString) { /** * Converts `value` to a string. An empty string is returned for `null` @@ -32,18 +22,7 @@ define(['./_Symbol', './isSymbol'], function(Symbol, isSymbol) { * // => '1,2,3' */ function toString(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 symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + return value == null ? '' : baseToString(value); } return toString; diff --git a/trim.js b/trim.js index 94116569d..7e54b080b 100644 --- a/trim.js +++ b/trim.js @@ -1,4 +1,4 @@ -define(['./_castSlice', './_charsEndIndex', './_charsStartIndex', './_stringToArray', './toString'], function(castSlice, charsEndIndex, charsStartIndex, stringToArray, toString) { +define(['./_baseToString', './_castSlice', './_charsEndIndex', './_charsStartIndex', './_stringToArray', './toString'], function(baseToString, castSlice, charsEndIndex, charsStartIndex, stringToArray, toString) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -30,13 +30,10 @@ define(['./_castSlice', './_charsEndIndex', './_charsStartIndex', './_stringToAr */ function trim(string, chars, guard) { string = toString(string); - if (!string) { - return string; - } - if (guard || chars === undefined) { + if (string && (guard || chars === undefined)) { return string.replace(reTrim, ''); } - if (!(chars += '')) { + if (!string || !(chars = baseToString(chars))) { return string; } var strSymbols = stringToArray(string), diff --git a/trimEnd.js b/trimEnd.js index 6221b2fdd..17bf5c356 100644 --- a/trimEnd.js +++ b/trimEnd.js @@ -1,4 +1,4 @@ -define(['./_castSlice', './_charsEndIndex', './_stringToArray', './toString'], function(castSlice, charsEndIndex, stringToArray, toString) { +define(['./_baseToString', './_castSlice', './_charsEndIndex', './_stringToArray', './toString'], function(baseToString, castSlice, charsEndIndex, stringToArray, toString) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -27,13 +27,10 @@ define(['./_castSlice', './_charsEndIndex', './_stringToArray', './toString'], f */ function trimEnd(string, chars, guard) { string = toString(string); - if (!string) { - return string; - } - if (guard || chars === undefined) { + if (string && (guard || chars === undefined)) { return string.replace(reTrimEnd, ''); } - if (!(chars += '')) { + if (!string || !(chars = baseToString(chars))) { return string; } var strSymbols = stringToArray(string), diff --git a/trimStart.js b/trimStart.js index e86aeeefe..307875dca 100644 --- a/trimStart.js +++ b/trimStart.js @@ -1,4 +1,4 @@ -define(['./_castSlice', './_charsStartIndex', './_stringToArray', './toString'], function(castSlice, charsStartIndex, stringToArray, toString) { +define(['./_baseToString', './_castSlice', './_charsStartIndex', './_stringToArray', './toString'], function(baseToString, castSlice, charsStartIndex, stringToArray, toString) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -27,13 +27,10 @@ define(['./_castSlice', './_charsStartIndex', './_stringToArray', './toString'], */ function trimStart(string, chars, guard) { string = toString(string); - if (!string) { - return string; - } - if (guard || chars === undefined) { + if (string && (guard || chars === undefined)) { return string.replace(reTrimStart, ''); } - if (!(chars += '')) { + if (!string || !(chars = baseToString(chars))) { return string; } var strSymbols = stringToArray(string), diff --git a/truncate.js b/truncate.js index f4047ec9d..01a1d82b8 100644 --- a/truncate.js +++ b/truncate.js @@ -1,4 +1,4 @@ -define(['./_castSlice', './isObject', './isRegExp', './_reHasComplexSymbol', './_stringSize', './_stringToArray', './toInteger', './toString'], function(castSlice, isObject, isRegExp, reHasComplexSymbol, stringSize, stringToArray, toInteger, toString) { +define(['./_baseToString', './_castSlice', './isObject', './isRegExp', './_reHasComplexSymbol', './_stringSize', './_stringToArray', './toInteger', './toString'], function(baseToString, castSlice, isObject, isRegExp, reHasComplexSymbol, stringSize, stringToArray, toInteger, toString) { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; @@ -54,7 +54,7 @@ define(['./_castSlice', './isObject', './isRegExp', './_reHasComplexSymbol', './ if (isObject(options)) { var separator = 'separator' in options ? options.separator : separator; length = 'length' in options ? toInteger(options.length) : length; - omission = 'omission' in options ? toString(options.omission) : omission; + omission = 'omission' in options ? baseToString(options.omission) : omission; } string = toString(string); @@ -94,7 +94,7 @@ define(['./_castSlice', './isObject', './isRegExp', './_reHasComplexSymbol', './ } result = result.slice(0, newEnd === undefined ? end : newEnd); } - } else if (string.indexOf(separator, end) != end) { + } else if (string.indexOf(baseToString(separator), end) != end) { var index = result.lastIndexOf(separator); if (index > -1) { result = result.slice(0, index); diff --git a/without.js b/without.js index 106521c41..bc1bb4db0 100644 --- a/without.js +++ b/without.js @@ -12,6 +12,7 @@ define(['./_baseDifference', './isArrayLikeObject', './rest'], function(baseDiff * @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); diff --git a/words.js b/words.js index 6f46c210a..f3bb48aff 100644 --- a/words.js +++ b/words.js @@ -14,11 +14,11 @@ define(['./toString'], function(toString) { rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', - rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d', + rsPunctuationRange = '\\u2000-\\u206f', 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 + rsQuoteRange + rsSpaceRange; + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; /** Used to compose unicode capture groups. */ var rsApos = "['\u2019]", diff --git a/xor.js b/xor.js index 3af66887c..33f2c9095 100644 --- a/xor.js +++ b/xor.js @@ -12,6 +12,7 @@ define(['./_arrayFilter', './_baseXor', './isArrayLikeObject', './rest'], functi * @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]);