diff --git a/LICENSE.txt b/LICENSE
similarity index 100%
rename from LICENSE.txt
rename to LICENSE
diff --git a/README.md b/README.md
index e5cd08ece..189265e7a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# lodash v3.9.3
+# lodash v3.10.0
The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) modules.
@@ -28,7 +28,7 @@ var array = require('lodash/array');
var chunk = require('lodash/array/chunk');
```
-See the [package source](https://github.com/lodash/lodash/tree/3.9.3-npm) for more details.
+See the [package source](https://github.com/lodash/lodash/tree/3.10.0-npm) for more details.
**Note:**
Don’t assign values to the [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL.
@@ -39,8 +39,8 @@ Install [n_](https://www.npmjs.com/package/n_) for a REPL that includes lodash b
lodash is also available in a variety of other builds & module formats.
* npm packages for [modern](https://www.npmjs.com/package/lodash), [compatibility](https://www.npmjs.com/package/lodash-compat), & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) builds
- * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.9.3-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.9.3-amd) builds
- * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.9.3-es) build
+ * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.10.0-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.10.0-amd) builds
+ * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.10.0-es) build
## Further Reading
@@ -55,8 +55,7 @@ lodash is also available in a variety of other builds & module formats.
* ~100% [code coverage](https://coveralls.io/r/lodash)
* Follows [semantic versioning](http://semver.org/) for releases
* [Lazily evaluated](http://filimanjaro.com/blog/2014/introducing-lazy-evaluation/) chaining
- * [_(…)](https://lodash.com/docs#_) supports intuitive chaining
- * [_.add](https://lodash.com/docs#add) for mathematical composition
+ * [_(…)](https://lodash.com/docs#_) supports implicit chaining
* [_.ary](https://lodash.com/docs#ary) & [_.rearg](https://lodash.com/docs#rearg) to change function argument limits & order
* [_.at](https://lodash.com/docs#at) for cherry-picking collection values
* [_.attempt](https://lodash.com/docs#attempt) to execute functions which may error without a try-catch
@@ -67,6 +66,7 @@ lodash is also available in a variety of other builds & module formats.
* [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays & objects
* [_.curry](https://lodash.com/docs#curry) & [_.curryRight](https://lodash.com/docs#curryRight) for creating [curried](http://hughfdjackson.com/javascript/why-curry-helps/) functions
* [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) are cancelable & accept options for more control
+ * [_.defaultsDeep](https://lodash.com/docs#defaultsDeep) for recursively assigning default properties
* [_.fill](https://lodash.com/docs#fill) to fill arrays with values
* [_.findKey](https://lodash.com/docs#findKey) for finding keys
* [_.flow](https://lodash.com/docs#flow) to complement [_.flowRight](https://lodash.com/docs#flowRight) (a.k.a `_.compose`)
@@ -82,8 +82,9 @@ lodash is also available in a variety of other builds & module formats.
* [_.mapKeys](https://lodash.com/docs#mapKeys) for mapping keys to an object
* [_.matches](https://lodash.com/docs#matches) supports deep object comparisons
* [_.matchesProperty](https://lodash.com/docs#matchesProperty) to complement [_.matches](https://lodash.com/docs#matches) & [_.property](https://lodash.com/docs#property)
- * [_.method](https://lodash.com/docs#method) & [_.methodOf](https://lodash.com/docs#methodOf) to create functions that invoke methods
* [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend)
+ * [_.method](https://lodash.com/docs#method) & [_.methodOf](https://lodash.com/docs#methodOf) to create functions that invoke methods
+ * [_.modArgs](https://lodash.com/docs#modArgs) for more advanced functional composition
* [_.parseInt](https://lodash.com/docs#parseInt) for consistent cross-environment behavior
* [_.pull](https://lodash.com/docs#pull), [_.pullAt](https://lodash.com/docs#pullAt), & [_.remove](https://lodash.com/docs#remove) for mutating arrays
* [_.random](https://lodash.com/docs#random) supports returning floating-point numbers
@@ -91,13 +92,14 @@ lodash is also available in a variety of other builds & module formats.
* [_.runInContext](https://lodash.com/docs#runInContext) for collisionless mixins & easier mocking
* [_.slice](https://lodash.com/docs#slice) for creating subsets of array-like values
* [_.sortByAll](https://lodash.com/docs#sortByAll) & [_.sortByOrder](https://lodash.com/docs#sortByOrder) for sorting by multiple properties & orders
- * [_.sum](https://lodash.com/docs#sum) to get the sum of values
* [_.support](https://lodash.com/docs#support) for flagging environment features
* [_.template](https://lodash.com/docs#template) supports [*“imports”*](https://lodash.com/docs#templateSettings-imports) options & [ES template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components)
* [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects
* [_.unzipWith](https://lodash.com/docs#unzipWith) & [_.zipWith](https://lodash.com/docs#zipWith) to specify how grouped values should be combined
- * [_.xor](https://lodash.com/docs#xor) to complement [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union)
* [_.valuesIn](https://lodash.com/docs#valuesIn) for getting values of all enumerable properties
+ * [_.xor](https://lodash.com/docs#xor) to complement [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union)
+ * [_.add](https://lodash.com/docs#add), [_.round](https://lodash.com/docs#round), [_.sum](https://lodash.com/docs#sum), &
+ [more](https://lodash.com/docs "_.ceil & _.floor") math methods
* [_.bind](https://lodash.com/docs#bind), [_.curry](https://lodash.com/docs#curry), [_.partial](https://lodash.com/docs#partial), &
[more](https://lodash.com/docs "_.bindKey, _.curryRight, _.partialRight") support customizable argument placeholders
* [_.capitalize](https://lodash.com/docs#capitalize), [_.trim](https://lodash.com/docs#trim), &
@@ -115,5 +117,5 @@ lodash is also available in a variety of other builds & module formats.
## Support
-Tested in Chrome 41-42, Firefox 37-38, IE 6-11, MS Edge, Opera 28-29, Safari 5-8, ChakraNode 0.12.2, io.js 2.1.0, Node.js 0.8.28, 0.10.38, & 0.12.4, PhantomJS 1.9.8, RingoJS 0.11, & Rhino 1.7.6.
+Tested in Chrome 42-43, Firefox 37-38, IE 6-11, MS Edge, Opera 28-29, Safari 5-8, ChakraNode 0.12.2, io.js 2.3.1, Node.js 0.8.28, 0.10.38, & 0.12.5, PhantomJS 1.9.8, RingoJS 0.11, & Rhino 1.7.6.
Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.
diff --git a/array/chunk.js b/array/chunk.js
index 4de9b3961..c8be1fb02 100644
--- a/array/chunk.js
+++ b/array/chunk.js
@@ -1,11 +1,10 @@
var baseSlice = require('../internal/baseSlice'),
isIterateeCall = require('../internal/isIterateeCall');
-/** Native method references. */
-var ceil = Math.ceil;
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeMax = Math.max;
+var nativeCeil = Math.ceil,
+ nativeFloor = Math.floor,
+ nativeMax = Math.max;
/**
* Creates an array of elements split into groups the length of `size`.
@@ -31,12 +30,12 @@ function chunk(array, size, guard) {
if (guard ? isIterateeCall(array, size, guard) : size == null) {
size = 1;
} else {
- size = nativeMax(+size || 1, 1);
+ size = nativeMax(nativeFloor(size) || 1, 1);
}
var index = 0,
length = array ? array.length : 0,
resIndex = -1,
- result = Array(ceil(length / size));
+ result = Array(nativeCeil(length / size));
while (index < length) {
result[++resIndex] = baseSlice(array, index, (index += size));
diff --git a/array/difference.js b/array/difference.js
index 5049337e5..128932a14 100644
--- a/array/difference.js
+++ b/array/difference.js
@@ -1,11 +1,12 @@
var baseDifference = require('../internal/baseDifference'),
baseFlatten = require('../internal/baseFlatten'),
isArrayLike = require('../internal/isArrayLike'),
+ isObjectLike = require('../internal/isObjectLike'),
restParam = require('../function/restParam');
/**
* Creates an array of unique `array` values not included in the other
- * provided arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
@@ -20,7 +21,7 @@ var baseDifference = require('../internal/baseDifference'),
* // => [1, 3]
*/
var difference = restParam(function(array, values) {
- return isArrayLike(array)
+ return (isObjectLike(array) && isArrayLike(array))
? baseDifference(array, baseFlatten(values, false, true))
: [];
});
diff --git a/array/indexOf.js b/array/indexOf.js
index f8f6c9fc2..bad310761 100644
--- a/array/indexOf.js
+++ b/array/indexOf.js
@@ -6,7 +6,7 @@ var nativeMax = Math.max;
/**
* Gets the index at which the first occurrence of `value` is found in `array`
- * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons. If `fromIndex` is negative, it is used as the offset
* from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
* performs a faster binary search.
@@ -40,10 +40,9 @@ function indexOf(array, value, fromIndex) {
if (typeof fromIndex == 'number') {
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
} else if (fromIndex) {
- var index = binaryIndex(array, value),
- other = array[index];
-
- if (value === value ? (value === other) : (other !== other)) {
+ var index = binaryIndex(array, value);
+ if (index < length &&
+ (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
return index;
}
return -1;
diff --git a/array/intersection.js b/array/intersection.js
index ec5b7f9b6..f218432cf 100644
--- a/array/intersection.js
+++ b/array/intersection.js
@@ -6,7 +6,7 @@ var baseIndexOf = require('../internal/baseIndexOf'),
/**
* Creates an array of unique values that are included in all of the provided
- * arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
diff --git a/array/pull.js b/array/pull.js
index 746f196f8..7bcbb4a63 100644
--- a/array/pull.js
+++ b/array/pull.js
@@ -8,7 +8,7 @@ var splice = arrayProto.splice;
/**
* Removes all provided values from `array` using
- * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* **Note:** Unlike `_.without`, this method mutates `array`.
diff --git a/array/union.js b/array/union.js
index 05101ca1c..53cefe432 100644
--- a/array/union.js
+++ b/array/union.js
@@ -4,7 +4,7 @@ var baseFlatten = require('../internal/baseFlatten'),
/**
* Creates an array of unique values, in order, from all of the provided arrays
- * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
diff --git a/array/uniq.js b/array/uniq.js
index 91ae46e24..f81a2b968 100644
--- a/array/uniq.js
+++ b/array/uniq.js
@@ -5,7 +5,7 @@ var baseCallback = require('../internal/baseCallback'),
/**
* Creates a duplicate-free version of an array, using
- * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons, in which only the first occurence of each element
* is kept. Providing `true` for `isSorted` performs a faster search algorithm
* for sorted arrays. If an iteratee function is provided it is invoked for
@@ -59,7 +59,7 @@ function uniq(array, isSorted, iteratee, thisArg) {
}
if (isSorted != null && typeof isSorted != 'boolean') {
thisArg = iteratee;
- iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted;
+ iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;
isSorted = false;
}
iteratee = iteratee == null ? iteratee : baseCallback(iteratee, thisArg, 3);
diff --git a/array/without.js b/array/without.js
index 19b78491a..2ac3d1176 100644
--- a/array/without.js
+++ b/array/without.js
@@ -4,7 +4,7 @@ var baseDifference = require('../internal/baseDifference'),
/**
* Creates an array excluding all provided values using
- * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
diff --git a/array/xor.js b/array/xor.js
index 3bdf9df12..04ef32aef 100644
--- a/array/xor.js
+++ b/array/xor.js
@@ -1,4 +1,5 @@
-var baseDifference = require('../internal/baseDifference'),
+var arrayPush = require('../internal/arrayPush'),
+ baseDifference = require('../internal/baseDifference'),
baseUniq = require('../internal/baseUniq'),
isArrayLike = require('../internal/isArrayLike');
@@ -24,7 +25,7 @@ function xor() {
var array = arguments[index];
if (isArrayLike(array)) {
var result = result
- ? baseDifference(result, array).concat(baseDifference(array, result))
+ ? arrayPush(baseDifference(result, array), baseDifference(array, result))
: array;
}
}
diff --git a/chain.js b/chain.js
index 7992b733e..6439627f3 100644
--- a/chain.js
+++ b/chain.js
@@ -1,6 +1,7 @@
module.exports = {
'chain': require('./chain/chain'),
'commit': require('./chain/commit'),
+ 'concat': require('./chain/concat'),
'lodash': require('./chain/lodash'),
'plant': require('./chain/plant'),
'reverse': require('./chain/reverse'),
diff --git a/chain/concat.js b/chain/concat.js
new file mode 100644
index 000000000..90607d1ee
--- /dev/null
+++ b/chain/concat.js
@@ -0,0 +1 @@
+module.exports = require('./wrapperConcat');
diff --git a/chain/lodash.js b/chain/lodash.js
index 3241ed89f..1c3467efe 100644
--- a/chain/lodash.js
+++ b/chain/lodash.js
@@ -14,15 +14,16 @@ var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Creates a `lodash` object which wraps `value` to enable implicit chaining.
* Methods that operate on and return arrays, collections, and functions can
- * be chained together. Methods that return a boolean or single value will
- * automatically end the chain returning the unwrapped value. Explicit chaining
- * may be enabled using `_.chain`. The execution of chained methods is lazy,
- * that is, execution is deferred until `_#value` is implicitly or explicitly
- * called.
+ * be chained together. Methods that retrieve a single value or may return a
+ * primitive value will automatically end the chain returning the unwrapped
+ * value. Explicit chaining may be enabled using `_.chain`. The execution of
+ * chained methods is lazy, that is, execution is deferred until `_#value`
+ * is implicitly or explicitly called.
*
* Lazy evaluation allows several methods to support shortcut fusion. Shortcut
- * fusion is an optimization that merges iteratees to avoid creating intermediate
- * arrays and reduce the number of iteratee executions.
+ * fusion is an optimization strategy which merge iteratee calls; this can help
+ * to avoid the creation of intermediate data structures and greatly reduce the
+ * number of iteratee executions.
*
* Chaining is supported in custom builds as long as the `_#value` method is
* directly or indirectly included in the build.
@@ -45,36 +46,37 @@ var hasOwnProperty = objectProto.hasOwnProperty;
* The chainable wrapper methods are:
* `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
* `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
- * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`,
- * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`,
- * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`,
- * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`,
- * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`,
- * `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
- * `memoize`, `merge`, `method`, `methodOf`, `mixin`, `negate`, `omit`, `once`,
- * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`,
- * `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`,
- * `reject`, `remove`, `rest`, `restParam`, `reverse`, `set`, `shuffle`,
- * `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, `spread`,
- * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`,
- * `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`,
- * `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `where`, `without`,
- * `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
+ * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
+ * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
+ * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
+ * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
+ * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
+ * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
+ * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
+ * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
+ * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
+ * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
+ * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
+ * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
+ * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
+ * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
+ * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
*
* The wrapper methods that are **not** chainable by default are:
- * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`,
- * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
- * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `get`,
- * `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, `inRange`, `isArguments`,
- * `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`,
- * `isFinite` `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`,
- * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`,
- * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`,
- * `max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`,
- * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`,
- * `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
- * `sortedLastIndex`, `startCase`, `startsWith`, `sum`, `template`, `trim`,
- * `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, `value`, and `words`
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
+ * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
+ * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
+ * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
+ * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
+ * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
+ * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
+ * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
+ * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
+ * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
+ * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
+ * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
+ * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
+ * `unescape`, `uniqueId`, `value`, and `words`
*
* The wrapper method `sample` will return a wrapped value when `n` is provided,
* otherwise an unwrapped value is returned.
diff --git a/chain/wrapperCommit.js b/chain/wrapperCommit.js
index c46a787e9..c3d289804 100644
--- a/chain/wrapperCommit.js
+++ b/chain/wrapperCommit.js
@@ -10,16 +10,16 @@ var LodashWrapper = require('../internal/LodashWrapper');
* @example
*
* var array = [1, 2];
- * var wrapper = _(array).push(3);
+ * var wrapped = _(array).push(3);
*
* console.log(array);
* // => [1, 2]
*
- * wrapper = wrapper.commit();
+ * wrapped = wrapped.commit();
* console.log(array);
* // => [1, 2, 3]
*
- * wrapper.last();
+ * wrapped.last();
* // => 3
*
* console.log(array);
diff --git a/chain/wrapperConcat.js b/chain/wrapperConcat.js
new file mode 100644
index 000000000..799156cd8
--- /dev/null
+++ b/chain/wrapperConcat.js
@@ -0,0 +1,34 @@
+var arrayConcat = require('../internal/arrayConcat'),
+ baseFlatten = require('../internal/baseFlatten'),
+ isArray = require('../lang/isArray'),
+ restParam = require('../function/restParam'),
+ toObject = require('../internal/toObject');
+
+/**
+ * Creates a new array joining a wrapped array with any additional arrays
+ * and/or values.
+ *
+ * @name concat
+ * @memberOf _
+ * @category Chain
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var wrapped = _(array).concat(2, [3], [[4]]);
+ *
+ * console.log(wrapped.value());
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */
+var wrapperConcat = restParam(function(values) {
+ values = baseFlatten(values);
+ return this.thru(function(array) {
+ return arrayConcat(isArray(array) ? array : [toObject(array)], values);
+ });
+});
+
+module.exports = wrapperConcat;
diff --git a/chain/wrapperPlant.js b/chain/wrapperPlant.js
index a3de146b1..234fe41fe 100644
--- a/chain/wrapperPlant.js
+++ b/chain/wrapperPlant.js
@@ -11,17 +11,17 @@ var baseLodash = require('../internal/baseLodash'),
* @example
*
* var array = [1, 2];
- * var wrapper = _(array).map(function(value) {
+ * var wrapped = _(array).map(function(value) {
* return Math.pow(value, 2);
* });
*
* var other = [3, 4];
- * var otherWrapper = wrapper.plant(other);
+ * var otherWrapped = wrapped.plant(other);
*
- * otherWrapper.value();
+ * otherWrapped.value();
* // => [9, 16]
*
- * wrapper.value();
+ * wrapped.value();
* // => [1, 4]
*/
function wrapperPlant(value) {
diff --git a/chain/wrapperReverse.js b/chain/wrapperReverse.js
index 4518b3ed2..f2b3d19c1 100644
--- a/chain/wrapperReverse.js
+++ b/chain/wrapperReverse.js
@@ -24,15 +24,20 @@ var LazyWrapper = require('../internal/LazyWrapper'),
*/
function wrapperReverse() {
var value = this.__wrapped__;
+
+ var interceptor = function(value) {
+ return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse();
+ };
if (value instanceof LazyWrapper) {
+ var wrapped = value;
if (this.__actions__.length) {
- value = new LazyWrapper(this);
+ wrapped = new LazyWrapper(this);
}
- return new LodashWrapper(value.reverse(), this.__chain__);
+ wrapped = wrapped.reverse();
+ wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
+ return new LodashWrapper(wrapped, this.__chain__);
}
- return this.thru(function(value) {
- return value.reverse();
- });
+ return this.thru(interceptor);
}
module.exports = wrapperReverse;
diff --git a/collection/every.js b/collection/every.js
index a04d3db63..5a2d0f5dd 100644
--- a/collection/every.js
+++ b/collection/every.js
@@ -55,7 +55,7 @@ var arrayEvery = require('../internal/arrayEvery'),
function every(collection, predicate, thisArg) {
var func = isArray(collection) ? arrayEvery : baseEvery;
if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
- predicate = null;
+ predicate = undefined;
}
if (typeof predicate != 'function' || thisArg !== undefined) {
predicate = baseCallback(predicate, thisArg, 3);
diff --git a/collection/includes.js b/collection/includes.js
index 80c90e1e3..482e42d11 100644
--- a/collection/includes.js
+++ b/collection/includes.js
@@ -11,7 +11,7 @@ var nativeMax = Math.max;
/**
* Checks if `value` is in `collection` using
- * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons. If `fromIndex` is negative, it is used as the offset
* from the end of `collection`.
*
@@ -44,17 +44,14 @@ function includes(collection, target, fromIndex, guard) {
collection = values(collection);
length = collection.length;
}
- if (!length) {
- return false;
- }
if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
fromIndex = 0;
} else {
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
}
return (typeof collection == 'string' || !isArray(collection) && isString(collection))
- ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1)
- : (baseIndexOf(collection, target, fromIndex) > -1);
+ ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)
+ : (!!length && baseIndexOf(collection, target, fromIndex) > -1);
}
module.exports = includes;
diff --git a/collection/invoke.js b/collection/invoke.js
index 0a0a84cdb..a1f8a2019 100644
--- a/collection/invoke.js
+++ b/collection/invoke.js
@@ -33,7 +33,7 @@ var invoke = restParam(function(collection, path, args) {
result = isArrayLike(collection) ? Array(collection.length) : [];
baseEach(collection, function(value) {
- var func = isFunc ? path : ((isProp && value != null) ? value[path] : null);
+ var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);
});
return result;
diff --git a/collection/reduce.js b/collection/reduce.js
index da97655c1..5d5e8c916 100644
--- a/collection/reduce.js
+++ b/collection/reduce.js
@@ -14,7 +14,8 @@ var arrayReduce = require('../internal/arrayReduce'),
* `_.reduce`, `_.reduceRight`, and `_.transform`.
*
* The guarded methods are:
- * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder`
+ * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`,
+ * and `sortByOrder`
*
* @static
* @memberOf _
diff --git a/collection/some.js b/collection/some.js
index 2b866b464..d0b09a474 100644
--- a/collection/some.js
+++ b/collection/some.js
@@ -56,7 +56,7 @@ var arraySome = require('../internal/arraySome'),
function some(collection, predicate, thisArg) {
var func = isArray(collection) ? arraySome : baseSome;
if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
- predicate = null;
+ predicate = undefined;
}
if (typeof predicate != 'function' || thisArg !== undefined) {
predicate = baseCallback(predicate, thisArg, 3);
diff --git a/collection/sortBy.js b/collection/sortBy.js
index 28d75f56d..4401c777f 100644
--- a/collection/sortBy.js
+++ b/collection/sortBy.js
@@ -57,7 +57,7 @@ function sortBy(collection, iteratee, thisArg) {
return [];
}
if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = null;
+ iteratee = undefined;
}
var index = -1;
iteratee = baseCallback(iteratee, thisArg, 3);
diff --git a/collection/sortByOrder.js b/collection/sortByOrder.js
index c704eeb61..8b4fc1968 100644
--- a/collection/sortByOrder.js
+++ b/collection/sortByOrder.js
@@ -4,9 +4,9 @@ var baseSortByOrder = require('../internal/baseSortByOrder'),
/**
* This method is like `_.sortByAll` except that it allows specifying the
- * sort orders of the iteratees to sort by. A truthy value in `orders` will
- * sort the corresponding property name in ascending order while a falsey
- * value will sort it in descending order.
+ * sort orders of the iteratees to sort by. If `orders` is unspecified, all
+ * values are sorted in ascending order. Otherwise, a value is sorted in
+ * ascending order if its corresponding order is "asc", and descending if "desc".
*
* If a property name is provided for an iteratee the created `_.property`
* style callback returns the property value of the given element.
@@ -20,7 +20,7 @@ var baseSortByOrder = require('../internal/baseSortByOrder'),
* @category Collection
* @param {Array|Object|string} collection The collection to iterate over.
* @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
- * @param {boolean[]} orders The sort orders of `iteratees`.
+ * @param {boolean[]} [orders] The sort orders of `iteratees`.
* @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
* @returns {Array} Returns the new sorted array.
* @example
@@ -33,7 +33,7 @@ var baseSortByOrder = require('../internal/baseSortByOrder'),
* ];
*
* // sort by `user` in ascending order and by `age` in descending order
- * _.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values);
+ * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values);
* // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
*/
function sortByOrder(collection, iteratees, orders, guard) {
@@ -41,7 +41,7 @@ function sortByOrder(collection, iteratees, orders, guard) {
return [];
}
if (guard && isIterateeCall(iteratees, orders, guard)) {
- orders = null;
+ orders = undefined;
}
if (!isArray(iteratees)) {
iteratees = iteratees == null ? [] : [iteratees];
diff --git a/function.js b/function.js
index 2cacde1ee..71f8ebeb2 100644
--- a/function.js
+++ b/function.js
@@ -15,6 +15,7 @@ module.exports = {
'flow': require('./function/flow'),
'flowRight': require('./function/flowRight'),
'memoize': require('./function/memoize'),
+ 'modArgs': require('./function/modArgs'),
'negate': require('./function/negate'),
'once': require('./function/once'),
'partial': require('./function/partial'),
diff --git a/function/ary.js b/function/ary.js
index 1bcb6a720..53a6913e3 100644
--- a/function/ary.js
+++ b/function/ary.js
@@ -25,10 +25,10 @@ var nativeMax = Math.max;
*/
function ary(func, n, guard) {
if (guard && isIterateeCall(func, n, guard)) {
- n = null;
+ n = undefined;
}
n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);
- return createWrapper(func, ARY_FLAG, null, null, null, null, n);
+ return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
}
module.exports = ary;
diff --git a/function/before.js b/function/before.js
index 4afd1e60a..dd1d03bca 100644
--- a/function/before.js
+++ b/function/before.js
@@ -33,7 +33,7 @@ function before(n, func) {
result = func.apply(this, arguments);
}
if (n <= 1) {
- func = null;
+ func = undefined;
}
return result;
};
diff --git a/function/debounce.js b/function/debounce.js
index 5df81e71a..caf2a69d0 100644
--- a/function/debounce.js
+++ b/function/debounce.js
@@ -90,9 +90,9 @@ function debounce(func, wait, options) {
var leading = true;
trailing = false;
} else if (isObject(options)) {
- leading = options.leading;
+ leading = !!options.leading;
maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
- trailing = 'trailing' in options ? options.trailing : trailing;
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function cancel() {
@@ -102,41 +102,35 @@ function debounce(func, wait, options) {
if (maxTimeoutId) {
clearTimeout(maxTimeoutId);
}
+ lastCalled = 0;
maxTimeoutId = timeoutId = trailingCall = undefined;
}
+ function complete(isCalled, id) {
+ if (id) {
+ clearTimeout(id);
+ }
+ maxTimeoutId = timeoutId = trailingCall = undefined;
+ if (isCalled) {
+ lastCalled = now();
+ result = func.apply(thisArg, args);
+ if (!timeoutId && !maxTimeoutId) {
+ args = thisArg = undefined;
+ }
+ }
+ }
+
function delayed() {
var remaining = wait - (now() - stamp);
if (remaining <= 0 || remaining > wait) {
- if (maxTimeoutId) {
- clearTimeout(maxTimeoutId);
- }
- var isCalled = trailingCall;
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (isCalled) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
+ complete(trailingCall, maxTimeoutId);
} else {
timeoutId = setTimeout(delayed, remaining);
}
}
function maxDelayed() {
- if (timeoutId) {
- clearTimeout(timeoutId);
- }
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (trailing || (maxWait !== wait)) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
+ complete(trailing, timeoutId);
}
function debounced() {
@@ -176,7 +170,7 @@ function debounce(func, wait, options) {
result = func.apply(thisArg, args);
}
if (isCalled && !timeoutId && !maxTimeoutId) {
- args = thisArg = null;
+ args = thisArg = undefined;
}
return result;
}
diff --git a/function/memoize.js b/function/memoize.js
index 1088e4be6..f3b8d6992 100644
--- a/function/memoize.js
+++ b/function/memoize.js
@@ -13,7 +13,7 @@ var FUNC_ERROR_TEXT = 'Expected a function';
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
- * constructor with one whose instances implement the [`Map`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object)
+ * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
* method interface of `get`, `has`, and `set`.
*
* @static
diff --git a/function/modArgs.js b/function/modArgs.js
new file mode 100644
index 000000000..49b9b5e68
--- /dev/null
+++ b/function/modArgs.js
@@ -0,0 +1,58 @@
+var arrayEvery = require('../internal/arrayEvery'),
+ baseFlatten = require('../internal/baseFlatten'),
+ baseIsFunction = require('../internal/baseIsFunction'),
+ restParam = require('./restParam');
+
+/** Used as the `TypeError` message for "Functions" methods. */
+var FUNC_ERROR_TEXT = 'Expected a function';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMin = Math.min;
+
+/**
+ * Creates a function that runs each argument through a corresponding
+ * transform function.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to wrap.
+ * @param {...(Function|Function[])} [transforms] The functions to transform
+ * arguments, specified as individual functions or arrays of functions.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function doubled(n) {
+ * return n * 2;
+ * }
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var modded = _.modArgs(function(x, y) {
+ * return [x, y];
+ * }, square, doubled);
+ *
+ * modded(1, 2);
+ * // => [1, 4]
+ *
+ * modded(5, 10);
+ * // => [25, 20]
+ */
+var modArgs = restParam(function(func, transforms) {
+ transforms = baseFlatten(transforms);
+ if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ var length = transforms.length;
+ return restParam(function(args) {
+ var index = nativeMin(args.length, length);
+ while (index--) {
+ args[index] = transforms[index](args[index]);
+ }
+ return func.apply(this, args);
+ });
+});
+
+module.exports = modArgs;
diff --git a/function/rearg.js b/function/rearg.js
index 0a4bf8fa6..f2bd9c41e 100644
--- a/function/rearg.js
+++ b/function/rearg.js
@@ -34,7 +34,7 @@ var REARG_FLAG = 256;
* // => [3, 6, 9]
*/
var rearg = restParam(function(func, indexes) {
- return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(indexes));
+ return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
});
module.exports = rearg;
diff --git a/function/throttle.js b/function/throttle.js
index 5e8f0ef56..1dd00eab7 100644
--- a/function/throttle.js
+++ b/function/throttle.js
@@ -4,13 +4,6 @@ var debounce = require('./debounce'),
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
-/** Used as an internal `_.debounce` options object by `_.throttle`. */
-var debounceOptions = {
- 'leading': false,
- 'maxWait': 0,
- 'trailing': false
-};
-
/**
* Creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds. The throttled function comes with a `cancel`
@@ -63,10 +56,7 @@ function throttle(func, wait, options) {
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
- debounceOptions.leading = leading;
- debounceOptions.maxWait = +wait;
- debounceOptions.trailing = trailing;
- return debounce(func, wait, debounceOptions);
+ return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
}
module.exports = throttle;
diff --git a/function/wrap.js b/function/wrap.js
index 68b09af23..6a33c5ec6 100644
--- a/function/wrap.js
+++ b/function/wrap.js
@@ -27,7 +27,7 @@ var PARTIAL_FLAG = 32;
*/
function wrap(value, wrapper) {
wrapper = wrapper == null ? identity : wrapper;
- return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []);
+ return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);
}
module.exports = wrap;
diff --git a/index.js b/index.js
index deb66539d..be768eef1 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1,6 @@
/**
* @license
- * lodash 3.9.3 (Custom Build)
+ * lodash 3.10.0 (Custom Build)
* Build: `lodash modern -d -o ./index.js`
* Copyright 2012-2015 The Dojo Foundation
* Based on Underscore.js 1.8.3
@@ -13,7 +13,7 @@
var undefined;
/** Used as the semantic version number. */
- var VERSION = '3.9.3';
+ var VERSION = '3.10.0';
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -34,9 +34,11 @@
var HOT_COUNT = 150,
HOT_SPAN = 16;
+ /** Used as the size to enable large array optimizations. */
+ var LARGE_ARRAY_SIZE = 200;
+
/** Used to indicate the type of lazy iteratees. */
- var LAZY_DROP_WHILE_FLAG = 0,
- LAZY_FILTER_FLAG = 1,
+ var LAZY_FILTER_FLAG = 1,
LAZY_MAP_FLAG = 2;
/** Used as the `TypeError` message for "Functions" methods. */
@@ -93,11 +95,10 @@
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
/**
- * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special).
- * In addition to special characters the forward slash is escaped to allow for
- * easier `eval` use and `Function` compilation.
+ * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns)
+ * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern).
*/
- var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g,
+ var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,
reHasRegExpChars = RegExp(reRegExpChars.source);
/** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
@@ -106,7 +107,7 @@
/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;
- /** Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components). */
+ /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
/** Used to match `RegExp` flags from their coerced string values. */
@@ -138,25 +139,13 @@
return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');
}());
- /** Used to detect and test for whitespace. */
- var whitespace = (
- // Basic whitespace characters.
- ' \t\x0b\f\xa0\ufeff' +
-
- // Line terminators.
- '\n\r\u2028\u2029' +
-
- // Unicode category "Zs" space separators.
- '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
- );
-
/** Used to assign default `context` object properties. */
var contextProps = [
'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
- 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document',
- 'isFinite', 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
- 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', 'window'
+ 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite',
+ 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
+ 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap'
];
/** Used to make template sourceURLs easier to identify. */
@@ -192,13 +181,6 @@
cloneableTags[mapTag] = cloneableTags[setTag] =
cloneableTags[weakMapTag] = false;
- /** Used as an internal `_.debounce` options object by `_.throttle`. */
- var debounceOptions = {
- 'leading': false,
- 'maxWait': 0,
- 'trailing': false
- };
-
/** Used to map latin-1 supplementary letters to basic latin letters. */
var deburredLetters = {
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
@@ -246,6 +228,15 @@
'object': true
};
+ /** Used to escape characters for inclusion in compiled regexes. */
+ var regexpEscapes = {
+ '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34',
+ '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39',
+ 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46',
+ 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66',
+ 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78'
+ };
+
/** Used to escape characters for inclusion in compiled string literals. */
var stringEscapes = {
'\\': '\\',
@@ -386,9 +377,6 @@
* @returns {string} Returns the string.
*/
function baseToString(value) {
- if (typeof value == 'string') {
- return value;
- }
return value == null ? '' : (value + '');
}
@@ -430,8 +418,8 @@
* sort them in ascending order.
*
* @private
- * @param {Object} object The object to compare to `other`.
- * @param {Object} other The object to compare to `object`.
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
* @returns {number} Returns the sort order indicator for `object`.
*/
function compareAscending(object, other) {
@@ -439,16 +427,16 @@
}
/**
- * Used by `_.sortByOrder` to compare multiple properties of each element
- * in a collection and stable sort them in the following order:
+ * Used by `_.sortByOrder` to compare multiple properties of a value to another
+ * and stable sort them.
*
- * If `orders` is unspecified, sort in ascending order for all properties.
- * Otherwise, for each property, sort in ascending order if its corresponding value in
- * orders is true, and descending order if false.
+ * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise,
+ * a value is sorted in ascending order if its corresponding order is "asc", and
+ * descending if "desc".
*
* @private
- * @param {Object} object The object to compare to `other`.
- * @param {Object} other The object to compare to `object`.
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
* @param {boolean[]} orders The order to sort by for each property.
* @returns {number} Returns the sort order indicator for `object`.
*/
@@ -465,7 +453,8 @@
if (index >= ordersLength) {
return result;
}
- return result * (orders[index] ? 1 : -1);
+ var order = orders[index];
+ return result * ((order === 'asc' || order === true) ? 1 : -1);
}
}
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
@@ -501,8 +490,25 @@
}
/**
- * Used by `_.template` to escape characters for inclusion in compiled
- * string literals.
+ * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes.
+ *
+ * @private
+ * @param {string} chr The matched character to escape.
+ * @param {string} leadingChar The capture group for a leading character.
+ * @param {string} whitespaceChar The capture group for a whitespace character.
+ * @returns {string} Returns the escaped character.
+ */
+ function escapeRegExpChar(chr, leadingChar, whitespaceChar) {
+ if (leadingChar) {
+ chr = regexpEscapes[chr];
+ } else if (whitespaceChar) {
+ chr = stringEscapes[chr];
+ }
+ return '\\' + chr;
+ }
+
+ /**
+ * Used by `_.template` to escape characters for inclusion in compiled string literals.
*
* @private
* @param {string} chr The matched character to escape.
@@ -713,9 +719,6 @@
objectProto = Object.prototype,
stringProto = String.prototype;
- /** Used to detect DOM support. */
- var document = (document = context.window) ? document.document : null;
-
/** Used to resolve the decompiled source of functions. */
var fnToString = Function.prototype.toString;
@@ -726,56 +729,42 @@
var idCounter = 0;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/** Used to restore the original `_` reference in `_.noConflict`. */
- var oldDash = context._;
+ var oldDash = root._;
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
- escapeRegExp(fnToString.call(hasOwnProperty))
+ fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
/** Native method references. */
- var ArrayBuffer = getNative(context, 'ArrayBuffer'),
- bufferSlice = getNative(ArrayBuffer && new ArrayBuffer(0), 'slice'),
- ceil = Math.ceil,
+ var ArrayBuffer = context.ArrayBuffer,
clearTimeout = context.clearTimeout,
- floor = Math.floor,
- getPrototypeOf = getNative(Object, 'getPrototypeOf'),
parseFloat = context.parseFloat,
- push = arrayProto.push,
+ pow = Math.pow,
+ propertyIsEnumerable = objectProto.propertyIsEnumerable,
Set = getNative(context, 'Set'),
setTimeout = context.setTimeout,
splice = arrayProto.splice,
- Uint8Array = getNative(context, 'Uint8Array'),
+ Uint8Array = context.Uint8Array,
WeakMap = getNative(context, 'WeakMap');
- /** Used to clone array buffers. */
- var Float64Array = (function() {
- // Safari 5 errors when using an array buffer to initialize a typed array
- // where the array buffer's `byteLength` is not a multiple of the typed
- // array's `BYTES_PER_ELEMENT`.
- try {
- var func = getNative(context, 'Float64Array'),
- result = new func(new ArrayBuffer(10), 0, 1) && func;
- } catch(e) {}
- return result || null;
- }());
-
/* Native method references for those with the same name as other `lodash` methods. */
- var nativeCreate = getNative(Object, 'create'),
+ var nativeCeil = Math.ceil,
+ nativeCreate = getNative(Object, 'create'),
+ nativeFloor = Math.floor,
nativeIsArray = getNative(Array, 'isArray'),
nativeIsFinite = context.isFinite,
nativeKeys = getNative(Object, 'keys'),
nativeMax = Math.max,
nativeMin = Math.min,
nativeNow = getNative(Date, 'now'),
- nativeNumIsFinite = getNative(Number, 'isFinite'),
nativeParseInt = context.parseInt,
nativeRandom = Math.random;
@@ -788,11 +777,8 @@
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
- /** Used as the size, in bytes, of each `Float64Array` element. */
- var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
-
/**
- * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
* of an array-like value.
*/
var MAX_SAFE_INTEGER = 9007199254740991;
@@ -808,15 +794,16 @@
/**
* Creates a `lodash` object which wraps `value` to enable implicit chaining.
* Methods that operate on and return arrays, collections, and functions can
- * be chained together. Methods that return a boolean or single value will
- * automatically end the chain returning the unwrapped value. Explicit chaining
- * may be enabled using `_.chain`. The execution of chained methods is lazy,
- * that is, execution is deferred until `_#value` is implicitly or explicitly
- * called.
+ * be chained together. Methods that retrieve a single value or may return a
+ * primitive value will automatically end the chain returning the unwrapped
+ * value. Explicit chaining may be enabled using `_.chain`. The execution of
+ * chained methods is lazy, that is, execution is deferred until `_#value`
+ * is implicitly or explicitly called.
*
* Lazy evaluation allows several methods to support shortcut fusion. Shortcut
- * fusion is an optimization that merges iteratees to avoid creating intermediate
- * arrays and reduce the number of iteratee executions.
+ * fusion is an optimization strategy which merge iteratee calls; this can help
+ * to avoid the creation of intermediate data structures and greatly reduce the
+ * number of iteratee executions.
*
* Chaining is supported in custom builds as long as the `_#value` method is
* directly or indirectly included in the build.
@@ -839,36 +826,37 @@
* The chainable wrapper methods are:
* `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
* `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
- * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`,
- * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`,
- * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`,
- * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`,
- * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`,
- * `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
- * `memoize`, `merge`, `method`, `methodOf`, `mixin`, `negate`, `omit`, `once`,
- * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`,
- * `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`,
- * `reject`, `remove`, `rest`, `restParam`, `reverse`, `set`, `shuffle`,
- * `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, `spread`,
- * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`,
- * `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`,
- * `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `where`, `without`,
- * `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
+ * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
+ * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
+ * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
+ * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
+ * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
+ * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
+ * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
+ * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
+ * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
+ * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
+ * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
+ * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
+ * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
+ * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
+ * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
*
* The wrapper methods that are **not** chainable by default are:
- * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`,
- * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
- * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `get`,
- * `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, `inRange`, `isArguments`,
- * `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`,
- * `isFinite` `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`,
- * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`,
- * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`,
- * `max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`,
- * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`,
- * `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
- * `sortedLastIndex`, `startCase`, `startsWith`, `sum`, `template`, `trim`,
- * `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, `value`, and `words`
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
+ * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
+ * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
+ * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
+ * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
+ * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
+ * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
+ * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
+ * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
+ * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
+ * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
+ * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
+ * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
+ * `unescape`, `uniqueId`, `value`, and `words`
*
* The wrapper method `sample` will return a wrapped value when `n` is provided,
* otherwise an unwrapped value is returned.
@@ -943,27 +931,6 @@
*/
var support = lodash.support = {};
- (function(x) {
- var Ctor = function() { this.x = x; },
- object = { '0': x, 'length': x },
- props = [];
-
- Ctor.prototype = { 'valueOf': x, 'y': x };
- for (var key in new Ctor) { props.push(key); }
-
- /**
- * Detect if the DOM is supported.
- *
- * @memberOf _.support
- * @type boolean
- */
- try {
- support.dom = document.createDocumentFragment().nodeType === 11;
- } catch(e) {
- support.dom = false;
- }
- }(1, 0));
-
/**
* By default, the template delimiters used by lodash are like those in
* embedded Ruby (ERB). Change the following template settings to use
@@ -1035,13 +1002,12 @@
*/
function LazyWrapper(value) {
this.__wrapped__ = value;
- this.__actions__ = null;
+ this.__actions__ = [];
this.__dir__ = 1;
- this.__dropCount__ = 0;
this.__filtered__ = false;
- this.__iteratees__ = null;
+ this.__iteratees__ = [];
this.__takeCount__ = POSITIVE_INFINITY;
- this.__views__ = null;
+ this.__views__ = [];
}
/**
@@ -1053,17 +1019,13 @@
* @returns {Object} Returns the cloned `LazyWrapper` object.
*/
function lazyClone() {
- var actions = this.__actions__,
- iteratees = this.__iteratees__,
- views = this.__views__,
- result = new LazyWrapper(this.__wrapped__);
-
- result.__actions__ = actions ? arrayCopy(actions) : null;
+ var result = new LazyWrapper(this.__wrapped__);
+ result.__actions__ = arrayCopy(this.__actions__);
result.__dir__ = this.__dir__;
result.__filtered__ = this.__filtered__;
- result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null;
+ result.__iteratees__ = arrayCopy(this.__iteratees__);
result.__takeCount__ = this.__takeCount__;
- result.__views__ = views ? arrayCopy(views) : null;
+ result.__views__ = arrayCopy(this.__views__);
return result;
}
@@ -1096,22 +1058,25 @@
* @returns {*} Returns the unwrapped value.
*/
function lazyValue() {
- var array = this.__wrapped__.value();
- if (!isArray(array)) {
- return baseWrapperValue(array, this.__actions__);
- }
- var dir = this.__dir__,
+ var array = this.__wrapped__.value(),
+ dir = this.__dir__,
+ isArr = isArray(array),
isRight = dir < 0,
- view = getView(0, array.length, this.__views__),
+ arrLength = isArr ? array.length : 0,
+ view = getView(0, arrLength, this.__views__),
start = view.start,
end = view.end,
length = end - start,
index = isRight ? end : (start - 1),
- takeCount = nativeMin(length, this.__takeCount__),
iteratees = this.__iteratees__,
- iterLength = iteratees ? iteratees.length : 0,
+ iterLength = iteratees.length,
resIndex = 0,
- result = [];
+ takeCount = nativeMin(length, this.__takeCount__);
+
+ if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
+ return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__);
+ }
+ var result = [];
outer:
while (length-- && resIndex < takeCount) {
@@ -1123,30 +1088,16 @@
while (++iterIndex < iterLength) {
var data = iteratees[iterIndex],
iteratee = data.iteratee,
- type = data.type;
+ type = data.type,
+ computed = iteratee(value);
- if (type == LAZY_DROP_WHILE_FLAG) {
- if (data.done && (isRight ? (index > data.index) : (index < data.index))) {
- data.count = 0;
- data.done = false;
- }
- data.index = index;
- if (!data.done) {
- var limit = data.limit;
- if (!(data.done = limit > -1 ? (data.count++ >= limit) : !iteratee(value))) {
- continue outer;
- }
- }
- } else {
- var computed = iteratee(value);
- if (type == LAZY_MAP_FLAG) {
- value = computed;
- } else if (!computed) {
- if (type == LAZY_FILTER_FLAG) {
- continue outer;
- } else {
- break outer;
- }
+ if (type == LAZY_MAP_FLAG) {
+ value = computed;
+ } else if (!computed) {
+ if (type == LAZY_FILTER_FLAG) {
+ continue outer;
+ } else {
+ break outer;
}
}
}
@@ -1278,6 +1229,30 @@
/*------------------------------------------------------------------------*/
+ /**
+ * Creates a new array joining `array` with `other`.
+ *
+ * @private
+ * @param {Array} array The array to join.
+ * @param {Array} other The other array to join.
+ * @returns {Array} Returns the new concatenated array.
+ */
+ function arrayConcat(array, other) {
+ var index = -1,
+ length = array.length,
+ othIndex = -1,
+ othLength = other.length,
+ result = Array(length + othLength);
+
+ while (++index < length) {
+ result[index] = array[index];
+ }
+ while (++othIndex < othLength) {
+ result[index++] = other[othIndex];
+ }
+ return result;
+ }
+
/**
* Copies the values of `source` to `array`.
*
@@ -1433,6 +1408,25 @@
return result;
}
+ /**
+ * Appends the elements of `values` to `array`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to append.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayPush(array, values) {
+ var index = -1,
+ length = values.length,
+ offset = array.length;
+
+ while (++index < length) {
+ array[offset + index] = values[index];
+ }
+ return array;
+ }
+
/**
* A specialized version of `_.reduce` for arrays without support for callback
* shorthands and `this` binding.
@@ -1504,18 +1498,20 @@
}
/**
- * A specialized version of `_.sum` for arrays without support for iteratees.
+ * A specialized version of `_.sum` for arrays without support for callback
+ * shorthands and `this` binding..
*
* @private
* @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
* @returns {number} Returns the sum.
*/
- function arraySum(array) {
+ function arraySum(array, iteratee) {
var length = array.length,
result = 0;
while (length--) {
- result += +array[length] || 0;
+ result += +iteratee(array[length]) || 0;
}
return result;
}
@@ -1719,7 +1715,7 @@
: (object ? value : {});
}
}
- // Check for circular references and return corresponding clone.
+ // Check for circular references and return its corresponding clone.
stackA || (stackA = []);
stackB || (stackB = []);
@@ -1754,7 +1750,7 @@
if (isObject(prototype)) {
object.prototype = prototype;
var result = new object;
- object.prototype = null;
+ object.prototype = undefined;
}
return result || {};
};
@@ -1796,7 +1792,7 @@
var index = -1,
indexOf = getIndexOf(),
isCommon = indexOf == baseIndexOf,
- cache = (isCommon && values.length >= 200) ? createCache(values) : null,
+ cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
valuesLength = values.length;
if (cache) {
@@ -1972,13 +1968,14 @@
* @param {Array} array The array to flatten.
* @param {boolean} [isDeep] Specify a deep flatten.
* @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
+ * @param {Array} [result=[]] The initial result value.
* @returns {Array} Returns the new flattened array.
*/
- function baseFlatten(array, isDeep, isStrict) {
+ function baseFlatten(array, isDeep, isStrict, result) {
+ result || (result = []);
+
var index = -1,
- length = array.length,
- resIndex = -1,
- result = [];
+ length = array.length;
while (++index < length) {
var value = array[index];
@@ -1986,16 +1983,12 @@
(isStrict || isArray(value) || isArguments(value))) {
if (isDeep) {
// Recursively flatten arrays (susceptible to call stack limits).
- value = baseFlatten(value, isDeep, isStrict);
- }
- var valIndex = -1,
- valLength = value.length;
-
- while (++valIndex < valLength) {
- result[++resIndex] = value[valIndex];
+ baseFlatten(value, isDeep, isStrict, result);
+ } else {
+ arrayPush(result, value);
}
} else if (!isStrict) {
- result[++resIndex] = value;
+ result[result.length] = value;
}
}
return result;
@@ -2350,7 +2343,7 @@
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
- * @param {Function} [customizer] The function to customize merging properties.
+ * @param {Function} [customizer] The function to customize merged values.
* @param {Array} [stackA=[]] Tracks traversed source objects.
* @param {Array} [stackB=[]] Associates values with source counterparts.
* @returns {Object} Returns `object`.
@@ -2360,7 +2353,7 @@
return object;
}
var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
- props = isSrcArr ? null : keys(source);
+ props = isSrcArr ? undefined : keys(source);
arrayEach(props || source, function(srcValue, key) {
if (props) {
@@ -2399,7 +2392,7 @@
* @param {Object} source The source object.
* @param {string} key The key of the value to merge.
* @param {Function} mergeFunc The function to merge values.
- * @param {Function} [customizer] The function to customize merging properties.
+ * @param {Function} [customizer] The function to customize merged values.
* @param {Array} [stackA=[]] Tracks traversed source objects.
* @param {Array} [stackB=[]] Associates values with source counterparts.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
@@ -2506,7 +2499,7 @@
* @returns {number} Returns the random number.
*/
function baseRandom(min, max) {
- return min + floor(nativeRandom() * (max - min + 1));
+ return min + nativeFloor(nativeRandom() * (max - min + 1));
}
/**
@@ -2672,7 +2665,7 @@
indexOf = getIndexOf(),
length = array.length,
isCommon = indexOf == baseIndexOf,
- isLarge = isCommon && length >= 200,
+ isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
seen = isLarge ? createCache() : null,
result = [];
@@ -2771,11 +2764,8 @@
length = actions.length;
while (++index < length) {
- var args = [result],
- action = actions[index];
-
- push.apply(args, action.args);
- result = action.func.apply(action.thisArg, args);
+ var action = actions[index];
+ result = action.func.apply(action.thisArg, arrayPush([result], action.args));
}
return result;
}
@@ -2834,7 +2824,7 @@
valIsUndef = value === undefined;
while (low < high) {
- var mid = floor((low + high) / 2),
+ var mid = nativeFloor((low + high) / 2),
computed = iteratee(array[mid]),
isDef = computed !== undefined,
isReflexive = computed === computed;
@@ -2903,26 +2893,11 @@
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function bufferClone(buffer) {
- return bufferSlice.call(buffer, 0);
- }
- if (!bufferSlice) {
- // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`.
- bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) {
- var byteLength = buffer.byteLength,
- floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0,
- offset = floatLength * FLOAT64_BYTES_PER_ELEMENT,
- result = new ArrayBuffer(byteLength);
+ var result = new ArrayBuffer(buffer.byteLength),
+ view = new Uint8Array(result);
- if (floatLength) {
- var view = new Float64Array(result, 0, floatLength);
- view.set(new Float64Array(buffer, 0, floatLength));
- }
- if (byteLength != offset) {
- view = new Uint8Array(result, offset);
- view.set(new Uint8Array(buffer, offset));
- }
- return result;
- };
+ view.set(new Uint8Array(buffer));
+ return result;
}
/**
@@ -2941,7 +2916,7 @@
argsLength = nativeMax(args.length - holdersLength, 0),
leftIndex = -1,
leftLength = partials.length,
- result = Array(argsLength + leftLength);
+ result = Array(leftLength + argsLength);
while (++leftIndex < leftLength) {
result[leftIndex] = partials[leftIndex];
@@ -2988,12 +2963,7 @@
}
/**
- * Creates a function that aggregates a collection, creating an accumulator
- * object composed from the results of running each element in the collection
- * through an iteratee.
- *
- * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`,
- * and `_.partition`.
+ * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.
*
* @private
* @param {Function} setter The function to set keys and values of the accumulator object.
@@ -3023,10 +2993,7 @@
}
/**
- * Creates a function that assigns properties of source object(s) to a given
- * destination object.
- *
- * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`.
+ * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
*
* @private
* @param {Function} assigner The function to assign values.
@@ -3137,9 +3104,9 @@
* @param {Array} [values] The values to cache.
* @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.
*/
- var createCache = !(nativeCreate && Set) ? constant(null) : function(values) {
- return new SetCache(values);
- };
+ function createCache(values) {
+ return (nativeCreate && Set) ? new SetCache(values) : null;
+ }
/**
* Creates a function that produces compound words out of the words in a
@@ -3174,7 +3141,7 @@
function createCtorWrapper(Ctor) {
return function() {
// Use a `switch` statement to work with class constructors.
- // See https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist
+ // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
// for more details.
var args = arguments;
switch (args.length) {
@@ -3184,6 +3151,8 @@
case 3: return new Ctor(args[0], args[1], args[2]);
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
+ case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
+ case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}
var thisBinding = baseCreate(Ctor.prototype),
result = Ctor.apply(thisBinding, args);
@@ -3204,15 +3173,34 @@
function createCurry(flag) {
function curryFunc(func, arity, guard) {
if (guard && isIterateeCall(func, arity, guard)) {
- arity = null;
+ arity = undefined;
}
- var result = createWrapper(func, flag, null, null, null, null, null, arity);
+ var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curryFunc.placeholder;
return result;
}
return curryFunc;
}
+ /**
+ * Creates a `_.defaults` or `_.defaultsDeep` function.
+ *
+ * @private
+ * @param {Function} assigner The function to assign values.
+ * @param {Function} customizer The function to customize assigned values.
+ * @returns {Function} Returns the new defaults function.
+ */
+ function createDefaults(assigner, customizer) {
+ return restParam(function(args) {
+ var object = args[0];
+ if (object == null) {
+ return object;
+ }
+ args.push(customizer);
+ return assigner.apply(undefined, args);
+ });
+ }
+
/**
* Creates a `_.max` or `_.min` function.
*
@@ -3224,11 +3212,11 @@
function createExtremum(comparator, exValue) {
return function(collection, iteratee, thisArg) {
if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = null;
+ iteratee = undefined;
}
iteratee = getCallback(iteratee, thisArg, 3);
if (iteratee.length == 1) {
- collection = toIterable(collection);
+ collection = isArray(collection) ? collection : toIterable(collection);
var result = arrayExtremum(collection, iteratee, comparator, exValue);
if (!(collection.length && result === exValue)) {
return result;
@@ -3309,7 +3297,7 @@
throw new TypeError(FUNC_ERROR_TEXT);
}
if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {
- wrapper = new LodashWrapper([]);
+ wrapper = new LodashWrapper([], true);
}
}
index = wrapper ? -1 : length;
@@ -3317,7 +3305,7 @@
func = funcs[index];
var funcName = getFuncName(func),
- data = funcName == 'wrapper' ? getData(func) : null;
+ data = funcName == 'wrapper' ? getData(func) : undefined;
if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
@@ -3326,12 +3314,14 @@
}
}
return function() {
- var args = arguments;
- if (wrapper && args.length == 1 && isArray(args[0])) {
- return wrapper.plant(args[0]).value();
+ var args = arguments,
+ value = args[0];
+
+ if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
+ return wrapper.plant(value).value();
}
var index = 0,
- result = length ? funcs[index].apply(this, args) : args[0];
+ result = length ? funcs[index].apply(this, args) : value;
while (++index < length) {
result = funcs[index].call(this, result);
@@ -3435,7 +3425,7 @@
function createPartial(flag) {
var partialFunc = restParam(function(func, partials) {
var holders = replaceHolders(partials, partialFunc.placeholder);
- return createWrapper(func, flag, null, partials, holders);
+ return createWrapper(func, flag, undefined, partials, holders);
});
return partialFunc;
}
@@ -3481,7 +3471,7 @@
isCurry = bitmask & CURRY_FLAG,
isCurryBound = bitmask & CURRY_BOUND_FLAG,
isCurryRight = bitmask & CURRY_RIGHT_FLAG,
- Ctor = isBindKey ? null : createCtorWrapper(func);
+ Ctor = isBindKey ? undefined : createCtorWrapper(func);
function wrapper() {
// Avoid `arguments` object use disqualifying optimizations by
@@ -3505,12 +3495,12 @@
length -= argsHolders.length;
if (length < arity) {
- var newArgPos = argPos ? arrayCopy(argPos) : null,
+ var newArgPos = argPos ? arrayCopy(argPos) : undefined,
newArity = nativeMax(arity - length, 0),
- newsHolders = isCurry ? argsHolders : null,
- newHoldersRight = isCurry ? null : argsHolders,
- newPartials = isCurry ? args : null,
- newPartialsRight = isCurry ? null : args;
+ newsHolders = isCurry ? argsHolders : undefined,
+ newHoldersRight = isCurry ? undefined : argsHolders,
+ newPartials = isCurry ? args : undefined,
+ newPartialsRight = isCurry ? undefined : args;
bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
@@ -3564,7 +3554,7 @@
}
var padLength = length - strLength;
chars = chars == null ? ' ' : (chars + '');
- return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength);
+ return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);
}
/**
@@ -3590,7 +3580,7 @@
argsLength = arguments.length,
leftIndex = -1,
leftLength = partials.length,
- args = Array(argsLength + leftLength);
+ args = Array(leftLength + argsLength);
while (++leftIndex < leftLength) {
args[leftIndex] = partials[leftIndex];
@@ -3604,6 +3594,25 @@
return wrapper;
}
+ /**
+ * Creates a `_.ceil`, `_.floor`, or `_.round` function.
+ *
+ * @private
+ * @param {string} methodName The name of the `Math` method to use when rounding.
+ * @returns {Function} Returns the new round function.
+ */
+ function createRound(methodName) {
+ var func = Math[methodName];
+ return function(number, precision) {
+ precision = precision === undefined ? 0 : (+precision || 0);
+ if (precision) {
+ precision = pow(10, precision);
+ return func(number * precision) / precision;
+ }
+ return func(number);
+ };
+ }
+
/**
* Creates a `_.sortedIndex` or `_.sortedLastIndex` function.
*
@@ -3653,16 +3662,16 @@
var length = partials ? partials.length : 0;
if (!length) {
bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
- partials = holders = null;
+ partials = holders = undefined;
}
length -= (holders ? holders.length : 0);
if (bitmask & PARTIAL_RIGHT_FLAG) {
var partialsRight = partials,
holdersRight = holders;
- partials = holders = null;
+ partials = holders = undefined;
}
- var data = isBindKey ? null : getData(func),
+ var data = isBindKey ? undefined : getData(func),
newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
if (data) {
@@ -3741,7 +3750,7 @@
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
*
* @private
- * @param {Object} value The object to compare.
+ * @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {string} tag The `toStringTag` of the objects to compare.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
@@ -3941,13 +3950,13 @@
* @private
* @param {number} start The start of the view.
* @param {number} end The end of the view.
- * @param {Array} [transforms] The transformations to apply to the view.
+ * @param {Array} transforms The transformations to apply to the view.
* @returns {Object} Returns an object containing the `start` and `end`
* positions of the view.
*/
function getView(start, end, transforms) {
var index = -1,
- length = transforms ? transforms.length : 0;
+ length = transforms.length;
while (++index < length) {
var data = transforms[index],
@@ -4146,7 +4155,7 @@
/**
* Checks if `value` is a valid array-like length.
*
- * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
+ * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
*
* @private
* @param {*} value The value to check.
@@ -4238,6 +4247,18 @@
return data;
}
+ /**
+ * Used by `_.defaultsDeep` to customize its `_.merge` use.
+ *
+ * @private
+ * @param {*} objectValue The destination object property value.
+ * @param {*} sourceValue The source object property value.
+ * @returns {*} Returns the value to assign to the destination object.
+ */
+ function mergeDefaults(objectValue, sourceValue) {
+ return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);
+ }
+
/**
* A specialized version of `_.pick` which picks `object` properties specified
* by `props`.
@@ -4337,38 +4358,6 @@
};
}());
- /**
- * A fallback implementation of `_.isPlainObject` which checks if `value`
- * is an object created by the `Object` constructor or has a `[[Prototype]]`
- * of `null`.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- */
- function shimIsPlainObject(value) {
- var Ctor,
- support = lodash.support;
-
- // Exit early for non `Object` objects.
- if (!(isObjectLike(value) && objToString.call(value) == objectTag) ||
- (!hasOwnProperty.call(value, 'constructor') &&
- (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
- return false;
- }
- // IE < 9 iterates inherited properties before own properties. If the first
- // iterated property is an object's own property then there are no inherited
- // enumerable properties.
- var result;
- // In most environments an object's own properties are iterated before
- // its inherited properties. If the last iterated property is an object's
- // own property then there are no inherited enumerable properties.
- baseForIn(value, function(subValue, key) {
- result = key;
- });
- return result === undefined || hasOwnProperty.call(value, result);
- }
-
/**
* A fallback implementation of `Object.keys` which creates an array of the
* own enumerable property names of `object`.
@@ -4482,12 +4471,12 @@
if (guard ? isIterateeCall(array, size, guard) : size == null) {
size = 1;
} else {
- size = nativeMax(+size || 1, 1);
+ size = nativeMax(nativeFloor(size) || 1, 1);
}
var index = 0,
length = array ? array.length : 0,
resIndex = -1,
- result = Array(ceil(length / size));
+ result = Array(nativeCeil(length / size));
while (index < length) {
result[++resIndex] = baseSlice(array, index, (index += size));
@@ -4526,7 +4515,7 @@
/**
* Creates an array of unique `array` values not included in the other
- * provided arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
@@ -4541,7 +4530,7 @@
* // => [1, 3]
*/
var difference = restParam(function(array, values) {
- return isArrayLike(array)
+ return (isObjectLike(array) && isArrayLike(array))
? baseDifference(array, baseFlatten(values, false, true))
: [];
});
@@ -4936,7 +4925,7 @@
/**
* Gets the index at which the first occurrence of `value` is found in `array`
- * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons. If `fromIndex` is negative, it is used as the offset
* from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
* performs a faster binary search.
@@ -4970,10 +4959,9 @@
if (typeof fromIndex == 'number') {
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
} else if (fromIndex) {
- var index = binaryIndex(array, value),
- other = array[index];
-
- if (value === value ? (value === other) : (other !== other)) {
+ var index = binaryIndex(array, value);
+ if (index < length &&
+ (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
return index;
}
return -1;
@@ -5000,7 +4988,7 @@
/**
* Creates an array of unique values that are included in all of the provided
- * arrays using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
@@ -5121,7 +5109,7 @@
/**
* Removes all provided values from `array` using
- * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* **Note:** Unlike `_.without`, this method mutates `array`.
@@ -5554,7 +5542,7 @@
/**
* Creates an array of unique values, in order, from all of the provided arrays
- * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
@@ -5573,7 +5561,7 @@
/**
* Creates a duplicate-free version of an array, using
- * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons, in which only the first occurence of each element
* is kept. Providing `true` for `isSorted` performs a faster search algorithm
* for sorted arrays. If an iteratee function is provided it is invoked for
@@ -5627,7 +5615,7 @@
}
if (isSorted != null && typeof isSorted != 'boolean') {
thisArg = iteratee;
- iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted;
+ iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;
isSorted = false;
}
var callback = getCallback();
@@ -5714,7 +5702,7 @@
/**
* Creates an array excluding all provided values using
- * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
@@ -5756,7 +5744,7 @@
var array = arguments[index];
if (isArrayLike(array)) {
var result = result
- ? baseDifference(result, array).concat(baseDifference(array, result))
+ ? arrayPush(baseDifference(result, array), baseDifference(array, result))
: array;
}
}
@@ -5978,16 +5966,16 @@
* @example
*
* var array = [1, 2];
- * var wrapper = _(array).push(3);
+ * var wrapped = _(array).push(3);
*
* console.log(array);
* // => [1, 2]
*
- * wrapper = wrapper.commit();
+ * wrapped = wrapped.commit();
* console.log(array);
* // => [1, 2, 3]
*
- * wrapper.last();
+ * wrapped.last();
* // => 3
*
* console.log(array);
@@ -5997,6 +5985,33 @@
return new LodashWrapper(this.value(), this.__chain__);
}
+ /**
+ * Creates a new array joining a wrapped array with any additional arrays
+ * and/or values.
+ *
+ * @name concat
+ * @memberOf _
+ * @category Chain
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var wrapped = _(array).concat(2, [3], [[4]]);
+ *
+ * console.log(wrapped.value());
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */
+ var wrapperConcat = restParam(function(values) {
+ values = baseFlatten(values);
+ return this.thru(function(array) {
+ return arrayConcat(isArray(array) ? array : [toObject(array)], values);
+ });
+ });
+
/**
* Creates a clone of the chained sequence planting `value` as the wrapped value.
*
@@ -6007,17 +6022,17 @@
* @example
*
* var array = [1, 2];
- * var wrapper = _(array).map(function(value) {
+ * var wrapped = _(array).map(function(value) {
* return Math.pow(value, 2);
* });
*
* var other = [3, 4];
- * var otherWrapper = wrapper.plant(other);
+ * var otherWrapped = wrapped.plant(other);
*
- * otherWrapper.value();
+ * otherWrapped.value();
* // => [9, 16]
*
- * wrapper.value();
+ * wrapped.value();
* // => [1, 4]
*/
function wrapperPlant(value) {
@@ -6060,15 +6075,20 @@
*/
function wrapperReverse() {
var value = this.__wrapped__;
+
+ var interceptor = function(value) {
+ return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse();
+ };
if (value instanceof LazyWrapper) {
+ var wrapped = value;
if (this.__actions__.length) {
- value = new LazyWrapper(this);
+ wrapped = new LazyWrapper(this);
}
- return new LodashWrapper(value.reverse(), this.__chain__);
+ wrapped = wrapped.reverse();
+ wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
+ return new LodashWrapper(wrapped, this.__chain__);
}
- return this.thru(function(value) {
- return value.reverse();
- });
+ return this.thru(interceptor);
}
/**
@@ -6226,7 +6246,7 @@
function every(collection, predicate, thisArg) {
var func = isArray(collection) ? arrayEvery : baseEvery;
if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
- predicate = null;
+ predicate = undefined;
}
if (typeof predicate != 'function' || thisArg !== undefined) {
predicate = getCallback(predicate, thisArg, 3);
@@ -6500,7 +6520,7 @@
/**
* Checks if `value` is in `collection` using
- * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons. If `fromIndex` is negative, it is used as the offset
* from the end of `collection`.
*
@@ -6533,17 +6553,14 @@
collection = values(collection);
length = collection.length;
}
- if (!length) {
- return false;
- }
if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
fromIndex = 0;
} else {
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
}
return (typeof collection == 'string' || !isArray(collection) && isString(collection))
- ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1)
- : (getIndexOf(collection, target, fromIndex) > -1);
+ ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)
+ : (!!length && getIndexOf(collection, target, fromIndex) > -1);
}
/**
@@ -6625,7 +6642,7 @@
result = isArrayLike(collection) ? Array(collection.length) : [];
baseEach(collection, function(value) {
- var func = isFunc ? path : ((isProp && value != null) ? value[path] : null);
+ var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);
});
return result;
@@ -6795,7 +6812,8 @@
* `_.reduce`, `_.reduceRight`, and `_.transform`.
*
* The guarded methods are:
- * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder`
+ * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`,
+ * and `sortByOrder`
*
* @static
* @memberOf _
@@ -7025,7 +7043,7 @@
function some(collection, predicate, thisArg) {
var func = isArray(collection) ? arraySome : baseSome;
if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
- predicate = null;
+ predicate = undefined;
}
if (typeof predicate != 'function' || thisArg !== undefined) {
predicate = getCallback(predicate, thisArg, 3);
@@ -7086,7 +7104,7 @@
return [];
}
if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = null;
+ iteratee = undefined;
}
var index = -1;
iteratee = getCallback(iteratee, thisArg, 3);
@@ -7145,9 +7163,9 @@
/**
* This method is like `_.sortByAll` except that it allows specifying the
- * sort orders of the iteratees to sort by. A truthy value in `orders` will
- * sort the corresponding property name in ascending order while a falsey
- * value will sort it in descending order.
+ * sort orders of the iteratees to sort by. If `orders` is unspecified, all
+ * values are sorted in ascending order. Otherwise, a value is sorted in
+ * ascending order if its corresponding order is "asc", and descending if "desc".
*
* If a property name is provided for an iteratee the created `_.property`
* style callback returns the property value of the given element.
@@ -7161,7 +7179,7 @@
* @category Collection
* @param {Array|Object|string} collection The collection to iterate over.
* @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
- * @param {boolean[]} orders The sort orders of `iteratees`.
+ * @param {boolean[]} [orders] The sort orders of `iteratees`.
* @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
* @returns {Array} Returns the new sorted array.
* @example
@@ -7174,7 +7192,7 @@
* ];
*
* // sort by `user` in ascending order and by `age` in descending order
- * _.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values);
+ * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values);
* // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
*/
function sortByOrder(collection, iteratees, orders, guard) {
@@ -7182,7 +7200,7 @@
return [];
}
if (guard && isIterateeCall(iteratees, orders, guard)) {
- orders = null;
+ orders = undefined;
}
if (!isArray(iteratees)) {
iteratees = iteratees == null ? [] : [iteratees];
@@ -7307,10 +7325,10 @@
*/
function ary(func, n, guard) {
if (guard && isIterateeCall(func, n, guard)) {
- n = null;
+ n = undefined;
}
n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);
- return createWrapper(func, ARY_FLAG, null, null, null, null, n);
+ return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
}
/**
@@ -7345,7 +7363,7 @@
result = func.apply(this, arguments);
}
if (n <= 1) {
- func = null;
+ func = undefined;
}
return result;
};
@@ -7653,9 +7671,9 @@
var leading = true;
trailing = false;
} else if (isObject(options)) {
- leading = options.leading;
+ leading = !!options.leading;
maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
- trailing = 'trailing' in options ? options.trailing : trailing;
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function cancel() {
@@ -7665,41 +7683,35 @@
if (maxTimeoutId) {
clearTimeout(maxTimeoutId);
}
+ lastCalled = 0;
maxTimeoutId = timeoutId = trailingCall = undefined;
}
+ function complete(isCalled, id) {
+ if (id) {
+ clearTimeout(id);
+ }
+ maxTimeoutId = timeoutId = trailingCall = undefined;
+ if (isCalled) {
+ lastCalled = now();
+ result = func.apply(thisArg, args);
+ if (!timeoutId && !maxTimeoutId) {
+ args = thisArg = undefined;
+ }
+ }
+ }
+
function delayed() {
var remaining = wait - (now() - stamp);
if (remaining <= 0 || remaining > wait) {
- if (maxTimeoutId) {
- clearTimeout(maxTimeoutId);
- }
- var isCalled = trailingCall;
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (isCalled) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
+ complete(trailingCall, maxTimeoutId);
} else {
timeoutId = setTimeout(delayed, remaining);
}
}
function maxDelayed() {
- if (timeoutId) {
- clearTimeout(timeoutId);
- }
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (trailing || (maxWait !== wait)) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
+ complete(trailing, timeoutId);
}
function debounced() {
@@ -7739,7 +7751,7 @@
result = func.apply(thisArg, args);
}
if (isCalled && !timeoutId && !maxTimeoutId) {
- args = thisArg = null;
+ args = thisArg = undefined;
}
return result;
}
@@ -7844,7 +7856,7 @@
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
- * constructor with one whose instances implement the [`Map`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object)
+ * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
* method interface of `get`, `has`, and `set`.
*
* @static
@@ -7905,6 +7917,52 @@
return memoized;
}
+ /**
+ * Creates a function that runs each argument through a corresponding
+ * transform function.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to wrap.
+ * @param {...(Function|Function[])} [transforms] The functions to transform
+ * arguments, specified as individual functions or arrays of functions.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function doubled(n) {
+ * return n * 2;
+ * }
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var modded = _.modArgs(function(x, y) {
+ * return [x, y];
+ * }, square, doubled);
+ *
+ * modded(1, 2);
+ * // => [1, 4]
+ *
+ * modded(5, 10);
+ * // => [25, 20]
+ */
+ var modArgs = restParam(function(func, transforms) {
+ transforms = baseFlatten(transforms);
+ if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ var length = transforms.length;
+ return restParam(function(args) {
+ var index = nativeMin(args.length, length);
+ while (index--) {
+ args[index] = transforms[index](args[index]);
+ }
+ return func.apply(this, args);
+ });
+ });
+
/**
* Creates a function that negates the result of the predicate `func`. The
* `func` predicate is invoked with the `this` binding and arguments of the
@@ -8050,7 +8108,7 @@
* // => [3, 6, 9]
*/
var rearg = restParam(function(func, indexes) {
- return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(indexes));
+ return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
});
/**
@@ -8196,10 +8254,7 @@
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
- debounceOptions.leading = leading;
- debounceOptions.maxWait = +wait;
- debounceOptions.trailing = trailing;
- return debounce(func, wait, debounceOptions);
+ return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
}
/**
@@ -8225,7 +8280,7 @@
*/
function wrap(value, wrapper) {
wrapper = wrapper == null ? identity : wrapper;
- return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []);
+ return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);
}
/*------------------------------------------------------------------------*/
@@ -8411,7 +8466,8 @@
* // => false
*/
function isArguments(value) {
- return isObjectLike(value) && isArrayLike(value) && objToString.call(value) == argsTag;
+ return isObjectLike(value) && isArrayLike(value) &&
+ hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
}
/**
@@ -8491,14 +8547,7 @@
* // => false
*/
function isElement(value) {
- return !!value && value.nodeType === 1 && isObjectLike(value) &&
- (objToString.call(value).indexOf('Element') > -1);
- }
- // Fallback for environments without DOM support.
- if (!support.dom) {
- isElement = function(value) {
- return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
- };
+ return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
}
/**
@@ -8613,7 +8662,7 @@
/**
* Checks if `value` is a finite primitive number.
*
- * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite).
+ * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).
*
* @static
* @memberOf _
@@ -8637,9 +8686,9 @@
* _.isFinite(Infinity);
* // => false
*/
- var isFinite = nativeNumIsFinite || function(value) {
+ function isFinite(value) {
return typeof value == 'number' && nativeIsFinite(value);
- };
+ }
/**
* Checks if `value` is classified as a `Function` object.
@@ -8657,12 +8706,12 @@
* _.isFunction(/abc/);
* // => false
*/
- var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) {
+ function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in older versions of Chrome and Safari which return 'function' for regexes
// and Safari 8 equivalents which return 'object' for typed array constructors.
- return objToString.call(value) == funcTag;
- };
+ return isObject(value) && objToString.call(value) == funcTag;
+ }
/**
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
@@ -8786,7 +8835,7 @@
if (value == null) {
return false;
}
- if (objToString.call(value) == funcTag) {
+ if (isFunction(value)) {
return reIsNative.test(fnToString.call(value));
}
return isObjectLike(value) && reIsHostCtor.test(value);
@@ -8868,17 +8917,26 @@
* _.isPlainObject(Object.create(null));
* // => true
*/
- var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
- if (!(value && objToString.call(value) == objectTag)) {
+ function isPlainObject(value) {
+ var Ctor;
+
+ // Exit early for non `Object` objects.
+ if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||
+ (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
return false;
}
- var valueOf = getNative(value, 'valueOf'),
- objProto = valueOf && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
-
- return objProto
- ? (value == objProto || getPrototypeOf(value) == objProto)
- : shimIsPlainObject(value);
- };
+ // IE < 9 iterates inherited properties before own properties. If the first
+ // iterated property is an object's own property then there are no inherited
+ // enumerable properties.
+ var result;
+ // In most environments an object's own properties are iterated before
+ // its inherited properties. If the last iterated property is an object's
+ // own property then there are no inherited enumerable properties.
+ baseForIn(value, function(subValue, key) {
+ result = key;
+ });
+ return result === undefined || hasOwnProperty.call(value, result);
+ }
/**
* Checks if `value` is classified as a `RegExp` object.
@@ -8897,7 +8955,7 @@
* // => false
*/
function isRegExp(value) {
- return isObjectLike(value) && objToString.call(value) == regexpTag;
+ return isObject(value) && objToString.call(value) == regexpTag;
}
/**
@@ -9063,6 +9121,56 @@
/*------------------------------------------------------------------------*/
+ /**
+ * Recursively merges own enumerable properties of the source object(s), that
+ * don't resolve to `undefined` into the destination object. Subsequent sources
+ * overwrite property assignments of previous sources. If `customizer` is
+ * provided it is invoked to produce the merged values of the destination and
+ * source properties. If `customizer` returns `undefined` merging is handled
+ * by the method instead. The `customizer` is bound to `thisArg` and invoked
+ * with five arguments: (objectValue, sourceValue, key, object, source).
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @param {*} [thisArg] The `this` binding of `customizer`.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var users = {
+ * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
+ * };
+ *
+ * var ages = {
+ * 'data': [{ 'age': 36 }, { 'age': 40 }]
+ * };
+ *
+ * _.merge(users, ages);
+ * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
+ *
+ * // using a customizer callback
+ * var object = {
+ * 'fruits': ['apple'],
+ * 'vegetables': ['beet']
+ * };
+ *
+ * var other = {
+ * 'fruits': ['banana'],
+ * 'vegetables': ['carrot']
+ * };
+ *
+ * _.merge(object, other, function(a, b) {
+ * if (_.isArray(a)) {
+ * return a.concat(b);
+ * }
+ * });
+ * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
+ */
+ var merge = createAssigner(baseMerge);
+
/**
* Assigns own enumerable properties of source object(s) to the destination
* object. Subsequent sources overwrite property assignments of previous sources.
@@ -9071,7 +9179,7 @@
* (objectValue, sourceValue, key, object, source).
*
* **Note:** This method mutates `object` and is based on
- * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign).
+ * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
*
* @static
* @memberOf _
@@ -9138,7 +9246,7 @@
function create(prototype, properties, guard) {
var result = baseCreate(prototype);
if (guard && isIterateeCall(prototype, properties, guard)) {
- properties = null;
+ properties = undefined;
}
return properties ? baseAssign(result, properties) : result;
}
@@ -9161,14 +9269,27 @@
* _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
* // => { 'user': 'barney', 'age': 36 }
*/
- var defaults = restParam(function(args) {
- var object = args[0];
- if (object == null) {
- return object;
- }
- args.push(assignDefaults);
- return assign.apply(undefined, args);
- });
+ var defaults = createDefaults(assign, assignDefaults);
+
+ /**
+ * This method is like `_.defaults` except that it recursively assigns
+ * default properties.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
+ * // => { 'user': { 'name': 'barney', 'age': 36 } }
+ *
+ */
+ var defaultsDeep = createDefaults(merge, mergeDefaults);
/**
* This method is like `_.find` except that it returns the key of the first
@@ -9495,7 +9616,7 @@
*/
function invert(object, multiValue, guard) {
if (guard && isIterateeCall(object, multiValue, guard)) {
- multiValue = null;
+ multiValue = undefined;
}
var index = -1,
props = keys(object),
@@ -9524,7 +9645,7 @@
* Creates an array of the own enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects. See the
- * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys)
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
* for more details.
*
* @static
@@ -9548,7 +9669,7 @@
* // => ['0', '1']
*/
var keys = !nativeKeys ? shimKeys : function(object) {
- var Ctor = object == null ? null : object.constructor;
+ var Ctor = object == null ? undefined : object.constructor;
if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
(typeof object != 'function' && isArrayLike(object))) {
return shimKeys(object);
@@ -9672,56 +9793,6 @@
*/
var mapValues = createObjectMapper();
- /**
- * Recursively merges own enumerable properties of the source object(s), that
- * don't resolve to `undefined` into the destination object. Subsequent sources
- * overwrite property assignments of previous sources. If `customizer` is
- * provided it is invoked to produce the merged values of the destination and
- * source properties. If `customizer` returns `undefined` merging is handled
- * by the method instead. The `customizer` is bound to `thisArg` and invoked
- * with five arguments: (objectValue, sourceValue, key, object, source).
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The destination object.
- * @param {...Object} [sources] The source objects.
- * @param {Function} [customizer] The function to customize assigned values.
- * @param {*} [thisArg] The `this` binding of `customizer`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var users = {
- * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
- * };
- *
- * var ages = {
- * 'data': [{ 'age': 36 }, { 'age': 40 }]
- * };
- *
- * _.merge(users, ages);
- * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
- *
- * // using a customizer callback
- * var object = {
- * 'fruits': ['apple'],
- * 'vegetables': ['beet']
- * };
- *
- * var other = {
- * 'fruits': ['banana'],
- * 'vegetables': ['carrot']
- * };
- *
- * _.merge(object, other, function(a, b) {
- * if (_.isArray(a)) {
- * return a.concat(b);
- * }
- * });
- * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
- */
- var merge = createAssigner(baseMerge);
-
/**
* The opposite of `_.pick`; this method creates an object composed of the
* own and inherited enumerable properties of `object` that are not omitted.
@@ -9952,7 +10023,7 @@
if (isArr) {
accumulator = isArray(object) ? new Ctor : [];
} else {
- accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : null);
+ accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
}
} else {
accumulator = {};
@@ -10055,7 +10126,7 @@
*/
function inRange(value, start, end) {
start = +start || 0;
- if (typeof end === 'undefined') {
+ if (end === undefined) {
end = start;
start = 0;
} else {
@@ -10093,7 +10164,7 @@
*/
function random(min, max, floating) {
if (floating && isIterateeCall(min, max, floating)) {
- max = floating = null;
+ max = floating = undefined;
}
var noMin = min == null,
noMax = max == null;
@@ -10280,8 +10351,8 @@
function escapeRegExp(string) {
string = baseToString(string);
return (string && reHasRegExpChars.test(string))
- ? string.replace(reRegExpChars, '\\$&')
- : string;
+ ? string.replace(reRegExpChars, escapeRegExpChar)
+ : (string || '(?:)');
}
/**
@@ -10338,8 +10409,8 @@
return string;
}
var mid = (length - strLength) / 2,
- leftLength = floor(mid),
- rightLength = ceil(mid);
+ leftLength = nativeFloor(mid),
+ rightLength = nativeCeil(mid);
chars = createPadding('', rightLength, chars);
return chars.slice(0, leftLength) + string + chars;
@@ -10417,25 +10488,16 @@
* // => [6, 8, 10]
*/
function parseInt(string, radix, guard) {
- if (guard && isIterateeCall(string, radix, guard)) {
+ // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.
+ // Chrome fails to trim leading whitespace characters.
+ // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
+ if (guard ? isIterateeCall(string, radix, guard) : radix == null) {
radix = 0;
+ } else if (radix) {
+ radix = +radix;
}
- return nativeParseInt(string, radix);
- }
- // Fallback for environments with pre-ES5 implementations.
- if (nativeParseInt(whitespace + '08') != 8) {
- parseInt = function(string, radix, guard) {
- // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.
- // Chrome fails to trim leading whitespace characters.
- // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
- if (guard ? isIterateeCall(string, radix, guard) : radix == null) {
- radix = 0;
- } else if (radix) {
- radix = +radix;
- }
- string = trim(string);
- return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
- };
+ string = trim(string);
+ return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
}
/**
@@ -10471,7 +10533,7 @@
if (n % 2) {
result += string;
}
- n = floor(n / 2);
+ n = nativeFloor(n / 2);
string += string;
} while (n);
@@ -10656,7 +10718,7 @@
var settings = lodash.templateSettings;
if (otherOptions && isIterateeCall(string, options, otherOptions)) {
- options = otherOptions = null;
+ options = otherOptions = undefined;
}
string = baseToString(string);
options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);
@@ -10892,7 +10954,7 @@
*/
function trunc(string, options, guard) {
if (guard && isIterateeCall(string, options, guard)) {
- options = null;
+ options = undefined;
}
var length = DEFAULT_TRUNC_LENGTH,
omission = DEFAULT_TRUNC_OMISSION;
@@ -10987,7 +11049,7 @@
*/
function words(string, pattern, guard) {
if (guard && isIterateeCall(string, pattern, guard)) {
- pattern = null;
+ pattern = undefined;
}
string = baseToString(string);
return string.match(pattern || reWords) || [];
@@ -11063,7 +11125,7 @@
*/
function callback(func, thisArg, guard) {
if (guard && isIterateeCall(func, thisArg, guard)) {
- thisArg = null;
+ thisArg = undefined;
}
return isObjectLike(func)
? matches(func)
@@ -11264,8 +11326,8 @@
function mixin(object, source, options) {
if (options == null) {
var isObj = isObject(source),
- props = isObj ? keys(source) : null,
- methodNames = (props && props.length) ? baseFunctions(source, props) : null;
+ props = isObj ? keys(source) : undefined,
+ methodNames = (props && props.length) ? baseFunctions(source, props) : undefined;
if (!(methodNames ? methodNames.length : isObj)) {
methodNames = false;
@@ -11304,9 +11366,7 @@
result.__chain__ = chainAll;
return result;
}
- var args = [this.value()];
- push.apply(args, arguments);
- return func.apply(object, args);
+ return func.apply(object, arrayPush([this.value()], arguments));
};
}(func));
}
@@ -11327,7 +11387,7 @@
* var lodash = _.noConflict();
*/
function noConflict() {
- context._ = oldDash;
+ root._ = oldDash;
return this;
}
@@ -11436,7 +11496,7 @@
*/
function range(start, end, step) {
if (step && isIterateeCall(start, end, step)) {
- end = step = null;
+ end = step = undefined;
}
start = +start || 0;
step = step == null ? 1 : (+step || 0);
@@ -11450,7 +11510,7 @@
// Use `Array(length)` so engines like Chakra and V8 avoid slower modes.
// See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details.
var index = -1,
- length = nativeMax(ceil((end - start) / (step || 1)), 0),
+ length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
result = Array(length);
while (++index < length) {
@@ -11488,7 +11548,7 @@
* // => also invokes `mage.castSpell(n)` three times
*/
function times(n, iteratee, thisArg) {
- n = floor(n);
+ n = nativeFloor(n);
// Exit early to avoid a JSC JIT bug in Safari 8
// where `Array(0)` is treated as `Array(1)`.
@@ -11550,6 +11610,50 @@
return (+augend || 0) + (+addend || 0);
}
+ /**
+ * Calculates `n` rounded up to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} n The number to round up.
+ * @param {number} [precision=0] The precision to round up to.
+ * @returns {number} Returns the rounded up number.
+ * @example
+ *
+ * _.ceil(4.006);
+ * // => 5
+ *
+ * _.ceil(6.004, 2);
+ * // => 6.01
+ *
+ * _.ceil(6040, -2);
+ * // => 6100
+ */
+ var ceil = createRound('ceil');
+
+ /**
+ * Calculates `n` rounded down to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} n The number to round down.
+ * @param {number} [precision=0] The precision to round down to.
+ * @returns {number} Returns the rounded down number.
+ * @example
+ *
+ * _.floor(4.006);
+ * // => 4
+ *
+ * _.floor(0.046, 2);
+ * // => 0.04
+ *
+ * _.floor(4060, -2);
+ * // => 4000
+ */
+ var floor = createRound('floor');
+
/**
* Gets the maximum value of `collection`. If `collection` is empty or falsey
* `-Infinity` is returned. If an iteratee function is provided it is invoked
@@ -11648,6 +11752,28 @@
*/
var min = createExtremum(lt, POSITIVE_INFINITY);
+ /**
+ * Calculates `n` rounded to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} n The number to round.
+ * @param {number} [precision=0] The precision to round to.
+ * @returns {number} Returns the rounded number.
+ * @example
+ *
+ * _.round(4.006);
+ * // => 4
+ *
+ * _.round(4.006, 2);
+ * // => 4.01
+ *
+ * _.round(4060, -2);
+ * // => 4100
+ */
+ var round = createRound('round');
+
/**
* Gets the sum of the values in `collection`.
*
@@ -11682,17 +11808,11 @@
*/
function sum(collection, iteratee, thisArg) {
if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = null;
+ iteratee = undefined;
}
- var callback = getCallback(),
- noIteratee = iteratee == null;
-
- if (!(noIteratee && callback === baseCallback)) {
- noIteratee = false;
- iteratee = callback(iteratee, thisArg, 3);
- }
- return noIteratee
- ? arraySum(isArray(collection) ? collection : toIterable(collection))
+ iteratee = getCallback(iteratee, thisArg, 3);
+ return iteratee.length == 1
+ ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee)
: baseSum(collection, iteratee);
}
@@ -11739,6 +11859,7 @@
lodash.curryRight = curryRight;
lodash.debounce = debounce;
lodash.defaults = defaults;
+ lodash.defaultsDeep = defaultsDeep;
lodash.defer = defer;
lodash.delay = delay;
lodash.difference = difference;
@@ -11777,6 +11898,7 @@
lodash.method = method;
lodash.methodOf = methodOf;
lodash.mixin = mixin;
+ lodash.modArgs = modArgs;
lodash.negate = negate;
lodash.omit = omit;
lodash.once = once;
@@ -11852,6 +11974,7 @@
lodash.attempt = attempt;
lodash.camelCase = camelCase;
lodash.capitalize = capitalize;
+ lodash.ceil = ceil;
lodash.clone = clone;
lodash.cloneDeep = cloneDeep;
lodash.deburr = deburr;
@@ -11867,6 +11990,7 @@
lodash.findLastKey = findLastKey;
lodash.findWhere = findWhere;
lodash.first = first;
+ lodash.floor = floor;
lodash.get = get;
lodash.gt = gt;
lodash.gte = gte;
@@ -11915,6 +12039,7 @@
lodash.reduceRight = reduceRight;
lodash.repeat = repeat;
lodash.result = result;
+ lodash.round = round;
lodash.runInContext = runInContext;
lodash.size = size;
lodash.snakeCase = snakeCase;
@@ -11985,48 +12110,20 @@
lodash[methodName].placeholder = lodash;
});
- // Add `LazyWrapper` methods that accept an `iteratee` value.
- arrayEach(['dropWhile', 'filter', 'map', 'takeWhile'], function(methodName, type) {
- var isFilter = type != LAZY_MAP_FLAG,
- isDropWhile = type == LAZY_DROP_WHILE_FLAG;
-
- LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {
- var filtered = this.__filtered__,
- result = (filtered && isDropWhile) ? new LazyWrapper(this) : this.clone(),
- iteratees = result.__iteratees__ || (result.__iteratees__ = []);
-
- iteratees.push({
- 'done': false,
- 'count': 0,
- 'index': 0,
- 'iteratee': getCallback(iteratee, thisArg, 1),
- 'limit': -1,
- 'type': type
- });
-
- result.__filtered__ = filtered || isFilter;
- return result;
- };
- });
-
// Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
arrayEach(['drop', 'take'], function(methodName, index) {
- var whileName = methodName + 'While';
-
LazyWrapper.prototype[methodName] = function(n) {
- var filtered = this.__filtered__,
- result = (filtered && !index) ? this.dropWhile() : this.clone();
+ var filtered = this.__filtered__;
+ if (filtered && !index) {
+ return new LazyWrapper(this);
+ }
+ n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0);
- n = n == null ? 1 : nativeMax(floor(n) || 0, 0);
+ var result = this.clone();
if (filtered) {
- if (index) {
- result.__takeCount__ = nativeMin(result.__takeCount__, n);
- } else {
- last(result.__iteratees__).limit = n;
- }
+ result.__takeCount__ = nativeMin(result.__takeCount__, n);
} else {
- var views = result.__views__ || (result.__views__ = []);
- views.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
+ result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
}
return result;
};
@@ -12034,9 +12131,18 @@
LazyWrapper.prototype[methodName + 'Right'] = function(n) {
return this.reverse()[methodName](n).reverse();
};
+ });
- LazyWrapper.prototype[methodName + 'RightWhile'] = function(predicate, thisArg) {
- return this.reverse()[whileName](predicate, thisArg).reverse();
+ // Add `LazyWrapper` methods that accept an `iteratee` value.
+ arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
+ var type = index + 1,
+ isFilter = type != LAZY_MAP_FLAG;
+
+ LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {
+ var result = this.clone();
+ result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type });
+ result.__filtered__ = result.__filtered__ || isFilter;
+ return result;
};
});
@@ -12054,7 +12160,7 @@
var dropName = 'drop' + (index ? '' : 'Right');
LazyWrapper.prototype[methodName] = function() {
- return this[dropName](1);
+ return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
};
});
@@ -12083,10 +12189,13 @@
start = start == null ? 0 : (+start || 0);
var result = this;
+ if (result.__filtered__ && (start > 0 || end < 0)) {
+ return new LazyWrapper(result);
+ }
if (start < 0) {
- result = this.takeRight(-start);
+ result = result.takeRight(-start);
} else if (start) {
- result = this.drop(start);
+ result = result.drop(start);
}
if (end !== undefined) {
end = (+end || 0);
@@ -12095,21 +12204,25 @@
return result;
};
+ LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) {
+ return this.reverse().takeWhile(predicate, thisArg).reverse();
+ };
+
LazyWrapper.prototype.toArray = function() {
- return this.drop(0);
+ return this.take(POSITIVE_INFINITY);
};
// Add `LazyWrapper` methods to `lodash.prototype`.
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
- var lodashFunc = lodash[methodName];
+ var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),
+ retUnwrapped = /^(?:first|last)$/.test(methodName),
+ lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName];
+
if (!lodashFunc) {
return;
}
- var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),
- retUnwrapped = /^(?:first|last)$/.test(methodName);
-
lodash.prototype[methodName] = function() {
- var args = arguments,
+ var args = retUnwrapped ? [1] : arguments,
chainAll = this.__chain__,
value = this.__wrapped__,
isHybrid = !!this.__actions__.length,
@@ -12118,28 +12231,30 @@
useLazy = isLazy || isArray(value);
if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
- // avoid lazy use if the iteratee has a "length" value other than `1`
+ // Avoid lazy use if the iteratee has a "length" value other than `1`.
isLazy = useLazy = false;
}
- var onlyLazy = isLazy && !isHybrid;
- if (retUnwrapped && !chainAll) {
- return onlyLazy
- ? func.call(value)
- : lodashFunc.call(lodash, this.value());
- }
var interceptor = function(value) {
- var otherArgs = [value];
- push.apply(otherArgs, args);
- return lodashFunc.apply(lodash, otherArgs);
+ return (retUnwrapped && chainAll)
+ ? lodashFunc(value, 1)[0]
+ : lodashFunc.apply(undefined, arrayPush([value], args));
};
- if (useLazy) {
- var wrapper = onlyLazy ? value : new LazyWrapper(this),
- result = func.apply(wrapper, args);
- if (!retUnwrapped && (isHybrid || result.__actions__)) {
- var actions = result.__actions__ || (result.__actions__ = []);
- actions.push({ 'func': thru, 'args': [interceptor], 'thisArg': lodash });
+ var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined },
+ onlyLazy = isLazy && !isHybrid;
+
+ if (retUnwrapped && !chainAll) {
+ if (onlyLazy) {
+ value = value.clone();
+ value.__actions__.push(action);
+ return func.call(value);
}
+ return lodashFunc.call(undefined, this.value())[0];
+ }
+ if (!retUnwrapped && useLazy) {
+ value = onlyLazy ? value : new LazyWrapper(this);
+ var result = func.apply(value, args);
+ result.__actions__.push(action);
return new LodashWrapper(result, chainAll);
}
return this.thru(interceptor);
@@ -12147,7 +12262,7 @@
});
// Add `Array` and `String` methods to `lodash.prototype`.
- arrayEach(['concat', 'join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) {
+ arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) {
var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName],
chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName);
@@ -12174,7 +12289,7 @@
}
});
- realNames[createHybridWrapper(null, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': null }];
+ realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];
// Add functions to the lazy wrapper.
LazyWrapper.prototype.clone = lazyClone;
@@ -12184,6 +12299,7 @@
// Add chaining functions to the `lodash` wrapper.
lodash.prototype.chain = wrapperChain;
lodash.prototype.commit = wrapperCommit;
+ lodash.prototype.concat = wrapperConcat;
lodash.prototype.plant = wrapperPlant;
lodash.prototype.reverse = wrapperReverse;
lodash.prototype.toString = wrapperToString;
diff --git a/internal/LazyWrapper.js b/internal/LazyWrapper.js
index 4c3709734..d9c808049 100644
--- a/internal/LazyWrapper.js
+++ b/internal/LazyWrapper.js
@@ -12,13 +12,12 @@ var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
*/
function LazyWrapper(value) {
this.__wrapped__ = value;
- this.__actions__ = null;
+ this.__actions__ = [];
this.__dir__ = 1;
- this.__dropCount__ = 0;
this.__filtered__ = false;
- this.__iteratees__ = null;
+ this.__iteratees__ = [];
this.__takeCount__ = POSITIVE_INFINITY;
- this.__views__ = null;
+ this.__views__ = [];
}
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
diff --git a/internal/arrayConcat.js b/internal/arrayConcat.js
new file mode 100644
index 000000000..0d131e399
--- /dev/null
+++ b/internal/arrayConcat.js
@@ -0,0 +1,25 @@
+/**
+ * Creates a new array joining `array` with `other`.
+ *
+ * @private
+ * @param {Array} array The array to join.
+ * @param {Array} other The other array to join.
+ * @returns {Array} Returns the new concatenated array.
+ */
+function arrayConcat(array, other) {
+ var index = -1,
+ length = array.length,
+ othIndex = -1,
+ othLength = other.length,
+ result = Array(length + othLength);
+
+ while (++index < length) {
+ result[index] = array[index];
+ }
+ while (++othIndex < othLength) {
+ result[index++] = other[othIndex];
+ }
+ return result;
+}
+
+module.exports = arrayConcat;
diff --git a/internal/arrayPush.js b/internal/arrayPush.js
new file mode 100644
index 000000000..7d742b383
--- /dev/null
+++ b/internal/arrayPush.js
@@ -0,0 +1,20 @@
+/**
+ * Appends the elements of `values` to `array`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to append.
+ * @returns {Array} Returns `array`.
+ */
+function arrayPush(array, values) {
+ var index = -1,
+ length = values.length,
+ offset = array.length;
+
+ while (++index < length) {
+ array[offset + index] = values[index];
+ }
+ return array;
+}
+
+module.exports = arrayPush;
diff --git a/internal/arraySum.js b/internal/arraySum.js
index 59ccd999c..0e40c917e 100644
--- a/internal/arraySum.js
+++ b/internal/arraySum.js
@@ -1,16 +1,18 @@
/**
- * A specialized version of `_.sum` for arrays without support for iteratees.
+ * A specialized version of `_.sum` for arrays without support for callback
+ * shorthands and `this` binding..
*
* @private
* @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
* @returns {number} Returns the sum.
*/
-function arraySum(array) {
+function arraySum(array, iteratee) {
var length = array.length,
result = 0;
while (length--) {
- result += +array[length] || 0;
+ result += +iteratee(array[length]) || 0;
}
return result;
}
diff --git a/internal/baseClone.js b/internal/baseClone.js
index a747e85b2..ebd6649f9 100644
--- a/internal/baseClone.js
+++ b/internal/baseClone.js
@@ -53,7 +53,7 @@ cloneableTags[weakMapTag] = false;
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
@@ -104,7 +104,7 @@ function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
: (object ? value : {});
}
}
- // Check for circular references and return corresponding clone.
+ // Check for circular references and return its corresponding clone.
stackA || (stackA = []);
stackB || (stackB = []);
diff --git a/internal/baseCreate.js b/internal/baseCreate.js
index 8f36becd3..be5e1d9d4 100644
--- a/internal/baseCreate.js
+++ b/internal/baseCreate.js
@@ -14,7 +14,7 @@ var baseCreate = (function() {
if (isObject(prototype)) {
object.prototype = prototype;
var result = new object;
- object.prototype = null;
+ object.prototype = undefined;
}
return result || {};
};
diff --git a/internal/baseDifference.js b/internal/baseDifference.js
index 97853edab..40da1b62a 100644
--- a/internal/baseDifference.js
+++ b/internal/baseDifference.js
@@ -2,6 +2,9 @@ var baseIndexOf = require('./baseIndexOf'),
cacheIndexOf = require('./cacheIndexOf'),
createCache = require('./createCache');
+/** Used as the size to enable large array optimizations. */
+var LARGE_ARRAY_SIZE = 200;
+
/**
* The base implementation of `_.difference` which accepts a single array
* of values to exclude.
@@ -21,7 +24,7 @@ function baseDifference(array, values) {
var index = -1,
indexOf = baseIndexOf,
isCommon = true,
- cache = (isCommon && values.length >= 200) ? createCache(values) : null,
+ cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
valuesLength = values.length;
if (cache) {
diff --git a/internal/baseFlatten.js b/internal/baseFlatten.js
index aa8702bce..744323322 100644
--- a/internal/baseFlatten.js
+++ b/internal/baseFlatten.js
@@ -1,4 +1,5 @@
-var isArguments = require('../lang/isArguments'),
+var arrayPush = require('./arrayPush'),
+ isArguments = require('../lang/isArguments'),
isArray = require('../lang/isArray'),
isArrayLike = require('./isArrayLike'),
isObjectLike = require('./isObjectLike');
@@ -11,13 +12,14 @@ var isArguments = require('../lang/isArguments'),
* @param {Array} array The array to flatten.
* @param {boolean} [isDeep] Specify a deep flatten.
* @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
+ * @param {Array} [result=[]] The initial result value.
* @returns {Array} Returns the new flattened array.
*/
-function baseFlatten(array, isDeep, isStrict) {
+function baseFlatten(array, isDeep, isStrict, result) {
+ result || (result = []);
+
var index = -1,
- length = array.length,
- resIndex = -1,
- result = [];
+ length = array.length;
while (++index < length) {
var value = array[index];
@@ -25,16 +27,12 @@ function baseFlatten(array, isDeep, isStrict) {
(isStrict || isArray(value) || isArguments(value))) {
if (isDeep) {
// Recursively flatten arrays (susceptible to call stack limits).
- value = baseFlatten(value, isDeep, isStrict);
- }
- var valIndex = -1,
- valLength = value.length;
-
- while (++valIndex < valLength) {
- result[++resIndex] = value[valIndex];
+ baseFlatten(value, isDeep, isStrict, result);
+ } else {
+ arrayPush(result, value);
}
} else if (!isStrict) {
- result[++resIndex] = value;
+ result[result.length] = value;
}
}
return result;
diff --git a/internal/baseIsEqualDeep.js b/internal/baseIsEqualDeep.js
index 586ebcd1c..f1dbffe89 100644
--- a/internal/baseIsEqualDeep.js
+++ b/internal/baseIsEqualDeep.js
@@ -16,7 +16,7 @@ var objectProto = Object.prototype;
var hasOwnProperty = objectProto.hasOwnProperty;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
diff --git a/internal/baseMerge.js b/internal/baseMerge.js
index 28a871069..ab8190086 100644
--- a/internal/baseMerge.js
+++ b/internal/baseMerge.js
@@ -14,7 +14,7 @@ var arrayEach = require('./arrayEach'),
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
- * @param {Function} [customizer] The function to customize merging properties.
+ * @param {Function} [customizer] The function to customize merged values.
* @param {Array} [stackA=[]] Tracks traversed source objects.
* @param {Array} [stackB=[]] Associates values with source counterparts.
* @returns {Object} Returns `object`.
@@ -24,7 +24,7 @@ function baseMerge(object, source, customizer, stackA, stackB) {
return object;
}
var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
- props = isSrcArr ? null : keys(source);
+ props = isSrcArr ? undefined : keys(source);
arrayEach(props || source, function(srcValue, key) {
if (props) {
diff --git a/internal/baseMergeDeep.js b/internal/baseMergeDeep.js
index daf1788d6..f8aeac591 100644
--- a/internal/baseMergeDeep.js
+++ b/internal/baseMergeDeep.js
@@ -16,7 +16,7 @@ var arrayCopy = require('./arrayCopy'),
* @param {Object} source The source object.
* @param {string} key The key of the value to merge.
* @param {Function} mergeFunc The function to merge values.
- * @param {Function} [customizer] The function to customize merging properties.
+ * @param {Function} [customizer] The function to customize merged values.
* @param {Array} [stackA=[]] Tracks traversed source objects.
* @param {Array} [stackB=[]] Associates values with source counterparts.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
diff --git a/internal/baseRandom.js b/internal/baseRandom.js
index d71bb1652..fa3326cd1 100644
--- a/internal/baseRandom.js
+++ b/internal/baseRandom.js
@@ -1,8 +1,6 @@
-/** Native method references. */
-var floor = Math.floor;
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeRandom = Math.random;
+var nativeFloor = Math.floor,
+ nativeRandom = Math.random;
/**
* The base implementation of `_.random` without support for argument juggling
@@ -14,7 +12,7 @@ var nativeRandom = Math.random;
* @returns {number} Returns the random number.
*/
function baseRandom(min, max) {
- return min + floor(nativeRandom() * (max - min + 1));
+ return min + nativeFloor(nativeRandom() * (max - min + 1));
}
module.exports = baseRandom;
diff --git a/internal/baseToString.js b/internal/baseToString.js
index 4de76a7ee..b802640b5 100644
--- a/internal/baseToString.js
+++ b/internal/baseToString.js
@@ -7,9 +7,6 @@
* @returns {string} Returns the string.
*/
function baseToString(value) {
- if (typeof value == 'string') {
- return value;
- }
return value == null ? '' : (value + '');
}
diff --git a/internal/baseUniq.js b/internal/baseUniq.js
index a70c8cb38..4a7c254a7 100644
--- a/internal/baseUniq.js
+++ b/internal/baseUniq.js
@@ -2,6 +2,9 @@ var baseIndexOf = require('./baseIndexOf'),
cacheIndexOf = require('./cacheIndexOf'),
createCache = require('./createCache');
+/** Used as the size to enable large array optimizations. */
+var LARGE_ARRAY_SIZE = 200;
+
/**
* The base implementation of `_.uniq` without support for callback shorthands
* and `this` binding.
@@ -16,7 +19,7 @@ function baseUniq(array, iteratee) {
indexOf = baseIndexOf,
length = array.length,
isCommon = true,
- isLarge = isCommon && length >= 200,
+ isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
seen = isLarge ? createCache() : null,
result = [];
diff --git a/internal/baseWrapperValue.js b/internal/baseWrapperValue.js
index 49c14fb2e..629c01fd1 100644
--- a/internal/baseWrapperValue.js
+++ b/internal/baseWrapperValue.js
@@ -1,10 +1,5 @@
-var LazyWrapper = require('./LazyWrapper');
-
-/** Used for native method references. */
-var arrayProto = Array.prototype;
-
-/** Native method references. */
-var push = arrayProto.push;
+var LazyWrapper = require('./LazyWrapper'),
+ arrayPush = require('./arrayPush');
/**
* The base implementation of `wrapperValue` which returns the result of
@@ -25,11 +20,8 @@ function baseWrapperValue(value, actions) {
length = actions.length;
while (++index < length) {
- var args = [result],
- action = actions[index];
-
- push.apply(args, action.args);
- result = action.func.apply(action.thisArg, args);
+ var action = actions[index];
+ result = action.func.apply(action.thisArg, arrayPush([result], action.args));
}
return result;
}
diff --git a/internal/binaryIndexBy.js b/internal/binaryIndexBy.js
index 5bcd7a744..767cbd216 100644
--- a/internal/binaryIndexBy.js
+++ b/internal/binaryIndexBy.js
@@ -1,8 +1,6 @@
-/** Native method references. */
-var floor = Math.floor;
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeMin = Math.min;
+var nativeFloor = Math.floor,
+ nativeMin = Math.min;
/** Used as references for the maximum length and index of an array. */
var MAX_ARRAY_LENGTH = 4294967295,
@@ -31,7 +29,7 @@ function binaryIndexBy(array, value, iteratee, retHighest) {
valIsUndef = value === undefined;
while (low < high) {
- var mid = floor((low + high) / 2),
+ var mid = nativeFloor((low + high) / 2),
computed = iteratee(array[mid]),
isDef = computed !== undefined,
isReflexive = computed === computed;
diff --git a/internal/bufferClone.js b/internal/bufferClone.js
index ba10802db..f3c12b8c1 100644
--- a/internal/bufferClone.js
+++ b/internal/bufferClone.js
@@ -1,26 +1,6 @@
-var constant = require('../utility/constant'),
- getNative = require('./getNative');
-
/** Native method references. */
-var ArrayBuffer = getNative(global, 'ArrayBuffer'),
- bufferSlice = getNative(ArrayBuffer && new ArrayBuffer(0), 'slice'),
- floor = Math.floor,
- Uint8Array = getNative(global, 'Uint8Array');
-
-/** Used to clone array buffers. */
-var Float64Array = (function() {
- // Safari 5 errors when using an array buffer to initialize a typed array
- // where the array buffer's `byteLength` is not a multiple of the typed
- // array's `BYTES_PER_ELEMENT`.
- try {
- var func = getNative(global, 'Float64Array'),
- result = new func(new ArrayBuffer(10), 0, 1) && func;
- } catch(e) {}
- return result || null;
-}());
-
-/** Used as the size, in bytes, of each `Float64Array` element. */
-var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
+var ArrayBuffer = global.ArrayBuffer,
+ Uint8Array = global.Uint8Array;
/**
* Creates a clone of the given array buffer.
@@ -30,26 +10,11 @@ var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT :
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function bufferClone(buffer) {
- return bufferSlice.call(buffer, 0);
-}
-if (!bufferSlice) {
- // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`.
- bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) {
- var byteLength = buffer.byteLength,
- floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0,
- offset = floatLength * FLOAT64_BYTES_PER_ELEMENT,
- result = new ArrayBuffer(byteLength);
+ var result = new ArrayBuffer(buffer.byteLength),
+ view = new Uint8Array(result);
- if (floatLength) {
- var view = new Float64Array(result, 0, floatLength);
- view.set(new Float64Array(buffer, 0, floatLength));
- }
- if (byteLength != offset) {
- view = new Uint8Array(result, offset);
- view.set(new Uint8Array(buffer, offset));
- }
- return result;
- };
+ view.set(new Uint8Array(buffer));
+ return result;
}
module.exports = bufferClone;
diff --git a/internal/compareAscending.js b/internal/compareAscending.js
index 07f0019af..f17b11750 100644
--- a/internal/compareAscending.js
+++ b/internal/compareAscending.js
@@ -5,8 +5,8 @@ var baseCompareAscending = require('./baseCompareAscending');
* sort them in ascending order.
*
* @private
- * @param {Object} object The object to compare to `other`.
- * @param {Object} other The object to compare to `object`.
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
* @returns {number} Returns the sort order indicator for `object`.
*/
function compareAscending(object, other) {
diff --git a/internal/compareMultiple.js b/internal/compareMultiple.js
index cc6c86c03..b2139f778 100644
--- a/internal/compareMultiple.js
+++ b/internal/compareMultiple.js
@@ -1,16 +1,16 @@
var baseCompareAscending = require('./baseCompareAscending');
/**
- * Used by `_.sortByOrder` to compare multiple properties of each element
- * in a collection and stable sort them in the following order:
+ * Used by `_.sortByOrder` to compare multiple properties of a value to another
+ * and stable sort them.
*
- * If `orders` is unspecified, sort in ascending order for all properties.
- * Otherwise, for each property, sort in ascending order if its corresponding value in
- * orders is true, and descending order if false.
+ * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise,
+ * a value is sorted in ascending order if its corresponding order is "asc", and
+ * descending if "desc".
*
* @private
- * @param {Object} object The object to compare to `other`.
- * @param {Object} other The object to compare to `object`.
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
* @param {boolean[]} orders The order to sort by for each property.
* @returns {number} Returns the sort order indicator for `object`.
*/
@@ -27,7 +27,8 @@ function compareMultiple(object, other, orders) {
if (index >= ordersLength) {
return result;
}
- return result * (orders[index] ? 1 : -1);
+ var order = orders[index];
+ return result * ((order === 'asc' || order === true) ? 1 : -1);
}
}
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
diff --git a/internal/composeArgs.js b/internal/composeArgs.js
index f5a98d5ee..cd5a2fedd 100644
--- a/internal/composeArgs.js
+++ b/internal/composeArgs.js
@@ -17,7 +17,7 @@ function composeArgs(args, partials, holders) {
argsLength = nativeMax(args.length - holdersLength, 0),
leftIndex = -1,
leftLength = partials.length,
- result = Array(argsLength + leftLength);
+ result = Array(leftLength + argsLength);
while (++leftIndex < leftLength) {
result[leftIndex] = partials[leftIndex];
diff --git a/internal/createAggregator.js b/internal/createAggregator.js
index 5137861a0..c3d3cec6e 100644
--- a/internal/createAggregator.js
+++ b/internal/createAggregator.js
@@ -3,12 +3,7 @@ var baseCallback = require('./baseCallback'),
isArray = require('../lang/isArray');
/**
- * Creates a function that aggregates a collection, creating an accumulator
- * object composed from the results of running each element in the collection
- * through an iteratee.
- *
- * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`,
- * and `_.partition`.
+ * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.
*
* @private
* @param {Function} setter The function to set keys and values of the accumulator object.
diff --git a/internal/createAssigner.js b/internal/createAssigner.js
index e06c1b1b7..ea5a5a495 100644
--- a/internal/createAssigner.js
+++ b/internal/createAssigner.js
@@ -3,10 +3,7 @@ var bindCallback = require('./bindCallback'),
restParam = require('../function/restParam');
/**
- * Creates a function that assigns properties of source object(s) to a given
- * destination object.
- *
- * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`.
+ * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
*
* @private
* @param {Function} assigner The function to assign values.
diff --git a/internal/createCache.js b/internal/createCache.js
index 012cab1b6..025e5662a 100644
--- a/internal/createCache.js
+++ b/internal/createCache.js
@@ -1,5 +1,4 @@
var SetCache = require('./SetCache'),
- constant = require('../utility/constant'),
getNative = require('./getNative');
/** Native method references. */
@@ -15,8 +14,8 @@ var nativeCreate = getNative(Object, 'create');
* @param {Array} [values] The values to cache.
* @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.
*/
-var createCache = !(nativeCreate && Set) ? constant(null) : function(values) {
- return new SetCache(values);
-};
+function createCache(values) {
+ return (nativeCreate && Set) ? new SetCache(values) : null;
+}
module.exports = createCache;
diff --git a/internal/createCtorWrapper.js b/internal/createCtorWrapper.js
index f1a12d14e..ffbee8035 100644
--- a/internal/createCtorWrapper.js
+++ b/internal/createCtorWrapper.js
@@ -12,7 +12,7 @@ var baseCreate = require('./baseCreate'),
function createCtorWrapper(Ctor) {
return function() {
// Use a `switch` statement to work with class constructors.
- // See https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist
+ // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
// for more details.
var args = arguments;
switch (args.length) {
@@ -22,6 +22,8 @@ function createCtorWrapper(Ctor) {
case 3: return new Ctor(args[0], args[1], args[2]);
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
+ case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
+ case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}
var thisBinding = baseCreate(Ctor.prototype),
result = Ctor.apply(thisBinding, args);
diff --git a/internal/createCurry.js b/internal/createCurry.js
index e140e711f..e5ced0e28 100644
--- a/internal/createCurry.js
+++ b/internal/createCurry.js
@@ -11,9 +11,9 @@ var createWrapper = require('./createWrapper'),
function createCurry(flag) {
function curryFunc(func, arity, guard) {
if (guard && isIterateeCall(func, arity, guard)) {
- arity = null;
+ arity = undefined;
}
- var result = createWrapper(func, flag, null, null, null, null, null, arity);
+ var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curryFunc.placeholder;
return result;
}
diff --git a/internal/createDefaults.js b/internal/createDefaults.js
new file mode 100644
index 000000000..5663bcb4a
--- /dev/null
+++ b/internal/createDefaults.js
@@ -0,0 +1,22 @@
+var restParam = require('../function/restParam');
+
+/**
+ * Creates a `_.defaults` or `_.defaultsDeep` function.
+ *
+ * @private
+ * @param {Function} assigner The function to assign values.
+ * @param {Function} customizer The function to customize assigned values.
+ * @returns {Function} Returns the new defaults function.
+ */
+function createDefaults(assigner, customizer) {
+ return restParam(function(args) {
+ var object = args[0];
+ if (object == null) {
+ return object;
+ }
+ args.push(customizer);
+ return assigner.apply(undefined, args);
+ });
+}
+
+module.exports = createDefaults;
diff --git a/internal/createExtremum.js b/internal/createExtremum.js
index 60f0b7919..5c4003e52 100644
--- a/internal/createExtremum.js
+++ b/internal/createExtremum.js
@@ -1,6 +1,7 @@
var arrayExtremum = require('./arrayExtremum'),
baseCallback = require('./baseCallback'),
baseExtremum = require('./baseExtremum'),
+ isArray = require('../lang/isArray'),
isIterateeCall = require('./isIterateeCall'),
toIterable = require('./toIterable');
@@ -15,11 +16,11 @@ var arrayExtremum = require('./arrayExtremum'),
function createExtremum(comparator, exValue) {
return function(collection, iteratee, thisArg) {
if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = null;
+ iteratee = undefined;
}
iteratee = baseCallback(iteratee, thisArg, 3);
if (iteratee.length == 1) {
- collection = toIterable(collection);
+ collection = isArray(collection) ? collection : toIterable(collection);
var result = arrayExtremum(collection, iteratee, comparator, exValue);
if (!(collection.length && result === exValue)) {
return result;
diff --git a/internal/createFlow.js b/internal/createFlow.js
index f1821835f..52ab38822 100644
--- a/internal/createFlow.js
+++ b/internal/createFlow.js
@@ -10,6 +10,9 @@ var CURRY_FLAG = 8,
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';
@@ -34,7 +37,7 @@ function createFlow(fromRight) {
throw new TypeError(FUNC_ERROR_TEXT);
}
if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {
- wrapper = new LodashWrapper([]);
+ wrapper = new LodashWrapper([], true);
}
}
index = wrapper ? -1 : length;
@@ -42,7 +45,7 @@ function createFlow(fromRight) {
func = funcs[index];
var funcName = getFuncName(func),
- data = funcName == 'wrapper' ? getData(func) : null;
+ data = funcName == 'wrapper' ? getData(func) : undefined;
if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
@@ -51,12 +54,14 @@ function createFlow(fromRight) {
}
}
return function() {
- var args = arguments;
- if (wrapper && args.length == 1 && isArray(args[0])) {
- return wrapper.plant(args[0]).value();
+ var args = arguments,
+ value = args[0];
+
+ if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
+ return wrapper.plant(value).value();
}
var index = 0,
- result = length ? funcs[index].apply(this, args) : args[0];
+ result = length ? funcs[index].apply(this, args) : value;
while (++index < length) {
result = funcs[index].call(this, result);
diff --git a/internal/createHybridWrapper.js b/internal/createHybridWrapper.js
index d7de9ade7..5382fa021 100644
--- a/internal/createHybridWrapper.js
+++ b/internal/createHybridWrapper.js
@@ -44,7 +44,7 @@ function createHybridWrapper(func, bitmask, thisArg, partials, holders, partials
isCurry = bitmask & CURRY_FLAG,
isCurryBound = bitmask & CURRY_BOUND_FLAG,
isCurryRight = bitmask & CURRY_RIGHT_FLAG,
- Ctor = isBindKey ? null : createCtorWrapper(func);
+ Ctor = isBindKey ? undefined : createCtorWrapper(func);
function wrapper() {
// Avoid `arguments` object use disqualifying optimizations by
@@ -68,12 +68,12 @@ function createHybridWrapper(func, bitmask, thisArg, partials, holders, partials
length -= argsHolders.length;
if (length < arity) {
- var newArgPos = argPos ? arrayCopy(argPos) : null,
+ var newArgPos = argPos ? arrayCopy(argPos) : undefined,
newArity = nativeMax(arity - length, 0),
- newsHolders = isCurry ? argsHolders : null,
- newHoldersRight = isCurry ? null : argsHolders,
- newPartials = isCurry ? args : null,
- newPartialsRight = isCurry ? null : args;
+ newsHolders = isCurry ? argsHolders : undefined,
+ newHoldersRight = isCurry ? undefined : argsHolders,
+ newPartials = isCurry ? args : undefined,
+ newPartialsRight = isCurry ? undefined : args;
bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
diff --git a/internal/createPadding.js b/internal/createPadding.js
index 57979926f..810dc24ca 100644
--- a/internal/createPadding.js
+++ b/internal/createPadding.js
@@ -1,10 +1,8 @@
var repeat = require('../string/repeat');
-/** Native method references. */
-var ceil = Math.ceil;
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeIsFinite = global.isFinite;
+var nativeCeil = Math.ceil,
+ nativeIsFinite = global.isFinite;
/**
* Creates the padding required for `string` based on the given `length`.
@@ -25,7 +23,7 @@ function createPadding(string, length, chars) {
}
var padLength = length - strLength;
chars = chars == null ? ' ' : (chars + '');
- return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength);
+ return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);
}
module.exports = createPadding;
diff --git a/internal/createPartial.js b/internal/createPartial.js
index c0e42b615..753327539 100644
--- a/internal/createPartial.js
+++ b/internal/createPartial.js
@@ -12,7 +12,7 @@ var createWrapper = require('./createWrapper'),
function createPartial(flag) {
var partialFunc = restParam(function(func, partials) {
var holders = replaceHolders(partials, partialFunc.placeholder);
- return createWrapper(func, flag, null, partials, holders);
+ return createWrapper(func, flag, undefined, partials, holders);
});
return partialFunc;
}
diff --git a/internal/createPartialWrapper.js b/internal/createPartialWrapper.js
index 10af97cbd..b19f9f0ec 100644
--- a/internal/createPartialWrapper.js
+++ b/internal/createPartialWrapper.js
@@ -26,7 +26,7 @@ function createPartialWrapper(func, bitmask, thisArg, partials) {
argsLength = arguments.length,
leftIndex = -1,
leftLength = partials.length,
- args = Array(argsLength + leftLength);
+ args = Array(leftLength + argsLength);
while (++leftIndex < leftLength) {
args[leftIndex] = partials[leftIndex];
diff --git a/internal/createRound.js b/internal/createRound.js
new file mode 100644
index 000000000..21240efb6
--- /dev/null
+++ b/internal/createRound.js
@@ -0,0 +1,23 @@
+/** Native method references. */
+var pow = Math.pow;
+
+/**
+ * Creates a `_.ceil`, `_.floor`, or `_.round` function.
+ *
+ * @private
+ * @param {string} methodName The name of the `Math` method to use when rounding.
+ * @returns {Function} Returns the new round function.
+ */
+function createRound(methodName) {
+ var func = Math[methodName];
+ return function(number, precision) {
+ precision = precision === undefined ? 0 : (+precision || 0);
+ if (precision) {
+ precision = pow(10, precision);
+ return func(number * precision) / precision;
+ }
+ return func(number);
+ };
+}
+
+module.exports = createRound;
diff --git a/internal/createWrapper.js b/internal/createWrapper.js
index 6b5379917..ea7a9b190 100644
--- a/internal/createWrapper.js
+++ b/internal/createWrapper.js
@@ -51,16 +51,16 @@ function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, a
var length = partials ? partials.length : 0;
if (!length) {
bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
- partials = holders = null;
+ partials = holders = undefined;
}
length -= (holders ? holders.length : 0);
if (bitmask & PARTIAL_RIGHT_FLAG) {
var partialsRight = partials,
holdersRight = holders;
- partials = holders = null;
+ partials = holders = undefined;
}
- var data = isBindKey ? null : getData(func),
+ var data = isBindKey ? undefined : getData(func),
newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
if (data) {
diff --git a/internal/equalByTag.js b/internal/equalByTag.js
index addc3df0e..d25c8e1ea 100644
--- a/internal/equalByTag.js
+++ b/internal/equalByTag.js
@@ -14,7 +14,7 @@ var boolTag = '[object Boolean]',
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
*
* @private
- * @param {Object} value The object to compare.
+ * @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {string} tag The `toStringTag` of the objects to compare.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
diff --git a/internal/escapeRegExpChar.js b/internal/escapeRegExpChar.js
new file mode 100644
index 000000000..8427de0ec
--- /dev/null
+++ b/internal/escapeRegExpChar.js
@@ -0,0 +1,38 @@
+/** Used to escape characters for inclusion in compiled regexes. */
+var regexpEscapes = {
+ '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34',
+ '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39',
+ 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46',
+ 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66',
+ 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78'
+};
+
+/** Used to escape characters for inclusion in compiled string literals. */
+var stringEscapes = {
+ '\\': '\\',
+ "'": "'",
+ '\n': 'n',
+ '\r': 'r',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+};
+
+/**
+ * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes.
+ *
+ * @private
+ * @param {string} chr The matched character to escape.
+ * @param {string} leadingChar The capture group for a leading character.
+ * @param {string} whitespaceChar The capture group for a whitespace character.
+ * @returns {string} Returns the escaped character.
+ */
+function escapeRegExpChar(chr, leadingChar, whitespaceChar) {
+ if (leadingChar) {
+ chr = regexpEscapes[chr];
+ } else if (whitespaceChar) {
+ chr = stringEscapes[chr];
+ }
+ return '\\' + chr;
+}
+
+module.exports = escapeRegExpChar;
diff --git a/internal/escapeStringChar.js b/internal/escapeStringChar.js
index c8fba0dca..44eca96ca 100644
--- a/internal/escapeStringChar.js
+++ b/internal/escapeStringChar.js
@@ -9,8 +9,7 @@ var stringEscapes = {
};
/**
- * Used by `_.template` to escape characters for inclusion in compiled
- * string literals.
+ * Used by `_.template` to escape characters for inclusion in compiled string literals.
*
* @private
* @param {string} chr The matched character to escape.
diff --git a/internal/getView.js b/internal/getView.js
index 8cc291b97..f49ec6d06 100644
--- a/internal/getView.js
+++ b/internal/getView.js
@@ -8,13 +8,13 @@ var nativeMax = Math.max,
* @private
* @param {number} start The start of the view.
* @param {number} end The end of the view.
- * @param {Array} [transforms] The transformations to apply to the view.
+ * @param {Array} transforms The transformations to apply to the view.
* @returns {Object} Returns an object containing the `start` and `end`
* positions of the view.
*/
function getView(start, end, transforms) {
var index = -1,
- length = transforms ? transforms.length : 0;
+ length = transforms.length;
while (++index < length) {
var data = transforms[index],
diff --git a/internal/isIndex.js b/internal/isIndex.js
index 142bde7fb..469164bfd 100644
--- a/internal/isIndex.js
+++ b/internal/isIndex.js
@@ -2,7 +2,7 @@
var reIsUint = /^\d+$/;
/**
- * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
* of an array-like value.
*/
var MAX_SAFE_INTEGER = 9007199254740991;
diff --git a/internal/isLength.js b/internal/isLength.js
index 39c85022f..209298798 100644
--- a/internal/isLength.js
+++ b/internal/isLength.js
@@ -1,5 +1,5 @@
/**
- * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
* of an array-like value.
*/
var MAX_SAFE_INTEGER = 9007199254740991;
@@ -7,7 +7,7 @@ var MAX_SAFE_INTEGER = 9007199254740991;
/**
* Checks if `value` is a valid array-like length.
*
- * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
+ * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
*
* @private
* @param {*} value The value to check.
diff --git a/internal/lazyClone.js b/internal/lazyClone.js
index 20cc8edd2..04c222b20 100644
--- a/internal/lazyClone.js
+++ b/internal/lazyClone.js
@@ -10,17 +10,13 @@ var LazyWrapper = require('./LazyWrapper'),
* @returns {Object} Returns the cloned `LazyWrapper` object.
*/
function lazyClone() {
- var actions = this.__actions__,
- iteratees = this.__iteratees__,
- views = this.__views__,
- result = new LazyWrapper(this.__wrapped__);
-
- result.__actions__ = actions ? arrayCopy(actions) : null;
+ var result = new LazyWrapper(this.__wrapped__);
+ result.__actions__ = arrayCopy(this.__actions__);
result.__dir__ = this.__dir__;
result.__filtered__ = this.__filtered__;
- result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null;
+ result.__iteratees__ = arrayCopy(this.__iteratees__);
result.__takeCount__ = this.__takeCount__;
- result.__views__ = views ? arrayCopy(views) : null;
+ result.__views__ = arrayCopy(this.__views__);
return result;
}
diff --git a/internal/lazyValue.js b/internal/lazyValue.js
index f0e342519..44aa377ee 100644
--- a/internal/lazyValue.js
+++ b/internal/lazyValue.js
@@ -2,9 +2,11 @@ var baseWrapperValue = require('./baseWrapperValue'),
getView = require('./getView'),
isArray = require('../lang/isArray');
+/** Used as the size to enable large array optimizations. */
+var LARGE_ARRAY_SIZE = 200;
+
/** Used to indicate the type of lazy iteratees. */
-var LAZY_DROP_WHILE_FLAG = 0,
- LAZY_FILTER_FLAG = 1,
+var LAZY_FILTER_FLAG = 1,
LAZY_MAP_FLAG = 2;
/* Native method references for those with the same name as other `lodash` methods. */
@@ -19,22 +21,25 @@ var nativeMin = Math.min;
* @returns {*} Returns the unwrapped value.
*/
function lazyValue() {
- var array = this.__wrapped__.value();
- if (!isArray(array)) {
- return baseWrapperValue(array, this.__actions__);
- }
- var dir = this.__dir__,
+ var array = this.__wrapped__.value(),
+ dir = this.__dir__,
+ isArr = isArray(array),
isRight = dir < 0,
- view = getView(0, array.length, this.__views__),
+ arrLength = isArr ? array.length : 0,
+ view = getView(0, arrLength, this.__views__),
start = view.start,
end = view.end,
length = end - start,
index = isRight ? end : (start - 1),
- takeCount = nativeMin(length, this.__takeCount__),
iteratees = this.__iteratees__,
- iterLength = iteratees ? iteratees.length : 0,
+ iterLength = iteratees.length,
resIndex = 0,
- result = [];
+ takeCount = nativeMin(length, this.__takeCount__);
+
+ if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
+ return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__);
+ }
+ var result = [];
outer:
while (length-- && resIndex < takeCount) {
@@ -46,30 +51,16 @@ function lazyValue() {
while (++iterIndex < iterLength) {
var data = iteratees[iterIndex],
iteratee = data.iteratee,
- type = data.type;
+ type = data.type,
+ computed = iteratee(value);
- if (type == LAZY_DROP_WHILE_FLAG) {
- if (data.done && (isRight ? (index > data.index) : (index < data.index))) {
- data.count = 0;
- data.done = false;
- }
- data.index = index;
- if (!data.done) {
- var limit = data.limit;
- if (!(data.done = limit > -1 ? (data.count++ >= limit) : !iteratee(value))) {
- continue outer;
- }
- }
- } else {
- var computed = iteratee(value);
- if (type == LAZY_MAP_FLAG) {
- value = computed;
- } else if (!computed) {
- if (type == LAZY_FILTER_FLAG) {
- continue outer;
- } else {
- break outer;
- }
+ if (type == LAZY_MAP_FLAG) {
+ value = computed;
+ } else if (!computed) {
+ if (type == LAZY_FILTER_FLAG) {
+ continue outer;
+ } else {
+ break outer;
}
}
}
diff --git a/internal/mergeDefaults.js b/internal/mergeDefaults.js
new file mode 100644
index 000000000..dcd967e9f
--- /dev/null
+++ b/internal/mergeDefaults.js
@@ -0,0 +1,15 @@
+var merge = require('../object/merge');
+
+/**
+ * Used by `_.defaultsDeep` to customize its `_.merge` use.
+ *
+ * @private
+ * @param {*} objectValue The destination object property value.
+ * @param {*} sourceValue The source object property value.
+ * @returns {*} Returns the value to assign to the destination object.
+ */
+function mergeDefaults(objectValue, sourceValue) {
+ return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);
+}
+
+module.exports = mergeDefaults;
diff --git a/internal/shimIsPlainObject.js b/internal/shimIsPlainObject.js
deleted file mode 100644
index 9821286d6..000000000
--- a/internal/shimIsPlainObject.js
+++ /dev/null
@@ -1,50 +0,0 @@
-var baseForIn = require('./baseForIn'),
- isObjectLike = require('./isObjectLike');
-
-/** `Object#toString` result references. */
-var objectTag = '[object Object]';
-
-/** Used for native method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
- * of values.
- */
-var objToString = objectProto.toString;
-
-/**
- * A fallback implementation of `_.isPlainObject` which checks if `value`
- * is an object created by the `Object` constructor or has a `[[Prototype]]`
- * of `null`.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- */
-function shimIsPlainObject(value) {
- var Ctor;
-
- // Exit early for non `Object` objects.
- if (!(isObjectLike(value) && objToString.call(value) == objectTag) ||
- (!hasOwnProperty.call(value, 'constructor') &&
- (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
- return false;
- }
- // IE < 9 iterates inherited properties before own properties. If the first
- // iterated property is an object's own property then there are no inherited
- // enumerable properties.
- var result;
- // In most environments an object's own properties are iterated before
- // its inherited properties. If the last iterated property is an object's
- // own property then there are no inherited enumerable properties.
- baseForIn(value, function(subValue, key) {
- result = key;
- });
- return result === undefined || hasOwnProperty.call(value, result);
-}
-
-module.exports = shimIsPlainObject;
diff --git a/lang/isArguments.js b/lang/isArguments.js
index db9071319..ce9763d23 100644
--- a/lang/isArguments.js
+++ b/lang/isArguments.js
@@ -1,17 +1,14 @@
var isArrayLike = require('../internal/isArrayLike'),
isObjectLike = require('../internal/isObjectLike');
-/** `Object#toString` result references. */
-var argsTag = '[object Arguments]';
-
/** Used for native method references. */
var objectProto = Object.prototype;
-/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
- * of values.
- */
-var objToString = objectProto.toString;
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Native method references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable;
/**
* Checks if `value` is classified as an `arguments` object.
@@ -30,7 +27,8 @@ var objToString = objectProto.toString;
* // => false
*/
function isArguments(value) {
- return isObjectLike(value) && isArrayLike(value) && objToString.call(value) == argsTag;
+ return isObjectLike(value) && isArrayLike(value) &&
+ hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
}
module.exports = isArguments;
diff --git a/lang/isArray.js b/lang/isArray.js
index 6826854c7..9ab023acb 100644
--- a/lang/isArray.js
+++ b/lang/isArray.js
@@ -9,7 +9,7 @@ var arrayTag = '[object Array]';
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
diff --git a/lang/isBoolean.js b/lang/isBoolean.js
index 8999da34c..460e6c5bd 100644
--- a/lang/isBoolean.js
+++ b/lang/isBoolean.js
@@ -7,7 +7,7 @@ var boolTag = '[object Boolean]';
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
diff --git a/lang/isDate.js b/lang/isDate.js
index 5d80e3dc4..29850d947 100644
--- a/lang/isDate.js
+++ b/lang/isDate.js
@@ -7,7 +7,7 @@ var dateTag = '[object Date]';
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
diff --git a/lang/isElement.js b/lang/isElement.js
index 4a1e31225..2e9c97048 100644
--- a/lang/isElement.js
+++ b/lang/isElement.js
@@ -1,15 +1,5 @@
var isObjectLike = require('../internal/isObjectLike'),
- isPlainObject = require('./isPlainObject'),
- support = require('../support');
-
-/** Used for native method references. */
-var objectProto = Object.prototype;
-
-/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
- * of values.
- */
-var objToString = objectProto.toString;
+ isPlainObject = require('./isPlainObject');
/**
* Checks if `value` is a DOM element.
@@ -28,14 +18,7 @@ var objToString = objectProto.toString;
* // => false
*/
function isElement(value) {
- return !!value && value.nodeType === 1 && isObjectLike(value) &&
- (objToString.call(value).indexOf('Element') > -1);
-}
-// Fallback for environments without DOM support.
-if (!support.dom) {
- isElement = function(value) {
- return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
- };
+ return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
}
module.exports = isElement;
diff --git a/lang/isError.js b/lang/isError.js
index 4ec836db4..a7bb0d094 100644
--- a/lang/isError.js
+++ b/lang/isError.js
@@ -7,7 +7,7 @@ var errorTag = '[object Error]';
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
diff --git a/lang/isFinite.js b/lang/isFinite.js
index 3a1c9059a..e01a307fc 100644
--- a/lang/isFinite.js
+++ b/lang/isFinite.js
@@ -1,13 +1,10 @@
-var getNative = require('../internal/getNative');
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeIsFinite = global.isFinite,
- nativeNumIsFinite = getNative(Number, 'isFinite');
+var nativeIsFinite = global.isFinite;
/**
* Checks if `value` is a finite primitive number.
*
- * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite).
+ * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).
*
* @static
* @memberOf _
@@ -31,8 +28,8 @@ var nativeIsFinite = global.isFinite,
* _.isFinite(Infinity);
* // => false
*/
-var isFinite = nativeNumIsFinite || function(value) {
+function isFinite(value) {
return typeof value == 'number' && nativeIsFinite(value);
-};
+}
module.exports = isFinite;
diff --git a/lang/isFunction.js b/lang/isFunction.js
index 114a4dff5..37e1a2d74 100644
--- a/lang/isFunction.js
+++ b/lang/isFunction.js
@@ -1,5 +1,4 @@
-var baseIsFunction = require('../internal/baseIsFunction'),
- getNative = require('../internal/getNative');
+var isObject = require('./isObject');
/** `Object#toString` result references. */
var funcTag = '[object Function]';
@@ -8,14 +7,11 @@ var funcTag = '[object Function]';
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
-/** Native method references. */
-var Uint8Array = getNative(global, 'Uint8Array');
-
/**
* Checks if `value` is classified as a `Function` object.
*
@@ -32,11 +28,11 @@ var Uint8Array = getNative(global, 'Uint8Array');
* _.isFunction(/abc/);
* // => false
*/
-var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) {
+function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in older versions of Chrome and Safari which return 'function' for regexes
// and Safari 8 equivalents which return 'object' for typed array constructors.
- return objToString.call(value) == funcTag;
-};
+ return isObject(value) && objToString.call(value) == funcTag;
+}
module.exports = isFunction;
diff --git a/lang/isNative.js b/lang/isNative.js
index cc2de0d31..3ad714452 100644
--- a/lang/isNative.js
+++ b/lang/isNative.js
@@ -1,9 +1,6 @@
-var escapeRegExp = require('../string/escapeRegExp'),
+var isFunction = require('./isFunction'),
isObjectLike = require('../internal/isObjectLike');
-/** `Object#toString` result references. */
-var funcTag = '[object Function]';
-
/** Used to detect host constructors (Safari > 5). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
@@ -16,15 +13,9 @@ var fnToString = Function.prototype.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
-/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
- * of values.
- */
-var objToString = objectProto.toString;
-
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
- escapeRegExp(fnToString.call(hasOwnProperty))
+ fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
@@ -48,7 +39,7 @@ function isNative(value) {
if (value == null) {
return false;
}
- if (objToString.call(value) == funcTag) {
+ if (isFunction(value)) {
return reIsNative.test(fnToString.call(value));
}
return isObjectLike(value) && reIsHostCtor.test(value);
diff --git a/lang/isNumber.js b/lang/isNumber.js
index 9404dc851..6764d6f99 100644
--- a/lang/isNumber.js
+++ b/lang/isNumber.js
@@ -7,7 +7,7 @@ var numberTag = '[object Number]';
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
diff --git a/lang/isPlainObject.js b/lang/isPlainObject.js
index 67e0a8abd..5b34c8389 100644
--- a/lang/isPlainObject.js
+++ b/lang/isPlainObject.js
@@ -1,5 +1,6 @@
-var getNative = require('../internal/getNative'),
- shimIsPlainObject = require('../internal/shimIsPlainObject');
+var baseForIn = require('../internal/baseForIn'),
+ isArguments = require('./isArguments'),
+ isObjectLike = require('../internal/isObjectLike');
/** `Object#toString` result references. */
var objectTag = '[object Object]';
@@ -7,15 +8,15 @@ var objectTag = '[object Object]';
/** Used for native method references. */
var objectProto = Object.prototype;
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
-/** Native method references. */
-var getPrototypeOf = getNative(Object, 'getPrototypeOf');
-
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
@@ -46,16 +47,25 @@ var getPrototypeOf = getNative(Object, 'getPrototypeOf');
* _.isPlainObject(Object.create(null));
* // => true
*/
-var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
- if (!(value && objToString.call(value) == objectTag)) {
+function isPlainObject(value) {
+ var Ctor;
+
+ // Exit early for non `Object` objects.
+ if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||
+ (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
return false;
}
- var valueOf = getNative(value, 'valueOf'),
- objProto = valueOf && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
-
- return objProto
- ? (value == objProto || getPrototypeOf(value) == objProto)
- : shimIsPlainObject(value);
-};
+ // IE < 9 iterates inherited properties before own properties. If the first
+ // iterated property is an object's own property then there are no inherited
+ // enumerable properties.
+ var result;
+ // In most environments an object's own properties are iterated before
+ // its inherited properties. If the last iterated property is an object's
+ // own property then there are no inherited enumerable properties.
+ baseForIn(value, function(subValue, key) {
+ result = key;
+ });
+ return result === undefined || hasOwnProperty.call(value, result);
+}
module.exports = isPlainObject;
diff --git a/lang/isRegExp.js b/lang/isRegExp.js
index 54ddf11a9..f029cbdcd 100644
--- a/lang/isRegExp.js
+++ b/lang/isRegExp.js
@@ -1,4 +1,4 @@
-var isObjectLike = require('../internal/isObjectLike');
+var isObject = require('./isObject');
/** `Object#toString` result references. */
var regexpTag = '[object RegExp]';
@@ -7,7 +7,7 @@ var regexpTag = '[object RegExp]';
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
@@ -29,7 +29,7 @@ var objToString = objectProto.toString;
* // => false
*/
function isRegExp(value) {
- return isObjectLike(value) && objToString.call(value) == regexpTag;
+ return isObject(value) && objToString.call(value) == regexpTag;
}
module.exports = isRegExp;
diff --git a/lang/isString.js b/lang/isString.js
index f4155dcb0..8b28ee19a 100644
--- a/lang/isString.js
+++ b/lang/isString.js
@@ -7,7 +7,7 @@ var stringTag = '[object String]';
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
diff --git a/lang/isTypedArray.js b/lang/isTypedArray.js
index 4642c7a40..6e8a6e038 100644
--- a/lang/isTypedArray.js
+++ b/lang/isTypedArray.js
@@ -46,7 +46,7 @@ typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
diff --git a/math.js b/math.js
index 3e551b23a..21409cebd 100644
--- a/math.js
+++ b/math.js
@@ -1,6 +1,9 @@
module.exports = {
'add': require('./math/add'),
+ 'ceil': require('./math/ceil'),
+ 'floor': require('./math/floor'),
'max': require('./math/max'),
'min': require('./math/min'),
+ 'round': require('./math/round'),
'sum': require('./math/sum')
};
diff --git a/math/ceil.js b/math/ceil.js
new file mode 100644
index 000000000..9dbf0c26d
--- /dev/null
+++ b/math/ceil.js
@@ -0,0 +1,25 @@
+var createRound = require('../internal/createRound');
+
+/**
+ * Calculates `n` rounded up to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} n The number to round up.
+ * @param {number} [precision=0] The precision to round up to.
+ * @returns {number} Returns the rounded up number.
+ * @example
+ *
+ * _.ceil(4.006);
+ * // => 5
+ *
+ * _.ceil(6.004, 2);
+ * // => 6.01
+ *
+ * _.ceil(6040, -2);
+ * // => 6100
+ */
+var ceil = createRound('ceil');
+
+module.exports = ceil;
diff --git a/math/floor.js b/math/floor.js
new file mode 100644
index 000000000..e4dcae8bf
--- /dev/null
+++ b/math/floor.js
@@ -0,0 +1,25 @@
+var createRound = require('../internal/createRound');
+
+/**
+ * Calculates `n` rounded down to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} n The number to round down.
+ * @param {number} [precision=0] The precision to round down to.
+ * @returns {number} Returns the rounded down number.
+ * @example
+ *
+ * _.floor(4.006);
+ * // => 4
+ *
+ * _.floor(0.046, 2);
+ * // => 0.04
+ *
+ * _.floor(4060, -2);
+ * // => 4000
+ */
+var floor = createRound('floor');
+
+module.exports = floor;
diff --git a/math/round.js b/math/round.js
new file mode 100644
index 000000000..5c69d0c15
--- /dev/null
+++ b/math/round.js
@@ -0,0 +1,25 @@
+var createRound = require('../internal/createRound');
+
+/**
+ * Calculates `n` rounded to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} n The number to round.
+ * @param {number} [precision=0] The precision to round to.
+ * @returns {number} Returns the rounded number.
+ * @example
+ *
+ * _.round(4.006);
+ * // => 4
+ *
+ * _.round(4.006, 2);
+ * // => 4.01
+ *
+ * _.round(4060, -2);
+ * // => 4100
+ */
+var round = createRound('round');
+
+module.exports = round;
diff --git a/math/sum.js b/math/sum.js
index 0e1878054..114ff1b0a 100644
--- a/math/sum.js
+++ b/math/sum.js
@@ -39,13 +39,11 @@ var arraySum = require('../internal/arraySum'),
*/
function sum(collection, iteratee, thisArg) {
if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = null;
+ iteratee = undefined;
}
- var noIteratee = iteratee == null;
-
- iteratee = noIteratee ? iteratee : baseCallback(iteratee, thisArg, 3);
- return noIteratee
- ? arraySum(isArray(collection) ? collection : toIterable(collection))
+ iteratee = baseCallback(iteratee, thisArg, 3);
+ return iteratee.length == 1
+ ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee)
: baseSum(collection, iteratee);
}
diff --git a/number/inRange.js b/number/inRange.js
index 4e5cc88b0..2ee832528 100644
--- a/number/inRange.js
+++ b/number/inRange.js
@@ -35,7 +35,7 @@ var nativeMax = Math.max,
*/
function inRange(value, start, end) {
start = +start || 0;
- if (typeof end === 'undefined') {
+ if (end === undefined) {
end = start;
start = 0;
} else {
diff --git a/number/random.js b/number/random.js
index 4212c2bb2..589d74e7c 100644
--- a/number/random.js
+++ b/number/random.js
@@ -34,7 +34,7 @@ var nativeMin = Math.min,
*/
function random(min, max, floating) {
if (floating && isIterateeCall(min, max, floating)) {
- max = floating = null;
+ max = floating = undefined;
}
var noMin = min == null,
noMax = max == null;
diff --git a/object.js b/object.js
index a1e0703e0..4beb005ac 100644
--- a/object.js
+++ b/object.js
@@ -2,6 +2,7 @@ module.exports = {
'assign': require('./object/assign'),
'create': require('./object/create'),
'defaults': require('./object/defaults'),
+ 'defaultsDeep': require('./object/defaultsDeep'),
'extend': require('./object/extend'),
'findKey': require('./object/findKey'),
'findLastKey': require('./object/findLastKey'),
diff --git a/object/assign.js b/object/assign.js
index a01c75719..424e7edf9 100644
--- a/object/assign.js
+++ b/object/assign.js
@@ -10,7 +10,7 @@ var assignWith = require('../internal/assignWith'),
* (objectValue, sourceValue, key, object, source).
*
* **Note:** This method mutates `object` and is based on
- * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign).
+ * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
*
* @static
* @memberOf _
diff --git a/object/create.js b/object/create.js
index a11d75be6..176294f35 100644
--- a/object/create.js
+++ b/object/create.js
@@ -39,7 +39,7 @@ var baseAssign = require('../internal/baseAssign'),
function create(prototype, properties, guard) {
var result = baseCreate(prototype);
if (guard && isIterateeCall(prototype, properties, guard)) {
- properties = null;
+ properties = undefined;
}
return properties ? baseAssign(result, properties) : result;
}
diff --git a/object/defaults.js b/object/defaults.js
index bcbd9f46b..c05011e52 100644
--- a/object/defaults.js
+++ b/object/defaults.js
@@ -1,6 +1,6 @@
var assign = require('./assign'),
assignDefaults = require('../internal/assignDefaults'),
- restParam = require('../function/restParam');
+ createDefaults = require('../internal/createDefaults');
/**
* Assigns own enumerable properties of source object(s) to the destination
@@ -20,13 +20,6 @@ var assign = require('./assign'),
* _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
* // => { 'user': 'barney', 'age': 36 }
*/
-var defaults = restParam(function(args) {
- var object = args[0];
- if (object == null) {
- return object;
- }
- args.push(assignDefaults);
- return assign.apply(undefined, args);
-});
+var defaults = createDefaults(assign, assignDefaults);
module.exports = defaults;
diff --git a/object/defaultsDeep.js b/object/defaultsDeep.js
new file mode 100644
index 000000000..ec6e687e3
--- /dev/null
+++ b/object/defaultsDeep.js
@@ -0,0 +1,25 @@
+var createDefaults = require('../internal/createDefaults'),
+ merge = require('./merge'),
+ mergeDefaults = require('../internal/mergeDefaults');
+
+/**
+ * This method is like `_.defaults` except that it recursively assigns
+ * default properties.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
+ * // => { 'user': { 'name': 'barney', 'age': 36 } }
+ *
+ */
+var defaultsDeep = createDefaults(merge, mergeDefaults);
+
+module.exports = defaultsDeep;
diff --git a/object/invert.js b/object/invert.js
index de02c08e8..54fb1f1be 100644
--- a/object/invert.js
+++ b/object/invert.js
@@ -32,7 +32,7 @@ var hasOwnProperty = objectProto.hasOwnProperty;
*/
function invert(object, multiValue, guard) {
if (guard && isIterateeCall(object, multiValue, guard)) {
- multiValue = null;
+ multiValue = undefined;
}
var index = -1,
props = keys(object),
diff --git a/object/keys.js b/object/keys.js
index a87551439..4706fd618 100644
--- a/object/keys.js
+++ b/object/keys.js
@@ -10,7 +10,7 @@ var nativeKeys = getNative(Object, 'keys');
* Creates an array of the own enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects. See the
- * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys)
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
* for more details.
*
* @static
@@ -34,7 +34,7 @@ var nativeKeys = getNative(Object, 'keys');
* // => ['0', '1']
*/
var keys = !nativeKeys ? shimKeys : function(object) {
- var Ctor = object == null ? null : object.constructor;
+ var Ctor = object == null ? undefined : object.constructor;
if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
(typeof object != 'function' && isArrayLike(object))) {
return shimKeys(object);
diff --git a/object/transform.js b/object/transform.js
index 9f6b8ce7e..9a814b145 100644
--- a/object/transform.js
+++ b/object/transform.js
@@ -46,7 +46,7 @@ function transform(object, iteratee, accumulator, thisArg) {
if (isArr) {
accumulator = isArray(object) ? new Ctor : [];
} else {
- accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : null);
+ accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
}
} else {
accumulator = {};
diff --git a/package.json b/package.json
index 34fbd73cd..1986951b4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "lodash",
- "version": "3.9.3",
+ "version": "3.10.0",
"description": "The modern build of lodash modular utilities.",
"homepage": "https://lodash.com/",
"icon": "https://lodash.com/icon.svg",
diff --git a/string/escapeRegExp.js b/string/escapeRegExp.js
index 0234d67f5..176137abf 100644
--- a/string/escapeRegExp.js
+++ b/string/escapeRegExp.js
@@ -1,11 +1,11 @@
-var baseToString = require('../internal/baseToString');
+var baseToString = require('../internal/baseToString'),
+ escapeRegExpChar = require('../internal/escapeRegExpChar');
/**
- * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special).
- * In addition to special characters the forward slash is escaped to allow for
- * easier `eval` use and `Function` compilation.
+ * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns)
+ * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern).
*/
-var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g,
+var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,
reHasRegExpChars = RegExp(reRegExpChars.source);
/**
@@ -25,8 +25,8 @@ var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g,
function escapeRegExp(string) {
string = baseToString(string);
return (string && reHasRegExpChars.test(string))
- ? string.replace(reRegExpChars, '\\$&')
- : string;
+ ? string.replace(reRegExpChars, escapeRegExpChar)
+ : (string || '(?:)');
}
module.exports = escapeRegExp;
diff --git a/string/pad.js b/string/pad.js
index 60b5c1332..60e523b9e 100644
--- a/string/pad.js
+++ b/string/pad.js
@@ -1,12 +1,10 @@
var baseToString = require('../internal/baseToString'),
createPadding = require('../internal/createPadding');
-/** Native method references. */
-var ceil = Math.ceil,
- floor = Math.floor;
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeIsFinite = global.isFinite;
+var nativeCeil = Math.ceil,
+ nativeFloor = Math.floor,
+ nativeIsFinite = global.isFinite;
/**
* Pads `string` on the left and right sides if it's shorter than `length`.
@@ -39,8 +37,8 @@ function pad(string, length, chars) {
return string;
}
var mid = (length - strLength) / 2,
- leftLength = floor(mid),
- rightLength = ceil(mid);
+ leftLength = nativeFloor(mid),
+ rightLength = nativeCeil(mid);
chars = createPadding('', rightLength, chars);
return chars.slice(0, leftLength) + string + chars;
diff --git a/string/parseInt.js b/string/parseInt.js
index c4cf71a96..f457711e4 100644
--- a/string/parseInt.js
+++ b/string/parseInt.js
@@ -4,18 +4,6 @@ var isIterateeCall = require('../internal/isIterateeCall'),
/** Used to detect hexadecimal string values. */
var reHasHexPrefix = /^0[xX]/;
-/** Used to detect and test for whitespace. */
-var whitespace = (
- // Basic whitespace characters.
- ' \t\x0b\f\xa0\ufeff' +
-
- // Line terminators.
- '\n\r\u2028\u2029' +
-
- // Unicode category "Zs" space separators.
- '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
-);
-
/* Native method references for those with the same name as other `lodash` methods. */
var nativeParseInt = global.parseInt;
@@ -43,25 +31,16 @@ var nativeParseInt = global.parseInt;
* // => [6, 8, 10]
*/
function parseInt(string, radix, guard) {
- if (guard && isIterateeCall(string, radix, guard)) {
+ // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.
+ // Chrome fails to trim leading whitespace characters.
+ // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
+ if (guard ? isIterateeCall(string, radix, guard) : radix == null) {
radix = 0;
+ } else if (radix) {
+ radix = +radix;
}
- return nativeParseInt(string, radix);
-}
-// Fallback for environments with pre-ES5 implementations.
-if (nativeParseInt(whitespace + '08') != 8) {
- parseInt = function(string, radix, guard) {
- // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.
- // Chrome fails to trim leading whitespace characters.
- // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
- if (guard ? isIterateeCall(string, radix, guard) : radix == null) {
- radix = 0;
- } else if (radix) {
- radix = +radix;
- }
- string = trim(string);
- return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
- };
+ string = trim(string);
+ return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
}
module.exports = parseInt;
diff --git a/string/repeat.js b/string/repeat.js
index 271156b42..2902123e6 100644
--- a/string/repeat.js
+++ b/string/repeat.js
@@ -1,10 +1,8 @@
var baseToString = require('../internal/baseToString');
-/** Native method references. */
-var floor = Math.floor;
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeIsFinite = global.isFinite;
+var nativeFloor = Math.floor,
+ nativeIsFinite = global.isFinite;
/**
* Repeats the given string `n` times.
@@ -39,7 +37,7 @@ function repeat(string, n) {
if (n % 2) {
result += string;
}
- n = floor(n / 2);
+ n = nativeFloor(n / 2);
string += string;
} while (n);
diff --git a/string/template.js b/string/template.js
index b3910481e..e75e992b2 100644
--- a/string/template.js
+++ b/string/template.js
@@ -16,7 +16,7 @@ var reEmptyStringLeading = /\b__p \+= '';/g,
reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-/** Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components). */
+/** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
/** Used to ensure capturing order of template delimiters. */
@@ -127,7 +127,7 @@ function template(string, options, otherOptions) {
var settings = templateSettings.imports._.templateSettings || templateSettings;
if (otherOptions && isIterateeCall(string, options, otherOptions)) {
- options = otherOptions = null;
+ options = otherOptions = undefined;
}
string = baseToString(string);
options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);
diff --git a/string/trunc.js b/string/trunc.js
index 8d9b309b9..29e193990 100644
--- a/string/trunc.js
+++ b/string/trunc.js
@@ -52,7 +52,7 @@ var reFlags = /\w*$/;
*/
function trunc(string, options, guard) {
if (guard && isIterateeCall(string, options, guard)) {
- options = null;
+ options = undefined;
}
var length = DEFAULT_TRUNC_LENGTH,
omission = DEFAULT_TRUNC_OMISSION;
diff --git a/string/words.js b/string/words.js
index 364e971de..3013ad630 100644
--- a/string/words.js
+++ b/string/words.js
@@ -29,7 +29,7 @@ var reWords = (function() {
*/
function words(string, pattern, guard) {
if (guard && isIterateeCall(string, pattern, guard)) {
- pattern = null;
+ pattern = undefined;
}
string = baseToString(string);
return string.match(pattern || reWords) || [];
diff --git a/support.js b/support.js
index 12c97f51c..5009c2c50 100644
--- a/support.js
+++ b/support.js
@@ -1,6 +1,3 @@
-/** Used to detect DOM support. */
-var document = (document = global.window) ? document.document : null;
-
/**
* An object environment feature flags.
*
@@ -10,25 +7,4 @@ var document = (document = global.window) ? document.document : null;
*/
var support = {};
-(function(x) {
- var Ctor = function() { this.x = x; },
- object = { '0': x, 'length': x },
- props = [];
-
- Ctor.prototype = { 'valueOf': x, 'y': x };
- for (var key in new Ctor) { props.push(key); }
-
- /**
- * Detect if the DOM is supported.
- *
- * @memberOf _.support
- * @type boolean
- */
- try {
- support.dom = document.createDocumentFragment().nodeType === 11;
- } catch(e) {
- support.dom = false;
- }
-}(1, 0));
-
module.exports = support;
diff --git a/utility/callback.js b/utility/callback.js
index d864d46c5..21223d023 100644
--- a/utility/callback.js
+++ b/utility/callback.js
@@ -43,7 +43,7 @@ var baseCallback = require('../internal/baseCallback'),
*/
function callback(func, thisArg, guard) {
if (guard && isIterateeCall(func, thisArg, guard)) {
- thisArg = null;
+ thisArg = undefined;
}
return isObjectLike(func)
? matches(func)
diff --git a/utility/mixin.js b/utility/mixin.js
index 1340464b4..5c4a372d3 100644
--- a/utility/mixin.js
+++ b/utility/mixin.js
@@ -1,15 +1,10 @@
var arrayCopy = require('../internal/arrayCopy'),
+ arrayPush = require('../internal/arrayPush'),
baseFunctions = require('../internal/baseFunctions'),
isFunction = require('../lang/isFunction'),
isObject = require('../lang/isObject'),
keys = require('../object/keys');
-/** Used for native method references. */
-var arrayProto = Array.prototype;
-
-/** Native method references. */
-var push = arrayProto.push;
-
/**
* Adds all own enumerable function properties of a source object to the
* destination object. If `object` is a function then methods are added to
@@ -76,9 +71,7 @@ function mixin(object, source, options) {
result.__chain__ = chainAll;
return result;
}
- var args = [this.value()];
- push.apply(args, arguments);
- return func.apply(object, args);
+ return func.apply(object, arrayPush([this.value()], arguments));
};
}(func));
}
diff --git a/utility/range.js b/utility/range.js
index fad70a42f..e45254e7f 100644
--- a/utility/range.js
+++ b/utility/range.js
@@ -1,10 +1,8 @@
var isIterateeCall = require('../internal/isIterateeCall');
-/** Native method references. */
-var ceil = Math.ceil;
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeMax = Math.max;
+var nativeCeil = Math.ceil,
+ nativeMax = Math.max;
/**
* Creates an array of numbers (positive and/or negative) progressing from
@@ -41,7 +39,7 @@ var nativeMax = Math.max;
*/
function range(start, end, step) {
if (step && isIterateeCall(start, end, step)) {
- end = step = null;
+ end = step = undefined;
}
start = +start || 0;
step = step == null ? 1 : (+step || 0);
@@ -55,7 +53,7 @@ function range(start, end, step) {
// Use `Array(length)` so engines like Chakra and V8 avoid slower modes.
// See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details.
var index = -1,
- length = nativeMax(ceil((end - start) / (step || 1)), 0),
+ length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
result = Array(length);
while (++index < length) {
diff --git a/utility/times.js b/utility/times.js
index dba312901..9a41e2fe2 100644
--- a/utility/times.js
+++ b/utility/times.js
@@ -1,10 +1,8 @@
var bindCallback = require('../internal/bindCallback');
-/** Native method references. */
-var floor = Math.floor;
-
/* Native method references for those with the same name as other `lodash` methods. */
-var nativeIsFinite = global.isFinite,
+var nativeFloor = Math.floor,
+ nativeIsFinite = global.isFinite,
nativeMin = Math.min;
/** Used as references for the maximum length and index of an array. */
@@ -38,7 +36,7 @@ var MAX_ARRAY_LENGTH = 4294967295;
* // => also invokes `mage.castSpell(n)` three times
*/
function times(n, iteratee, thisArg) {
- n = floor(n);
+ n = nativeFloor(n);
// Exit early to avoid a JSC JIT bug in Safari 8
// where `Array(0)` is treated as `Array(1)`.