diff --git a/README.md b/README.md index 38088be4a..b9e56a5bb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash-es v4.5.1 +# lodash-es v4.6.0 The [lodash](https://lodash.com/) library exported as [ES](http://www.ecma-international.org/ecma-262/6.0/) modules. @@ -7,4 +7,4 @@ Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli): $ lodash modularize exports=es -o ./ ``` -See the [package source](https://github.com/lodash/lodash/tree/4.5.1-es) for more details. +See the [package source](https://github.com/lodash/lodash/tree/4.6.0-es) for more details. diff --git a/_addMapEntry.js b/_addMapEntry.js index 486c184ff..a5094faf0 100644 --- a/_addMapEntry.js +++ b/_addMapEntry.js @@ -7,6 +7,7 @@ * @returns {Object} Returns `map`. */ function addMapEntry(map, pair) { + // Don't return `Map#set` because it doesn't return the map instance in IE 11. map.set(pair[0], pair[1]); return map; } diff --git a/_arrayFilter.js b/_arrayFilter.js index 247b29891..dadc70fce 100644 --- a/_arrayFilter.js +++ b/_arrayFilter.js @@ -10,13 +10,13 @@ function arrayFilter(array, predicate) { var index = -1, length = array.length, - resIndex = -1, + resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { - result[++resIndex] = value; + result[resIndex++] = value; } } return result; diff --git a/_arrayIncludesWith.js b/_arrayIncludesWith.js index b84117693..4a3baab93 100644 --- a/_arrayIncludesWith.js +++ b/_arrayIncludesWith.js @@ -1,6 +1,5 @@ /** - * A specialized version of `_.includesWith` for arrays without support for - * specifying an index to search from. + * This function is like `arrayIncludes` except that it accepts a comparator. * * @private * @param {Array} array The array to search. diff --git a/_assignMergeValue.js b/_assignMergeValue.js index 7b1353d25..63bab0e63 100644 --- a/_assignMergeValue.js +++ b/_assignMergeValue.js @@ -1,7 +1,8 @@ import eq from './eq'; /** - * This function is like `assignValue` except that it doesn't assign `undefined` values. + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. * * @private * @param {Object} object The object to modify. diff --git a/_baseIndexOfWith.js b/_baseIndexOfWith.js new file mode 100644 index 000000000..028ad9159 --- /dev/null +++ b/_baseIndexOfWith.js @@ -0,0 +1,23 @@ +/** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; +} + +export default baseIndexOfWith; diff --git a/_baseIntersection.js b/_baseIntersection.js index 1a20c3437..d64c75fd1 100644 --- a/_baseIntersection.js +++ b/_baseIntersection.js @@ -5,6 +5,9 @@ import arrayMap from './_arrayMap'; import baseUnary from './_baseUnary'; import cacheHas from './_cacheHas'; +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + /** * The base implementation of methods like `_.intersection`, without support * for iteratee shorthands, that accepts an array of arrays to inspect. @@ -17,9 +20,11 @@ import cacheHas from './_cacheHas'; */ function baseIntersection(arrays, iteratee, comparator) { var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, othLength = arrays.length, othIndex = othLength, caches = Array(othLength), + maxLength = Infinity, result = []; while (othIndex--) { @@ -27,18 +32,18 @@ function baseIntersection(arrays, iteratee, comparator) { if (othIndex && iteratee) { array = arrayMap(array, baseUnary(iteratee)); } - caches[othIndex] = !comparator && (iteratee || array.length >= 120) + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) ? new SetCache(othIndex && array) : undefined; } array = arrays[0]; var index = -1, - length = array.length, seen = caches[0]; outer: - while (++index < length) { + while (++index < length && result.length < maxLength) { var value = array[index], computed = iteratee ? iteratee(value) : value; @@ -46,7 +51,7 @@ function baseIntersection(arrays, iteratee, comparator) { ? cacheHas(seen, computed) : includes(result, computed, comparator) )) { - var othIndex = othLength; + othIndex = othLength; while (--othIndex) { var cache = caches[othIndex]; if (!(cache diff --git a/_baseIsEqualDeep.js b/_baseIsEqualDeep.js index 37a8fe323..41484522a 100644 --- a/_baseIsEqualDeep.js +++ b/_baseIsEqualDeep.js @@ -43,33 +43,28 @@ function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { if (!objIsArr) { objTag = getTag(object); - if (objTag == argsTag) { - objTag = objectTag; - } else if (objTag != objectTag) { - objIsArr = isTypedArray(object); - } + objTag = objTag == argsTag ? objectTag : objTag; } if (!othIsArr) { othTag = getTag(other); - if (othTag == argsTag) { - othTag = objectTag; - } else if (othTag != objectTag) { - othIsArr = isTypedArray(other); - } + othTag = othTag == argsTag ? objectTag : othTag; } var objIsObj = objTag == objectTag && !isHostObject(object), othIsObj = othTag == objectTag && !isHostObject(other), isSameTag = objTag == othTag; - if (isSameTag && !(objIsArr || objIsObj)) { - return equalByTag(object, other, objTag, equalFunc, customizer, bitmask); + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) + : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); } - var isPartial = bitmask & PARTIAL_COMPARE_FLAG; - if (!isPartial) { + if (!(bitmask & PARTIAL_COMPARE_FLAG)) { var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); if (objIsWrapped || othIsWrapped) { + stack || (stack = new Stack); return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); } } @@ -77,7 +72,7 @@ function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { return false; } stack || (stack = new Stack); - return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack); + return equalObjects(object, other, equalFunc, customizer, bitmask, stack); } export default baseIsEqualDeep; diff --git a/_baseMergeDeep.js b/_baseMergeDeep.js index 828330172..dff6c2dff 100644 --- a/_baseMergeDeep.js +++ b/_baseMergeDeep.js @@ -50,7 +50,7 @@ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, sta } else { isCommon = false; - newValue = baseClone(srcValue, true); + newValue = baseClone(srcValue, !customizer); } } else if (isPlainObject(srcValue) || isArguments(srcValue)) { @@ -59,7 +59,7 @@ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, sta } else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { isCommon = false; - newValue = baseClone(srcValue, true); + newValue = baseClone(srcValue, !customizer); } else { newValue = objValue; @@ -75,6 +75,7 @@ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, sta // Recursively merge objects and arrays (susceptible to call stack limits). mergeFunc(newValue, srcValue, srcIndex, customizer, stack); } + stack['delete'](srcValue); assignMergeValue(object, key, newValue); } diff --git a/_baseOrderBy.js b/_baseOrderBy.js index f987cb183..9f892d07c 100644 --- a/_baseOrderBy.js +++ b/_baseOrderBy.js @@ -14,12 +14,8 @@ import compareMultiple from './_compareMultiple'; * @returns {Array} Returns the new sorted array. */ function baseOrderBy(collection, iteratees, orders) { - var index = -1, - toIteratee = baseIteratee; - - iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) { - return toIteratee(iteratee); - }); + var index = -1; + iteratees = arrayMap(iteratees.length ? iteratees : Array(1), baseIteratee); var result = baseMap(collection, function(value, key, collection) { var criteria = arrayMap(iteratees, function(iteratee) { diff --git a/_basePullAll.js b/_basePullAll.js index 7f3cf3037..f819d5ac8 100644 --- a/_basePullAll.js +++ b/_basePullAll.js @@ -1,15 +1,47 @@ -import basePullAllBy from './_basePullAllBy'; +import arrayMap from './_arrayMap'; +import baseIndexOf from './_baseIndexOf'; +import baseIndexOfWith from './_baseIndexOfWith'; +import baseUnary from './_baseUnary'; + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; /** - * The base implementation of `_.pullAll`. + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns `array`. */ -function basePullAll(array, values) { - return basePullAllBy(array, values); +function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; } export default basePullAll; diff --git a/_basePullAllBy.js b/_basePullAllBy.js deleted file mode 100644 index 1a6ca9e6e..000000000 --- a/_basePullAllBy.js +++ /dev/null @@ -1,43 +0,0 @@ -import arrayMap from './_arrayMap'; -import baseIndexOf from './_baseIndexOf'; - -/** Used for built-in method references. */ -var arrayProto = Array.prototype; - -/** Built-in value references. */ -var splice = arrayProto.splice; - -/** - * The base implementation of `_.pullAllBy` without support for iteratee - * shorthands. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns `array`. - */ -function basePullAllBy(array, values, iteratee) { - var index = -1, - length = values.length, - seen = array; - - if (iteratee) { - seen = arrayMap(array, function(value) { return iteratee(value); }); - } - while (++index < length) { - var fromIndex = 0, - value = values[index], - computed = iteratee ? iteratee(value) : value; - - while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) { - if (seen !== array) { - splice.call(seen, fromIndex, 1); - } - splice.call(array, fromIndex, 1); - } - } - return array; -} - -export default basePullAllBy; diff --git a/_baseSortBy.js b/_baseSortBy.js index aeb74542f..e2041cd66 100644 --- a/_baseSortBy.js +++ b/_baseSortBy.js @@ -1,7 +1,7 @@ /** - * The base implementation of `_.sortBy` which uses `comparer` to define - * the sort order of `array` and replaces criteria objects with their - * corresponding values. + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. * * @private * @param {Array} array The array to sort. diff --git a/_baseSortedUniqBy.js b/_baseSortedUniqBy.js index 8484197be..d31384f5d 100644 --- a/_baseSortedUniqBy.js +++ b/_baseSortedUniqBy.js @@ -15,7 +15,7 @@ function baseSortedUniqBy(array, iteratee) { value = array[0], computed = iteratee ? iteratee(value) : value, seen = computed, - resIndex = 0, + resIndex = 1, result = [value]; while (++index < length) { @@ -24,7 +24,7 @@ function baseSortedUniqBy(array, iteratee) { if (!eq(computed, seen)) { seen = computed; - result[++resIndex] = value; + result[resIndex++] = value; } } return result; diff --git a/_baseUpdate.js b/_baseUpdate.js new file mode 100644 index 000000000..79cea3ff2 --- /dev/null +++ b/_baseUpdate.js @@ -0,0 +1,18 @@ +import baseGet from './_baseGet'; +import baseSet from './_baseSet'; + +/** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); +} + +export default baseUpdate; diff --git a/_cloneArrayBuffer.js b/_cloneArrayBuffer.js index ad319449f..2b3a5eba5 100644 --- a/_cloneArrayBuffer.js +++ b/_cloneArrayBuffer.js @@ -8,11 +8,8 @@ import Uint8Array from './_Uint8Array'; * @returns {ArrayBuffer} Returns the cloned array buffer. */ function cloneArrayBuffer(arrayBuffer) { - var Ctor = arrayBuffer.constructor, - result = new Ctor(arrayBuffer.byteLength), - view = new Uint8Array(result); - - view.set(new Uint8Array(arrayBuffer)); + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); return result; } diff --git a/_cloneBuffer.js b/_cloneBuffer.js index 0619230af..c1139dd8a 100644 --- a/_cloneBuffer.js +++ b/_cloneBuffer.js @@ -10,9 +10,7 @@ function cloneBuffer(buffer, isDeep) { if (isDeep) { return buffer.slice(); } - var Ctor = buffer.constructor, - result = new Ctor(buffer.length); - + var result = new buffer.constructor(buffer.length); buffer.copy(result); return result; } diff --git a/_cloneMap.js b/_cloneMap.js index c3defb6ae..122e72c0d 100644 --- a/_cloneMap.js +++ b/_cloneMap.js @@ -10,8 +10,7 @@ import mapToArray from './_mapToArray'; * @returns {Object} Returns the cloned map. */ function cloneMap(map) { - var Ctor = map.constructor; - return arrayReduce(mapToArray(map), addMapEntry, new Ctor); + return arrayReduce(mapToArray(map), addMapEntry, new map.constructor); } export default cloneMap; diff --git a/_cloneRegExp.js b/_cloneRegExp.js index 4942fa44b..0ddb49b4c 100644 --- a/_cloneRegExp.js +++ b/_cloneRegExp.js @@ -9,9 +9,7 @@ var reFlags = /\w*$/; * @returns {Object} Returns the cloned regexp. */ function cloneRegExp(regexp) { - var Ctor = regexp.constructor, - result = new Ctor(regexp.source, reFlags.exec(regexp)); - + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); result.lastIndex = regexp.lastIndex; return result; } diff --git a/_cloneSet.js b/_cloneSet.js index 416882635..2189362e4 100644 --- a/_cloneSet.js +++ b/_cloneSet.js @@ -10,8 +10,7 @@ import setToArray from './_setToArray'; * @returns {Object} Returns the cloned set. */ function cloneSet(set) { - var Ctor = set.constructor; - return arrayReduce(setToArray(set), addSetEntry, new Ctor); + return arrayReduce(setToArray(set), addSetEntry, new set.constructor); } export default cloneSet; diff --git a/_cloneSymbol.js b/_cloneSymbol.js index 597c83cb3..9cd1e1c09 100644 --- a/_cloneSymbol.js +++ b/_cloneSymbol.js @@ -2,7 +2,7 @@ import Symbol from './_Symbol'; /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = Symbol ? symbolProto.valueOf : undefined; + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; /** * Creates a clone of the `symbol` object. @@ -12,7 +12,7 @@ var symbolProto = Symbol ? Symbol.prototype : undefined, * @returns {Object} Returns the cloned symbol object. */ function cloneSymbol(symbol) { - return Symbol ? Object(symbolValueOf.call(symbol)) : {}; + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; } export default cloneSymbol; diff --git a/_cloneTypedArray.js b/_cloneTypedArray.js index b1f8f6890..abc4554d9 100644 --- a/_cloneTypedArray.js +++ b/_cloneTypedArray.js @@ -9,11 +9,8 @@ import cloneArrayBuffer from './_cloneArrayBuffer'; * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { - var arrayBuffer = typedArray.buffer, - buffer = isDeep ? cloneArrayBuffer(arrayBuffer) : arrayBuffer, - Ctor = typedArray.constructor; - - return new Ctor(buffer, typedArray.byteOffset, typedArray.length); + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); } export default cloneTypedArray; diff --git a/_createFlow.js b/_createFlow.js index 635c423db..e9e1d5e35 100644 --- a/_createFlow.js +++ b/_createFlow.js @@ -6,18 +6,18 @@ import isArray from './isArray'; import isLaziable from './_isLaziable'; import rest from './rest'; -/** Used to compose bitmasks for wrapper metadata. */ -var CURRY_FLAG = 8, - PARTIAL_FLAG = 32, - ARY_FLAG = 128, - REARG_FLAG = 256; - /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_FLAG = 8, + PARTIAL_FLAG = 32, + ARY_FLAG = 128, + REARG_FLAG = 256; + /** * Creates a `_.flow` or `_.flowRight` function. * diff --git a/_createWrapper.js b/_createWrapper.js index c15e68a4d..846e94fc6 100644 --- a/_createWrapper.js +++ b/_createWrapper.js @@ -8,6 +8,9 @@ import mergeData from './_mergeData'; import setData from './_setData'; import toInteger from './toInteger'; +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, BIND_KEY_FLAG = 2, @@ -16,9 +19,6 @@ var BIND_FLAG = 1, PARTIAL_FLAG = 32, PARTIAL_RIGHT_FLAG = 64; -/** Used as the `TypeError` message for "Functions" methods. */ -var FUNC_ERROR_TEXT = 'Expected a function'; - /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max; diff --git a/_equalArrays.js b/_equalArrays.js index ff975ccee..ce870e5e2 100644 --- a/_equalArrays.js +++ b/_equalArrays.js @@ -12,9 +12,9 @@ var UNORDERED_COMPARE_FLAG = 1, * @param {Array} array The array to compare. * @param {Array} other The other array to compare. * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparisons. - * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. - * @param {Object} [stack] Tracks traversed `array` and `other` objects. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `array` and `other` objects. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. */ function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { diff --git a/_equalByTag.js b/_equalByTag.js index 005e34a49..bc9e540b8 100644 --- a/_equalByTag.js +++ b/_equalByTag.js @@ -1,5 +1,6 @@ import Symbol from './_Symbol'; import Uint8Array from './_Uint8Array'; +import equalArrays from './_equalArrays'; import mapToArray from './_mapToArray'; import setToArray from './_setToArray'; @@ -22,7 +23,7 @@ var arrayBufferTag = '[object ArrayBuffer]'; /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = Symbol ? symbolProto.valueOf : undefined; + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; /** * A specialized version of `baseIsEqualDeep` for comparing objects of @@ -36,11 +37,12 @@ var symbolProto = Symbol ? Symbol.prototype : undefined, * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparisons. - * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ -function equalByTag(object, other, tag, equalFunc, customizer, bitmask) { +function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { switch (tag) { case arrayBufferTag: if ((object.byteLength != other.byteLength) || @@ -75,12 +77,21 @@ function equalByTag(object, other, tag, equalFunc, customizer, bitmask) { var isPartial = bitmask & PARTIAL_COMPARE_FLAG; convert || (convert = setToArray); + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } // Recursively compare objects (susceptible to call stack limits). - return (isPartial || object.size == other.size) && - equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG); + return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask | UNORDERED_COMPARE_FLAG, stack.set(object, other)); case symbolTag: - return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other)); + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } } return false; } diff --git a/_equalObjects.js b/_equalObjects.js index 7511bb2dc..24bc79606 100644 --- a/_equalObjects.js +++ b/_equalObjects.js @@ -12,9 +12,9 @@ var PARTIAL_COMPARE_FLAG = 2; * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparisons. - * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { diff --git a/_getNative.js b/_getNative.js index b91f8dc61..a1dccd550 100644 --- a/_getNative.js +++ b/_getNative.js @@ -9,7 +9,7 @@ import isNative from './isNative'; * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { - var value = object == null ? undefined : object[key]; + var value = object[key]; return isNative(value) ? value : undefined; } diff --git a/_initCloneObject.js b/_initCloneObject.js index b6c8dd58c..35a1cba07 100644 --- a/_initCloneObject.js +++ b/_initCloneObject.js @@ -1,5 +1,4 @@ import baseCreate from './_baseCreate'; -import isFunction from './isFunction'; import isPrototype from './_isPrototype'; /** Built-in value references. */ @@ -13,7 +12,7 @@ var getPrototypeOf = Object.getPrototypeOf; * @returns {Object} Returns the initialized clone. */ function initCloneObject(object) { - return (isFunction(object.constructor) && !isPrototype(object)) + return (typeof object.constructor == 'function' && !isPrototype(object)) ? baseCreate(getPrototypeOf(object)) : {}; } diff --git a/_isPrototype.js b/_isPrototype.js index 9214b1c4d..f6c7660d0 100644 --- a/_isPrototype.js +++ b/_isPrototype.js @@ -1,5 +1,3 @@ -import isFunction from './isFunction'; - /** Used for built-in method references. */ var objectProto = Object.prototype; @@ -12,7 +10,7 @@ var objectProto = Object.prototype; */ function isPrototype(value) { var Ctor = value && value.constructor, - proto = (isFunction(Ctor) && Ctor.prototype) || objectProto; + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; return value === proto; } diff --git a/_mergeData.js b/_mergeData.js index aef1c8077..224a80b00 100644 --- a/_mergeData.js +++ b/_mergeData.js @@ -3,6 +3,9 @@ import composeArgsRight from './_composeArgsRight'; import copyArray from './_copyArray'; import replaceHolders from './_replaceHolders'; +/** Used as the internal argument placeholder. */ +var PLACEHOLDER = '__lodash_placeholder__'; + /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, BIND_KEY_FLAG = 2, @@ -11,9 +14,6 @@ var BIND_FLAG = 1, ARY_FLAG = 128, REARG_FLAG = 256; -/** Used as the internal argument placeholder. */ -var PLACEHOLDER = '__lodash_placeholder__'; - /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMin = Math.min; diff --git a/_mergeDefaults.js b/_mergeDefaults.js index 05eae7dee..f8b8c2907 100644 --- a/_mergeDefaults.js +++ b/_mergeDefaults.js @@ -15,8 +15,7 @@ import isObject from './isObject'; */ function mergeDefaults(objValue, srcValue, key, object, source, stack) { if (isObject(objValue) && isObject(srcValue)) { - stack.set(srcValue, objValue); - baseMerge(objValue, srcValue, undefined, mergeDefaults, stack); + baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue)); } return objValue; } diff --git a/_replaceHolders.js b/_replaceHolders.js index 7a2e62e78..e63605416 100644 --- a/_replaceHolders.js +++ b/_replaceHolders.js @@ -13,14 +13,14 @@ var PLACEHOLDER = '__lodash_placeholder__'; function replaceHolders(array, placeholder) { var index = -1, length = array.length, - resIndex = -1, + resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (value === placeholder || value === PLACEHOLDER) { array[index] = PLACEHOLDER; - result[++resIndex] = index; + result[resIndex++] = index; } } return result; diff --git a/array.default.js b/array.default.js index 15a60b909..608789c53 100644 --- a/array.default.js +++ b/array.default.js @@ -27,6 +27,7 @@ import lastIndexOf from './lastIndexOf'; import pull from './pull'; import pullAll from './pullAll'; import pullAllBy from './pullAllBy'; +import pullAllWith from './pullAllWith'; import pullAt from './pullAt'; import remove from './remove'; import reverse from './reverse'; @@ -67,12 +68,12 @@ export default { fill, findIndex, findLastIndex, flatten, flattenDeep, flattenDepth, fromPairs, head, indexOf, initial, intersection, intersectionBy, intersectionWith, join, last, - lastIndexOf, pull, pullAll, pullAllBy, pullAt, - remove, reverse, slice, sortedIndex, sortedIndexBy, - sortedIndexOf, sortedLastIndex, sortedLastIndexBy, sortedLastIndexOf, sortedUniq, - sortedUniqBy, tail, take, takeRight, takeRightWhile, - takeWhile, union, unionBy, unionWith, uniq, - uniqBy, uniqWith, unzip, unzipWith, without, - xor, xorBy, xorWith, zip, zipObject, - zipObjectDeep, zipWith + lastIndexOf, pull, pullAll, pullAllBy, pullAllWith, + pullAt, remove, reverse, slice, sortedIndex, + sortedIndexBy, sortedIndexOf, sortedLastIndex, sortedLastIndexBy, sortedLastIndexOf, + sortedUniq, sortedUniqBy, tail, take, takeRight, + takeRightWhile, takeWhile, union, unionBy, unionWith, + uniq, uniqBy, uniqWith, unzip, unzipWith, + without, xor, xorBy, xorWith, zip, + zipObject, zipObjectDeep, zipWith }; diff --git a/array.js b/array.js index f6e6fb2a3..753314615 100644 --- a/array.js +++ b/array.js @@ -27,6 +27,7 @@ export { default as lastIndexOf } from './lastIndexOf'; export { default as pull } from './pull'; export { default as pullAll } from './pullAll'; export { default as pullAllBy } from './pullAllBy'; +export { default as pullAllWith } from './pullAllWith'; export { default as pullAt } from './pullAt'; export { default as remove } from './remove'; export { default as reverse } from './reverse'; diff --git a/assign.js b/assign.js index c13a41deb..d4a4fd780 100644 --- a/assign.js +++ b/assign.js @@ -1,7 +1,19 @@ +import assignValue from './_assignValue'; import copyObject from './_copyObject'; import createAssigner from './_createAssigner'; +import isArrayLike from './isArrayLike'; +import isPrototype from './_isPrototype'; import keys from './keys'; +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !({ 'valueOf': 1 }).propertyIsEnumerable('valueOf'); + /** * Assigns own enumerable properties of source objects to the destination * object. Source objects are applied from left to right. Subsequent sources @@ -33,7 +45,15 @@ import keys from './keys'; * // => { 'a': 1, 'c': 3, 'e': 5 } */ var assign = createAssigner(function(object, source) { - copyObject(source, keys(source), object); + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } }); export default assign; diff --git a/assignIn.js b/assignIn.js index eb281b15f..317187873 100644 --- a/assignIn.js +++ b/assignIn.js @@ -1,7 +1,13 @@ +import assignValue from './_assignValue'; import copyObject from './_copyObject'; import createAssigner from './_createAssigner'; +import isArrayLike from './isArrayLike'; +import isPrototype from './_isPrototype'; import keysIn from './keysIn'; +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !({ 'valueOf': 1 }).propertyIsEnumerable('valueOf'); + /** * This method is like `_.assign` except that it iterates over own and * inherited source properties. @@ -32,7 +38,13 @@ import keysIn from './keysIn'; * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } */ var assignIn = createAssigner(function(object, source) { - copyObject(source, keysIn(source), object); + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keysIn(source), object); + return; + } + for (var key in source) { + assignValue(object, key, source[key]); + } }); export default assignIn; diff --git a/chunk.js b/chunk.js index 0c69eb333..11328e24f 100644 --- a/chunk.js +++ b/chunk.js @@ -32,11 +32,11 @@ function chunk(array, size) { return []; } var index = 0, - resIndex = -1, + resIndex = 0, result = Array(nativeCeil(length / size)); while (index < length) { - result[++resIndex] = baseSlice(array, index, (index += size)); + result[resIndex++] = baseSlice(array, index, (index += size)); } return result; } diff --git a/compact.js b/compact.js index 438719a21..8abb94333 100644 --- a/compact.js +++ b/compact.js @@ -15,13 +15,13 @@ function compact(array) { var index = -1, length = array ? array.length : 0, - resIndex = -1, + resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (value) { - result[++resIndex] = value; + result[resIndex++] = value; } } return result; diff --git a/difference.js b/difference.js index eb2e283d6..27d9ef8f6 100644 --- a/difference.js +++ b/difference.js @@ -6,7 +6,8 @@ import rest from './rest'; /** * Creates an array of unique `array` values not included in the other * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. * * @static * @memberOf _ diff --git a/differenceBy.js b/differenceBy.js index cec8d0327..844a14faf 100644 --- a/differenceBy.js +++ b/differenceBy.js @@ -8,7 +8,8 @@ import rest from './rest'; /** * This method is like `_.difference` except that it accepts `iteratee` which * is invoked for each element of `array` and `values` to generate the criterion - * by which uniqueness is computed. The iteratee is invoked with one argument: (value). + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). * * @static * @memberOf _ diff --git a/differenceWith.js b/differenceWith.js index e2f13959a..5ef96657e 100644 --- a/differenceWith.js +++ b/differenceWith.js @@ -6,8 +6,9 @@ import rest from './rest'; /** * This method is like `_.difference` except that it accepts `comparator` - * which is invoked to compare elements of `array` to `values`. The comparator - * is invoked with two arguments: (arrVal, othVal). + * which is invoked to compare elements of `array` to `values`. Result values + * are chosen from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). * * @static * @memberOf _ diff --git a/intersection.js b/intersection.js index 60b3a0913..64591b110 100644 --- a/intersection.js +++ b/intersection.js @@ -6,13 +6,14 @@ import rest from './rest'; /** * Creates an array of unique values that are included in all given arrays * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. * * @static * @memberOf _ * @category Array * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of shared values. + * @returns {Array} Returns the new array of intersecting values. * @example * * _.intersection([2, 1], [4, 2], [1, 2]); diff --git a/intersectionBy.js b/intersectionBy.js index 880668abb..49dfeb518 100644 --- a/intersectionBy.js +++ b/intersectionBy.js @@ -8,14 +8,15 @@ import rest from './rest'; /** * This method is like `_.intersection` except that it accepts `iteratee` * which is invoked for each element of each `arrays` to generate the criterion - * by which uniqueness is computed. The iteratee is invoked with one argument: (value). + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of shared values. + * @returns {Array} Returns the new array of intersecting values. * @example * * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); diff --git a/intersectionWith.js b/intersectionWith.js index 59d5ff1ac..8d14ecb80 100644 --- a/intersectionWith.js +++ b/intersectionWith.js @@ -6,15 +6,16 @@ import rest from './rest'; /** * This method is like `_.intersection` except that it accepts `comparator` - * which is invoked to compare elements of `arrays`. The comparator is invoked - * with two arguments: (arrVal, othVal). + * which is invoked to compare elements of `arrays`. Result values are chosen + * from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). * * @static * @memberOf _ * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of shared values. + * @returns {Array} Returns the new array of intersecting values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; diff --git a/isArrayLike.js b/isArrayLike.js index cf64b36d8..6c70e2375 100644 --- a/isArrayLike.js +++ b/isArrayLike.js @@ -27,8 +27,7 @@ import isLength from './isLength'; * // => false */ function isArrayLike(value) { - return value != null && - !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value)); + return value != null && isLength(getLength(value)) && !isFunction(value); } export default isArrayLike; diff --git a/isEmpty.js b/isEmpty.js index b12758a1c..9c35eff8c 100644 --- a/isEmpty.js +++ b/isEmpty.js @@ -11,14 +11,14 @@ var objectProto = Object.prototype; var hasOwnProperty = objectProto.hasOwnProperty; /** - * Checks if `value` is empty. A value is considered empty unless it's an - * `arguments` object, array, string, or jQuery-like collection with a length - * greater than `0` or an object with own enumerable properties. + * Checks if `value` is an empty collection or object. A value is considered + * empty if it's an `arguments` object, array, string, or jQuery-like collection + * with a length of `0` or has no own enumerable properties. * * @static * @memberOf _ * @category Lang - * @param {Array|Object|string} value The value to inspect. + * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is empty, else `false`. * @example * diff --git a/isFunction.js b/isFunction.js index 5e2e6b609..c66ff49f0 100644 --- a/isFunction.js +++ b/isFunction.js @@ -31,8 +31,8 @@ var objectToString = objectProto.toString; */ function isFunction(value) { // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8 which returns 'object' for typed array constructors, and - // PhantomJS 1.9 which returns 'function' for `NodeList` instances. + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. var tag = isObject(value) ? objectToString.call(value) : ''; return tag == funcTag || tag == genTag; } diff --git a/lodash.default.js b/lodash.default.js index d8b4684a6..3a74287f2 100644 --- a/lodash.default.js +++ b/lodash.default.js @@ -1,6 +1,6 @@ /** * @license - * lodash 4.5.1 (Custom Build) + * lodash 4.6.0 (Custom Build) * Build: `lodash modularize exports="es" -o ./` * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 @@ -44,7 +44,7 @@ import toInteger from './toInteger'; import lodash from './wrapperLodash'; /** Used as the semantic version number. */ -var VERSION = '4.5.1'; +var VERSION = '4.6.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_KEY_FLAG = 2; @@ -179,6 +179,7 @@ lodash.propertyOf = util.propertyOf; lodash.pull = array.pull; lodash.pullAll = array.pullAll; lodash.pullAllBy = array.pullAllBy; +lodash.pullAllWith = array.pullAllWith; lodash.pullAt = array.pullAt; lodash.range = util.range; lodash.rangeRight = util.rangeRight; @@ -221,6 +222,8 @@ lodash.uniqWith = array.uniqWith; lodash.unset = object.unset; lodash.unzip = array.unzip; lodash.unzipWith = array.unzipWith; +lodash.update = object.update; +lodash.updateWith = object.updateWith; lodash.values = object.values; lodash.valuesIn = object.valuesIn; lodash.without = array.without; diff --git a/lodash.js b/lodash.js index b493d24cf..7cfb2fb00 100644 --- a/lodash.js +++ b/lodash.js @@ -1,6 +1,6 @@ /** * @license - * lodash 4.5.1 (Custom Build) + * lodash 4.6.0 (Custom Build) * Build: `lodash modularize exports="es" -o ./` * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 @@ -201,6 +201,7 @@ export { default as propertyOf } from './propertyOf'; export { default as pull } from './pull'; export { default as pullAll } from './pullAll'; export { default as pullAllBy } from './pullAllBy'; +export { default as pullAllWith } from './pullAllWith'; export { default as pullAt } from './pullAt'; export { default as random } from './random'; export { default as range } from './range'; @@ -283,6 +284,8 @@ export { default as uniqueId } from './uniqueId'; export { default as unset } from './unset'; export { default as unzip } from './unzip'; export { default as unzipWith } from './unzipWith'; +export { default as update } from './update'; +export { default as updateWith } from './updateWith'; export { default as upperCase } from './upperCase'; export { default as upperFirst } from './upperFirst'; export { default as value } from './value'; diff --git a/merge.js b/merge.js index a00334f92..0368b8f87 100644 --- a/merge.js +++ b/merge.js @@ -2,12 +2,13 @@ import baseMerge from './_baseMerge'; import createAssigner from './_createAssigner'; /** - * Recursively merges own and inherited enumerable properties of source objects - * into the destination object. Source properties that resolve to `undefined` - * are skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable properties of source objects into the destination + * object. Source properties that resolve to `undefined` are skipped if a + * destination value exists. Array and plain object properties are merged + * recursively.Other objects and value types are overridden by assignment. + * Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. * * **Note:** This method mutates `object`. * diff --git a/object.default.js b/object.default.js index 30ef1a8fb..d87236cd2 100644 --- a/object.default.js +++ b/object.default.js @@ -38,6 +38,8 @@ import toPairs from './toPairs'; import toPairsIn from './toPairsIn'; import transform from './transform'; import unset from './unset'; +import update from './update'; +import updateWith from './updateWith'; import values from './values'; import valuesIn from './valuesIn'; @@ -50,5 +52,5 @@ export default { mapKeys, mapValues, merge, mergeWith, omit, omitBy, pick, pickBy, result, set, setWith, toPairs, toPairsIn, transform, unset, - values, valuesIn + update, updateWith, values, valuesIn }; diff --git a/object.js b/object.js index 8826ba4fb..d49b04b6d 100644 --- a/object.js +++ b/object.js @@ -38,6 +38,8 @@ export { default as toPairs } from './toPairs'; export { default as toPairsIn } from './toPairsIn'; export { default as transform } from './transform'; export { default as unset } from './unset'; +export { default as update } from './update'; +export { default as updateWith } from './updateWith'; export { default as values } from './values'; export { default as valuesIn } from './valuesIn'; export { default as default } from './object.default'; diff --git a/package.json b/package.json index 59f926e0f..441c14eb8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash-es", - "version": "4.5.1", + "version": "4.6.0", "description": "Lodash exported as ES modules.", "homepage": "https://lodash.com/custom-builds", "license": "MIT", diff --git a/pullAllBy.js b/pullAllBy.js index 585c8a543..e649aef41 100644 --- a/pullAllBy.js +++ b/pullAllBy.js @@ -1,10 +1,10 @@ import baseIteratee from './_baseIteratee'; -import basePullAllBy from './_basePullAllBy'; +import basePullAll from './_basePullAll'; /** * This method is like `_.pullAll` except that it accepts `iteratee` which is * invoked for each element of `array` and `values` to generate the criterion - * by which uniqueness is computed. The iteratee is invoked with one argument: (value). + * by which they're compared. The iteratee is invoked with one argument: (value). * * **Note:** Unlike `_.differenceBy`, this method mutates `array`. * @@ -25,7 +25,7 @@ import basePullAllBy from './_basePullAllBy'; */ function pullAllBy(array, values, iteratee) { return (array && array.length && values && values.length) - ? basePullAllBy(array, values, baseIteratee(iteratee)) + ? basePullAll(array, values, baseIteratee(iteratee)) : array; } diff --git a/pullAllWith.js b/pullAllWith.js new file mode 100644 index 000000000..dd2d6d3e8 --- /dev/null +++ b/pullAllWith.js @@ -0,0 +1,31 @@ +import basePullAll from './_basePullAll'; + +/** + * This method is like `_.pullAll` except that it accepts `comparator` which + * is invoked to compare elements of `array` to `values`. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.differenceWith`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; + * + * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); + * console.log(array); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] + */ +function pullAllWith(array, values, comparator) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, undefined, comparator) + : array; +} + +export default pullAllWith; diff --git a/setWith.js b/setWith.js index 880d64c6a..1baaa6e06 100644 --- a/setWith.js +++ b/setWith.js @@ -18,8 +18,10 @@ import baseSet from './_baseSet'; * @returns {Object} Returns `object`. * @example * - * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object); - * // => { '0': { '1': { '2': 3 }, 'length': 2 } } + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } */ function setWith(object, path, value, customizer) { customizer = typeof customizer == 'function' ? customizer : undefined; diff --git a/toLower.js b/toLower.js index 4a8b452cf..c3e7270be 100644 --- a/toLower.js +++ b/toLower.js @@ -1,7 +1,8 @@ import toString from './toString'; /** - * Converts `string`, as a whole, to lower case. + * Converts `string`, as a whole, to lower case just like + * [String#toLowerCase](https://mdn.io/toLowerCase). * * @static * @memberOf _ diff --git a/toString.js b/toString.js index e1af8b2be..0e289b708 100644 --- a/toString.js +++ b/toString.js @@ -6,7 +6,7 @@ var INFINITY = 1 / 0; /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = Symbol ? symbolProto.toString : undefined; + symbolToString = symbolProto ? symbolProto.toString : undefined; /** * Converts `value` to a string if it's not one. An empty string is returned @@ -37,7 +37,7 @@ function toString(value) { return ''; } if (isSymbol(value)) { - return Symbol ? symbolToString.call(value) : ''; + return symbolToString ? symbolToString.call(value) : ''; } var result = (value + ''); return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; diff --git a/toUpper.js b/toUpper.js index b1da10938..d06e55a21 100644 --- a/toUpper.js +++ b/toUpper.js @@ -1,7 +1,8 @@ import toString from './toString'; /** - * Converts `string`, as a whole, to upper case. + * Converts `string`, as a whole, to upper case just like + * [String#toUpperCase](https://mdn.io/toUpperCase). * * @static * @memberOf _ diff --git a/update.js b/update.js new file mode 100644 index 000000000..8a6a22727 --- /dev/null +++ b/update.js @@ -0,0 +1,34 @@ +import baseCastFunction from './_baseCastFunction'; +import baseUpdate from './_baseUpdate'; + +/** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ +function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, baseCastFunction(updater)); +} + +export default update; diff --git a/updateWith.js b/updateWith.js new file mode 100644 index 000000000..0a9930fce --- /dev/null +++ b/updateWith.js @@ -0,0 +1,32 @@ +import baseCastFunction from './_baseCastFunction'; +import baseUpdate from './_baseUpdate'; + +/** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ +function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseUpdate(object, path, baseCastFunction(updater), customizer); +} + +export default updateWith; diff --git a/wrapperLodash.js b/wrapperLodash.js index 6761677df..8bab5c782 100644 --- a/wrapperLodash.js +++ b/wrapperLodash.js @@ -53,46 +53,48 @@ var hasOwnProperty = objectProto.hasOwnProperty; * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, - * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, - * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, - * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`, - * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`, - * `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`, - * `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, - * `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`, - * `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`, - * `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`, - * `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`, - * `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, - * `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, - * `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, - * `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`, - * `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`, - * `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`, - * `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`, - * `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, - * `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith` + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatten`, `flattenDeep`, `flattenDepth`, `flip`, `flow`, `flowRight`, + * `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, `intersection`, + * `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, `invokeMap`, + * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, + * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`, + * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, + * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`, + * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`, + * `pullAll`, `pullAllBy`, `pullAllWith`, `pullAt`, `push`, `range`, + * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, + * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, + * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, + * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, + * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `update`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, + * `zipObjectDeep`, and `zipWith` * * The wrapper methods that are **not** chainable by default are: * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, - * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`, - * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, - * `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`, `forIn`, - * `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, - * `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, - * `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, - * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, - * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, - * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, - * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`, - * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, - * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, - * `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`, - * `now`, `pad`, `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `sample`, - * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, - * `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`, - * `sum`, `sumBy`, `template`, `times`, `toLower`, `toInteger`, `toLength`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `each`, `eachRight`, + * `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`, `floor`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`, `includes`, + * `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, `isArrayBuffer`, + * `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, `isDate`, + * `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, `isFinite`, + * `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, `isMatchWith`, + * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`, + * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isSet`, `isString`, + * `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, + * `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toInteger`, `toJSON`, `toLength`, `toLower`, * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`, * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`, * `value`, and `words` @@ -137,5 +139,6 @@ function lodash(value) { // Ensure wrappers are instances of `baseLodash`. lodash.prototype = baseLodash.prototype; +lodash.prototype.constructor = lodash; export default lodash; diff --git a/xor.js b/xor.js index 0a5b97458..f89eea0eb 100644 --- a/xor.js +++ b/xor.js @@ -5,7 +5,8 @@ import rest from './rest'; /** * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the given arrays. + * of the given arrays. The order of result values is determined by the order + * they occur in the arrays. * * @static * @memberOf _ diff --git a/xorBy.js b/xorBy.js index dfdb4ef52..c30ab224d 100644 --- a/xorBy.js +++ b/xorBy.js @@ -8,7 +8,7 @@ import rest from './rest'; /** * This method is like `_.xor` except that it accepts `iteratee` which is * invoked for each element of each `arrays` to generate the criterion by which - * uniqueness is computed. The iteratee is invoked with one argument: (value). + * by which they're compared. The iteratee is invoked with one argument: (value). * * @static * @memberOf _