diff --git a/.npmignore b/.npmignore
new file mode 100644
index 000000000..8d98f9deb
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1 @@
+.*
diff --git a/LICENSE b/LICENSE
index 9cd87e5dc..b054ca5a3 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
-Copyright 2012-2015 The Dojo Foundation
-Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas,
+Copyright 2012-2016 The Dojo Foundation
+Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/README.md b/README.md
index 696b7765b..5bf134b39 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,30 @@
-# lodash v3.10.1
+# lodash-amd v4.0.0
-The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules.
+The [lodash](https://lodash.com/) library exported as [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules.
Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli):
```bash
-$ lodash modularize modern exports=amd -o ./
-$ lodash modern exports=amd -d -o ./main.js
+$ lodash exports=amd -o ./
+$ lodash exports=amd -d -o ./main.js
```
## Installation
-Using bower or volo:
-
+Using npm:
```bash
-$ bower i lodash#3.10.1-amd
-$ volo add lodash/3.10.1-amd
+$ {sudo -H} npm i -g npm
+$ npm i --save lodash-amd
```
-Defining a build as `'lodash'`.
-
+Using an AMD loader:
```js
require({
'packages': [
{ 'name': 'lodash', 'location': 'path/to/lodash' }
]
-}, ['lodash/array/chunk'], function(chunk) {
+}, ['lodash/chunk'], function(chunk) {
// use `chunk`
});
```
+
+See the [package source](https://github.com/lodash/lodash/tree/4.0.0-amd) for more details.
diff --git a/add.js b/add.js
new file mode 100644
index 000000000..7b8eb9b4b
--- /dev/null
+++ b/add.js
@@ -0,0 +1,32 @@
+define([], function() {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Adds two numbers.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} augend The first number in an addition.
+ * @param {number} addend The second number in an addition.
+ * @returns {number} Returns the total.
+ * @example
+ *
+ * _.add(6, 4);
+ * // => 10
+ */
+ function add(augend, addend) {
+ var result;
+ if (augend !== undefined) {
+ result = augend;
+ }
+ if (addend !== undefined) {
+ result = result === undefined ? addend : (result + addend);
+ }
+ return result;
+ }
+
+ return add;
+});
diff --git a/function/after.js b/after.js
similarity index 73%
rename from function/after.js
rename to after.js
index c2e235af0..f6ac517c1 100644
--- a/function/after.js
+++ b/after.js
@@ -1,11 +1,8 @@
-define(['../internal/root'], function(root) {
+define(['./toInteger'], function(toInteger) {
/** 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 nativeIsFinite = root.isFinite;
-
/**
* The opposite of `_.before`; this method creates a function that invokes
* `func` once it's called `n` or more times.
@@ -31,15 +28,9 @@ define(['../internal/root'], function(root) {
*/
function after(n, func) {
if (typeof func != 'function') {
- if (typeof n == 'function') {
- var temp = n;
- n = func;
- func = temp;
- } else {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
+ throw new TypeError(FUNC_ERROR_TEXT);
}
- n = nativeIsFinite(n = +n) ? n : 0;
+ n = toInteger(n);
return function() {
if (--n < 1) {
return func.apply(this, arguments);
diff --git a/array.js b/array.js
index b3953a6c8..f8ab23a85 100644
--- a/array.js
+++ b/array.js
@@ -1,8 +1,11 @@
-define(['./array/chunk', './array/compact', './array/difference', './array/drop', './array/dropRight', './array/dropRightWhile', './array/dropWhile', './array/fill', './array/findIndex', './array/findLastIndex', './array/first', './array/flatten', './array/flattenDeep', './array/head', './array/indexOf', './array/initial', './array/intersection', './array/last', './array/lastIndexOf', './array/object', './array/pull', './array/pullAt', './array/remove', './array/rest', './array/slice', './array/sortedIndex', './array/sortedLastIndex', './array/tail', './array/take', './array/takeRight', './array/takeRightWhile', './array/takeWhile', './array/union', './array/uniq', './array/unique', './array/unzip', './array/unzipWith', './array/without', './array/xor', './array/zip', './array/zipObject', './array/zipWith'], function(chunk, compact, difference, drop, dropRight, dropRightWhile, dropWhile, fill, findIndex, findLastIndex, first, flatten, flattenDeep, head, indexOf, initial, intersection, last, lastIndexOf, object, pull, pullAt, remove, rest, slice, sortedIndex, sortedLastIndex, tail, take, takeRight, takeRightWhile, takeWhile, union, uniq, unique, unzip, unzipWith, without, xor, zip, zipObject, zipWith) {
+define(['./chunk', './compact', './concat', './difference', './differenceBy', './differenceWith', './drop', './dropRight', './dropRightWhile', './dropWhile', './fill', './findIndex', './findLastIndex', './flatMap', './flatten', './flattenDeep', './fromPairs', './head', './indexOf', './initial', './intersection', './intersectionBy', './intersectionWith', './join', './last', './lastIndexOf', './pull', './pullAll', './pullAllBy', './pullAt', './remove', './reverse', './slice', './sortedIndex', './sortedIndexBy', './sortedIndexOf', './sortedLastIndex', './sortedLastIndexBy', './sortedLastIndexOf', './sortedUniq', './sortedUniqBy', './tail', './take', './takeRight', './takeRightWhile', './takeWhile', './union', './unionBy', './unionWith', './uniq', './uniqBy', './uniqWith', './unzip', './unzipWith', './without', './xor', './xorBy', './xorWith', './zip', './zipObject', './zipWith'], function(chunk, compact, concat, difference, differenceBy, differenceWith, drop, dropRight, dropRightWhile, dropWhile, fill, findIndex, findLastIndex, flatMap, flatten, flattenDeep, fromPairs, head, indexOf, initial, intersection, intersectionBy, intersectionWith, join, last, lastIndexOf, pull, pullAll, pullAllBy, pullAt, remove, reverse, slice, sortedIndex, sortedIndexBy, sortedIndexOf, sortedLastIndex, sortedLastIndexBy, sortedLastIndexOf, sortedUniq, sortedUniqBy, tail, take, takeRight, takeRightWhile, takeWhile, union, unionBy, unionWith, uniq, uniqBy, uniqWith, unzip, unzipWith, without, xor, xorBy, xorWith, zip, zipObject, zipWith) {
return {
'chunk': chunk,
'compact': compact,
+ 'concat': concat,
'difference': difference,
+ 'differenceBy': differenceBy,
+ 'differenceWith': differenceWith,
'drop': drop,
'dropRight': dropRight,
'dropRightWhile': dropRightWhile,
@@ -10,35 +13,51 @@ define(['./array/chunk', './array/compact', './array/difference', './array/drop'
'fill': fill,
'findIndex': findIndex,
'findLastIndex': findLastIndex,
- 'first': first,
+ 'flatMap': flatMap,
'flatten': flatten,
'flattenDeep': flattenDeep,
+ 'fromPairs': fromPairs,
'head': head,
'indexOf': indexOf,
'initial': initial,
'intersection': intersection,
+ 'intersectionBy': intersectionBy,
+ 'intersectionWith': intersectionWith,
+ 'join': join,
'last': last,
'lastIndexOf': lastIndexOf,
- 'object': object,
'pull': pull,
+ 'pullAll': pullAll,
+ 'pullAllBy': pullAllBy,
'pullAt': pullAt,
'remove': remove,
- 'rest': rest,
+ 'reverse': reverse,
'slice': slice,
'sortedIndex': sortedIndex,
+ 'sortedIndexBy': sortedIndexBy,
+ 'sortedIndexOf': sortedIndexOf,
'sortedLastIndex': sortedLastIndex,
+ 'sortedLastIndexBy': sortedLastIndexBy,
+ 'sortedLastIndexOf': sortedLastIndexOf,
+ 'sortedUniq': sortedUniq,
+ 'sortedUniqBy': sortedUniqBy,
'tail': tail,
'take': take,
'takeRight': takeRight,
'takeRightWhile': takeRightWhile,
'takeWhile': takeWhile,
'union': union,
+ 'unionBy': unionBy,
+ 'unionWith': unionWith,
'uniq': uniq,
- 'unique': unique,
+ 'uniqBy': uniqBy,
+ 'uniqWith': uniqWith,
'unzip': unzip,
'unzipWith': unzipWith,
'without': without,
'xor': xor,
+ 'xorBy': xorBy,
+ 'xorWith': xorWith,
'zip': zip,
'zipObject': zipObject,
'zipWith': zipWith
diff --git a/array/dropRightWhile.js b/array/dropRightWhile.js
deleted file mode 100644
index 8a245bfb5..000000000
--- a/array/dropRightWhile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-define(['../internal/baseCallback', '../internal/baseWhile'], function(baseCallback, baseWhile) {
-
- /**
- * Creates a slice of `array` excluding elements dropped from the end.
- * Elements are dropped until `predicate` returns falsey. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that match the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to query.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Array} Returns the slice of `array`.
- * @example
- *
- * _.dropRightWhile([1, 2, 3], function(n) {
- * return n > 1;
- * });
- * // => [1]
- *
- * var users = [
- * { 'user': 'barney', 'active': true },
- * { 'user': 'fred', 'active': false },
- * { 'user': 'pebbles', 'active': false }
- * ];
- *
- * // using the `_.matches` callback shorthand
- * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');
- * // => ['barney', 'fred']
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.dropRightWhile(users, 'active', false), 'user');
- * // => ['barney']
- *
- * // using the `_.property` callback shorthand
- * _.pluck(_.dropRightWhile(users, 'active'), 'user');
- * // => ['barney', 'fred', 'pebbles']
- */
- function dropRightWhile(array, predicate, thisArg) {
- return (array && array.length)
- ? baseWhile(array, baseCallback(predicate, thisArg, 3), true, true)
- : [];
- }
-
- return dropRightWhile;
-});
diff --git a/array/dropWhile.js b/array/dropWhile.js
deleted file mode 100644
index 09c4b70e9..000000000
--- a/array/dropWhile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-define(['../internal/baseCallback', '../internal/baseWhile'], function(baseCallback, baseWhile) {
-
- /**
- * Creates a slice of `array` excluding elements dropped from the beginning.
- * Elements are dropped until `predicate` returns falsey. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to query.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Array} Returns the slice of `array`.
- * @example
- *
- * _.dropWhile([1, 2, 3], function(n) {
- * return n < 3;
- * });
- * // => [3]
- *
- * var users = [
- * { 'user': 'barney', 'active': false },
- * { 'user': 'fred', 'active': false },
- * { 'user': 'pebbles', 'active': true }
- * ];
- *
- * // using the `_.matches` callback shorthand
- * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user');
- * // => ['fred', 'pebbles']
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.dropWhile(users, 'active', false), 'user');
- * // => ['pebbles']
- *
- * // using the `_.property` callback shorthand
- * _.pluck(_.dropWhile(users, 'active'), 'user');
- * // => ['barney', 'fred', 'pebbles']
- */
- function dropWhile(array, predicate, thisArg) {
- return (array && array.length)
- ? baseWhile(array, baseCallback(predicate, thisArg, 3), true)
- : [];
- }
-
- return dropWhile;
-});
diff --git a/array/findIndex.js b/array/findIndex.js
deleted file mode 100644
index 3f8c8fd6c..000000000
--- a/array/findIndex.js
+++ /dev/null
@@ -1,54 +0,0 @@
-define(['../internal/createFindIndex'], function(createFindIndex) {
-
- /**
- * This method is like `_.find` except that it returns the index of the first
- * element `predicate` returns truthy for instead of the element itself.
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'active': false },
- * { 'user': 'fred', 'active': false },
- * { 'user': 'pebbles', 'active': true }
- * ];
- *
- * _.findIndex(users, function(chr) {
- * return chr.user == 'barney';
- * });
- * // => 0
- *
- * // using the `_.matches` callback shorthand
- * _.findIndex(users, { 'user': 'fred', 'active': false });
- * // => 1
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.findIndex(users, 'active', false);
- * // => 0
- *
- * // using the `_.property` callback shorthand
- * _.findIndex(users, 'active');
- * // => 2
- */
- var findIndex = createFindIndex();
-
- return findIndex;
-});
diff --git a/array/findLastIndex.js b/array/findLastIndex.js
deleted file mode 100644
index dc9a99e98..000000000
--- a/array/findLastIndex.js
+++ /dev/null
@@ -1,54 +0,0 @@
-define(['../internal/createFindIndex'], function(createFindIndex) {
-
- /**
- * This method is like `_.findIndex` except that it iterates over elements
- * of `collection` from right to left.
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'active': true },
- * { 'user': 'fred', 'active': false },
- * { 'user': 'pebbles', 'active': false }
- * ];
- *
- * _.findLastIndex(users, function(chr) {
- * return chr.user == 'pebbles';
- * });
- * // => 2
- *
- * // using the `_.matches` callback shorthand
- * _.findLastIndex(users, { 'user': 'barney', 'active': true });
- * // => 0
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.findLastIndex(users, 'active', false);
- * // => 2
- *
- * // using the `_.property` callback shorthand
- * _.findLastIndex(users, 'active');
- * // => 0
- */
- var findLastIndex = createFindIndex(true);
-
- return findLastIndex;
-});
diff --git a/array/flatten.js b/array/flatten.js
deleted file mode 100644
index 73ad51280..000000000
--- a/array/flatten.js
+++ /dev/null
@@ -1,32 +0,0 @@
-define(['../internal/baseFlatten', '../internal/isIterateeCall'], function(baseFlatten, isIterateeCall) {
-
- /**
- * Flattens a nested array. If `isDeep` is `true` the array is recursively
- * flattened, otherwise it's only flattened a single level.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to flatten.
- * @param {boolean} [isDeep] Specify a deep flatten.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {Array} Returns the new flattened array.
- * @example
- *
- * _.flatten([1, [2, 3, [4]]]);
- * // => [1, 2, 3, [4]]
- *
- * // using `isDeep`
- * _.flatten([1, [2, 3, [4]]], true);
- * // => [1, 2, 3, 4]
- */
- function flatten(array, isDeep, guard) {
- var length = array ? array.length : 0;
- if (guard && isIterateeCall(array, isDeep, guard)) {
- isDeep = false;
- }
- return length ? baseFlatten(array, isDeep) : [];
- }
-
- return flatten;
-});
diff --git a/array/head.js b/array/head.js
deleted file mode 100644
index cb5515c9a..000000000
--- a/array/head.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./first"], function(first) {
- return first;
-});
diff --git a/array/intersection.js b/array/intersection.js
deleted file mode 100644
index ceb20011f..000000000
--- a/array/intersection.js
+++ /dev/null
@@ -1,55 +0,0 @@
-define(['../internal/baseIndexOf', '../internal/cacheIndexOf', '../internal/createCache', '../internal/isArrayLike', '../function/restParam'], function(baseIndexOf, cacheIndexOf, createCache, isArrayLike, restParam) {
-
- /**
- * Creates an array of unique values that are included in all of the provided
- * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {...Array} [arrays] The arrays to inspect.
- * @returns {Array} Returns the new array of shared values.
- * @example
- * _.intersection([1, 2], [4, 2], [2, 1]);
- * // => [2]
- */
- var intersection = restParam(function(arrays) {
- var othLength = arrays.length,
- othIndex = othLength,
- caches = Array(length),
- indexOf = baseIndexOf,
- isCommon = true,
- result = [];
-
- while (othIndex--) {
- var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : [];
- caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null;
- }
- var array = arrays[0],
- index = -1,
- length = array ? array.length : 0,
- seen = caches[0];
-
- outer:
- while (++index < length) {
- value = array[index];
- if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) {
- var othIndex = othLength;
- while (--othIndex) {
- var cache = caches[othIndex];
- if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) {
- continue outer;
- }
- }
- if (seen) {
- seen.push(value);
- }
- result.push(value);
- }
- }
- return result;
- });
-
- return intersection;
-});
diff --git a/array/object.js b/array/object.js
deleted file mode 100644
index ad84b07c0..000000000
--- a/array/object.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./zipObject"], function(zipObject) {
- return zipObject;
-});
diff --git a/array/pull.js b/array/pull.js
deleted file mode 100644
index b40decdc4..000000000
--- a/array/pull.js
+++ /dev/null
@@ -1,53 +0,0 @@
-define(['../internal/baseIndexOf'], function(baseIndexOf) {
-
- /** Used for native method references. */
- var arrayProto = Array.prototype;
-
- /** Native method references. */
- var splice = arrayProto.splice;
-
- /**
- * Removes all provided values from `array` using
- * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons.
- *
- * **Note:** Unlike `_.without`, this method mutates `array`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to modify.
- * @param {...*} [values] The values to remove.
- * @returns {Array} Returns `array`.
- * @example
- *
- * var array = [1, 2, 3, 1, 2, 3];
- *
- * _.pull(array, 2, 3);
- * console.log(array);
- * // => [1, 1]
- */
- function pull() {
- var args = arguments,
- array = args[0];
-
- if (!(array && array.length)) {
- return array;
- }
- var index = 0,
- indexOf = baseIndexOf,
- length = args.length;
-
- while (++index < length) {
- var fromIndex = 0,
- value = args[index];
-
- while ((fromIndex = indexOf(array, value, fromIndex)) > -1) {
- splice.call(array, fromIndex, 1);
- }
- }
- return array;
- }
-
- return pull;
-});
diff --git a/array/pullAt.js b/array/pullAt.js
deleted file mode 100644
index c368261c7..000000000
--- a/array/pullAt.js
+++ /dev/null
@@ -1,37 +0,0 @@
-define(['../internal/baseAt', '../internal/baseCompareAscending', '../internal/baseFlatten', '../internal/basePullAt', '../function/restParam'], function(baseAt, baseCompareAscending, baseFlatten, basePullAt, restParam) {
-
- /**
- * Removes elements from `array` corresponding to the given indexes and returns
- * an array of the removed elements. Indexes may be specified as an array of
- * indexes or as individual arguments.
- *
- * **Note:** Unlike `_.at`, this method mutates `array`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to modify.
- * @param {...(number|number[])} [indexes] The indexes of elements to remove,
- * specified as individual indexes or arrays of indexes.
- * @returns {Array} Returns the new array of removed elements.
- * @example
- *
- * var array = [5, 10, 15, 20];
- * var evens = _.pullAt(array, 1, 3);
- *
- * console.log(array);
- * // => [5, 15]
- *
- * console.log(evens);
- * // => [10, 20]
- */
- var pullAt = restParam(function(array, indexes) {
- indexes = baseFlatten(indexes);
-
- var result = baseAt(array, indexes);
- basePullAt(array, indexes.sort(baseCompareAscending));
- return result;
- });
-
- return pullAt;
-});
diff --git a/array/sortedIndex.js b/array/sortedIndex.js
deleted file mode 100644
index d69e28e84..000000000
--- a/array/sortedIndex.js
+++ /dev/null
@@ -1,54 +0,0 @@
-define(['../internal/createSortedIndex'], function(createSortedIndex) {
-
- /**
- * Uses a binary search to determine the lowest index at which `value` should
- * be inserted into `array` in order to maintain its sort order. If an iteratee
- * function is provided it's invoked for `value` and each element of `array`
- * to compute their sort ranking. The iteratee is bound to `thisArg` and
- * invoked with one argument; (value).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The sorted array to inspect.
- * @param {*} value The value to evaluate.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
- * @example
- *
- * _.sortedIndex([30, 50], 40);
- * // => 1
- *
- * _.sortedIndex([4, 4, 5, 5], 5);
- * // => 2
- *
- * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } };
- *
- * // using an iteratee function
- * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) {
- * return this.data[word];
- * }, dict);
- * // => 1
- *
- * // using the `_.property` callback shorthand
- * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
- * // => 1
- */
- var sortedIndex = createSortedIndex();
-
- return sortedIndex;
-});
diff --git a/array/tail.js b/array/tail.js
deleted file mode 100644
index de2bacfd2..000000000
--- a/array/tail.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./rest"], function(rest) {
- return rest;
-});
diff --git a/array/takeRightWhile.js b/array/takeRightWhile.js
deleted file mode 100644
index bca3955bb..000000000
--- a/array/takeRightWhile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-define(['../internal/baseCallback', '../internal/baseWhile'], function(baseCallback, baseWhile) {
-
- /**
- * Creates a slice of `array` with elements taken from the end. Elements are
- * taken until `predicate` returns falsey. The predicate is bound to `thisArg`
- * and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to query.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Array} Returns the slice of `array`.
- * @example
- *
- * _.takeRightWhile([1, 2, 3], function(n) {
- * return n > 1;
- * });
- * // => [2, 3]
- *
- * var users = [
- * { 'user': 'barney', 'active': true },
- * { 'user': 'fred', 'active': false },
- * { 'user': 'pebbles', 'active': false }
- * ];
- *
- * // using the `_.matches` callback shorthand
- * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');
- * // => ['pebbles']
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.takeRightWhile(users, 'active', false), 'user');
- * // => ['fred', 'pebbles']
- *
- * // using the `_.property` callback shorthand
- * _.pluck(_.takeRightWhile(users, 'active'), 'user');
- * // => []
- */
- function takeRightWhile(array, predicate, thisArg) {
- return (array && array.length)
- ? baseWhile(array, baseCallback(predicate, thisArg, 3), false, true)
- : [];
- }
-
- return takeRightWhile;
-});
diff --git a/array/takeWhile.js b/array/takeWhile.js
deleted file mode 100644
index 62de8f90b..000000000
--- a/array/takeWhile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-define(['../internal/baseCallback', '../internal/baseWhile'], function(baseCallback, baseWhile) {
-
- /**
- * Creates a slice of `array` with elements taken from the beginning. Elements
- * are taken until `predicate` returns falsey. The predicate is bound to
- * `thisArg` and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to query.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Array} Returns the slice of `array`.
- * @example
- *
- * _.takeWhile([1, 2, 3], function(n) {
- * return n < 3;
- * });
- * // => [1, 2]
- *
- * var users = [
- * { 'user': 'barney', 'active': false },
- * { 'user': 'fred', 'active': false},
- * { 'user': 'pebbles', 'active': true }
- * ];
- *
- * // using the `_.matches` callback shorthand
- * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user');
- * // => ['barney']
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.takeWhile(users, 'active', false), 'user');
- * // => ['barney', 'fred']
- *
- * // using the `_.property` callback shorthand
- * _.pluck(_.takeWhile(users, 'active'), 'user');
- * // => []
- */
- function takeWhile(array, predicate, thisArg) {
- return (array && array.length)
- ? baseWhile(array, baseCallback(predicate, thisArg, 3))
- : [];
- }
-
- return takeWhile;
-});
diff --git a/array/uniq.js b/array/uniq.js
deleted file mode 100644
index 37b19fcb5..000000000
--- a/array/uniq.js
+++ /dev/null
@@ -1,72 +0,0 @@
-define(['../internal/baseCallback', '../internal/baseUniq', '../internal/isIterateeCall', '../internal/sortedUniq'], function(baseCallback, baseUniq, isIterateeCall, sortedUniq) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a duplicate-free version of an array, using
- * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons, in which only the first 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's invoked for
- * each element in the array to generate the criterion by which uniqueness
- * is computed. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index, array).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @alias unique
- * @category Array
- * @param {Array} array The array to inspect.
- * @param {boolean} [isSorted] Specify the array is sorted.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the new duplicate-value-free array.
- * @example
- *
- * _.uniq([2, 1, 2]);
- * // => [2, 1]
- *
- * // using `isSorted`
- * _.uniq([1, 1, 2], true);
- * // => [1, 2]
- *
- * // using an iteratee function
- * _.uniq([1, 2.5, 1.5, 2], function(n) {
- * return this.floor(n);
- * }, Math);
- * // => [1, 2.5]
- *
- * // using the `_.property` callback shorthand
- * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
- * // => [{ 'x': 1 }, { 'x': 2 }]
- */
- function uniq(array, isSorted, iteratee, thisArg) {
- var length = array ? array.length : 0;
- if (!length) {
- return [];
- }
- if (isSorted != null && typeof isSorted != 'boolean') {
- thisArg = iteratee;
- iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;
- isSorted = false;
- }
- iteratee = iteratee == null ? iteratee : baseCallback(iteratee, thisArg, 3);
- return (isSorted)
- ? sortedUniq(array, iteratee)
- : baseUniq(array, iteratee);
- }
-
- return uniq;
-});
diff --git a/array/unique.js b/array/unique.js
deleted file mode 100644
index 68394c408..000000000
--- a/array/unique.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./uniq"], function(uniq) {
- return uniq;
-});
diff --git a/array/unzipWith.js b/array/unzipWith.js
deleted file mode 100644
index fb521815b..000000000
--- a/array/unzipWith.js
+++ /dev/null
@@ -1,42 +0,0 @@
-define(['../internal/arrayMap', '../internal/arrayReduce', '../internal/bindCallback', './unzip'], function(arrayMap, arrayReduce, bindCallback, unzip) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * This method is like `_.unzip` except that it accepts an iteratee to specify
- * how regrouped values should be combined. The `iteratee` is bound to `thisArg`
- * and invoked with four arguments: (accumulator, value, index, group).
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array of grouped elements to process.
- * @param {Function} [iteratee] The function to combine regrouped values.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the new array of regrouped elements.
- * @example
- *
- * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
- * // => [[1, 10, 100], [2, 20, 200]]
- *
- * _.unzipWith(zipped, _.add);
- * // => [3, 30, 300]
- */
- function unzipWith(array, iteratee, thisArg) {
- var length = array ? array.length : 0;
- if (!length) {
- return [];
- }
- var result = unzip(array);
- if (iteratee == null) {
- return result;
- }
- iteratee = bindCallback(iteratee, thisArg, 4);
- return arrayMap(result, function(group) {
- return arrayReduce(group, iteratee, undefined, true);
- });
- }
-
- return unzipWith;
-});
diff --git a/array/xor.js b/array/xor.js
deleted file mode 100644
index 345368a0a..000000000
--- a/array/xor.js
+++ /dev/null
@@ -1,33 +0,0 @@
-define(['../internal/arrayPush', '../internal/baseDifference', '../internal/baseUniq', '../internal/isArrayLike'], function(arrayPush, baseDifference, baseUniq, isArrayLike) {
-
- /**
- * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
- * of the provided arrays.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {...Array} [arrays] The arrays to inspect.
- * @returns {Array} Returns the new array of values.
- * @example
- *
- * _.xor([1, 2], [4, 2]);
- * // => [1, 4]
- */
- function xor() {
- var index = -1,
- length = arguments.length;
-
- while (++index < length) {
- var array = arguments[index];
- if (isArrayLike(array)) {
- var result = result
- ? arrayPush(baseDifference(result, array), baseDifference(array, result))
- : array;
- }
- }
- return result ? baseUniq(result) : [];
- }
-
- return xor;
-});
diff --git a/array/zipObject.js b/array/zipObject.js
deleted file mode 100644
index 8c4425cf4..000000000
--- a/array/zipObject.js
+++ /dev/null
@@ -1,44 +0,0 @@
-define(['../lang/isArray'], function(isArray) {
-
- /**
- * The inverse of `_.pairs`; this method returns an object composed from arrays
- * of property names and values. Provide either a single two dimensional array,
- * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names
- * and one of corresponding values.
- *
- * @static
- * @memberOf _
- * @alias object
- * @category Array
- * @param {Array} props The property names.
- * @param {Array} [values=[]] The property values.
- * @returns {Object} Returns the new object.
- * @example
- *
- * _.zipObject([['fred', 30], ['barney', 40]]);
- * // => { 'fred': 30, 'barney': 40 }
- *
- * _.zipObject(['fred', 'barney'], [30, 40]);
- * // => { 'fred': 30, 'barney': 40 }
- */
- function zipObject(props, values) {
- var index = -1,
- length = props ? props.length : 0,
- result = {};
-
- if (length && !values && !isArray(props[0])) {
- values = [];
- }
- while (++index < length) {
- var key = props[index];
- if (values) {
- result[key] = values[index];
- } else if (key) {
- result[key[0]] = key[1];
- }
- }
- return result;
- }
-
- return zipObject;
-});
diff --git a/array/zipWith.js b/array/zipWith.js
deleted file mode 100644
index a961409a9..000000000
--- a/array/zipWith.js
+++ /dev/null
@@ -1,39 +0,0 @@
-define(['../function/restParam', './unzipWith'], function(restParam, unzipWith) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * This method is like `_.zip` except that it accepts an iteratee to specify
- * how grouped values should be combined. The `iteratee` is bound to `thisArg`
- * and invoked with four arguments: (accumulator, value, index, group).
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {...Array} [arrays] The arrays to process.
- * @param {Function} [iteratee] The function to combine grouped values.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the new array of grouped elements.
- * @example
- *
- * _.zipWith([1, 2], [10, 20], [100, 200], _.add);
- * // => [111, 222]
- */
- var zipWith = restParam(function(arrays) {
- var length = arrays.length,
- iteratee = length > 2 ? arrays[length - 2] : undefined,
- thisArg = length > 1 ? arrays[length - 1] : undefined;
-
- if (length > 2 && typeof iteratee == 'function') {
- length -= 2;
- } else {
- iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined;
- thisArg = undefined;
- }
- arrays.length = length;
- return unzipWith(arrays, iteratee, thisArg);
- });
-
- return zipWith;
-});
diff --git a/function/ary.js b/ary.js
similarity index 56%
rename from function/ary.js
rename to ary.js
index d9c19d888..d9fe1c71a 100644
--- a/function/ary.js
+++ b/ary.js
@@ -1,4 +1,4 @@
-define(['../internal/createWrapper', '../internal/isIterateeCall'], function(createWrapper, isIterateeCall) {
+define(['./internal/createWrapper'], function(createWrapper) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -6,11 +6,8 @@ define(['../internal/createWrapper', '../internal/isIterateeCall'], function(cre
/** Used to compose bitmasks for wrapper metadata. */
var ARY_FLAG = 128;
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeMax = Math.max;
-
/**
- * Creates a function that accepts up to `n` arguments ignoring any
+ * Creates a function that accepts up to `n` arguments, ignoring any
* additional arguments.
*
* @static
@@ -18,7 +15,7 @@ define(['../internal/createWrapper', '../internal/isIterateeCall'], function(cre
* @category Function
* @param {Function} func The function to cap arguments for.
* @param {number} [n=func.length] The arity cap.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the new function.
* @example
*
@@ -26,10 +23,8 @@ define(['../internal/createWrapper', '../internal/isIterateeCall'], function(cre
* // => [6, 8, 10]
*/
function ary(func, n, guard) {
- if (guard && isIterateeCall(func, n, guard)) {
- n = undefined;
- }
- n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);
+ n = guard ? undefined : n;
+ n = (func && n == null) ? func.length : n;
return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
}
diff --git a/assign.js b/assign.js
new file mode 100644
index 000000000..1152cd3d6
--- /dev/null
+++ b/assign.js
@@ -0,0 +1,38 @@
+define(['./internal/copyObject', './internal/createAssigner', './keys'], function(copyObject, createAssigner, keys) {
+
+ /**
+ * Assigns own enumerable properties of source objects to the destination
+ * object. Source objects are applied from left to right. Subsequent sources
+ * overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object` and is loosely based on
+ * [`Object.assign`](https://mdn.io/Object/assign).
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function Foo() {
+ * this.c = 3;
+ * }
+ *
+ * function Bar() {
+ * this.e = 5;
+ * }
+ *
+ * Foo.prototype.d = 4;
+ * Bar.prototype.f = 6;
+ *
+ * _.assign({ 'a': 1 }, new Foo, new Bar);
+ * // => { 'a': 1, 'c': 3, 'e': 5 }
+ */
+ var assign = createAssigner(function(object, source) {
+ copyObject(source, keys(source), object);
+ });
+
+ return assign;
+});
diff --git a/assignIn.js b/assignIn.js
new file mode 100644
index 000000000..09b3f57fa
--- /dev/null
+++ b/assignIn.js
@@ -0,0 +1,37 @@
+define(['./internal/copyObject', './internal/createAssigner', './keysIn'], function(copyObject, createAssigner, keysIn) {
+
+ /**
+ * This method is like `_.assign` except that it iterates over own and
+ * inherited source properties.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @alias extend
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function Foo() {
+ * this.b = 2;
+ * }
+ *
+ * function Bar() {
+ * this.d = 4;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ * Bar.prototype.e = 5;
+ *
+ * _.assignIn({ 'a': 1 }, new Foo, new Bar);
+ * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
+ */
+ var assignIn = createAssigner(function(object, source) {
+ copyObject(source, keysIn(source), object);
+ });
+
+ return assignIn;
+});
diff --git a/assignInWith.js b/assignInWith.js
new file mode 100644
index 000000000..1ef39a573
--- /dev/null
+++ b/assignInWith.js
@@ -0,0 +1,35 @@
+define(['./internal/copyObjectWith', './internal/createAssigner', './keysIn'], function(copyObjectWith, createAssigner, keysIn) {
+
+ /**
+ * This method is like `_.assignIn` except that it accepts `customizer` which
+ * is invoked to produce the assigned values. If `customizer` returns `undefined`
+ * assignment is handled by the method instead. The `customizer` is invoked
+ * with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @alias extendWith
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignInWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */
+ var assignInWith = createAssigner(function(object, source, customizer) {
+ copyObjectWith(source, keysIn(source), object, customizer);
+ });
+
+ return assignInWith;
+});
diff --git a/assignWith.js b/assignWith.js
new file mode 100644
index 000000000..da6d87cf4
--- /dev/null
+++ b/assignWith.js
@@ -0,0 +1,34 @@
+define(['./internal/copyObjectWith', './internal/createAssigner', './keys'], function(copyObjectWith, createAssigner, keys) {
+
+ /**
+ * This method is like `_.assign` except that it accepts `customizer` which
+ * is invoked to produce the assigned values. If `customizer` returns `undefined`
+ * assignment is handled by the method instead. The `customizer` is invoked
+ * with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */
+ var assignWith = createAssigner(function(object, source, customizer) {
+ copyObjectWith(source, keys(source), object, customizer);
+ });
+
+ return assignWith;
+});
diff --git a/at.js b/at.js
new file mode 100644
index 000000000..9e0dafb90
--- /dev/null
+++ b/at.js
@@ -0,0 +1,28 @@
+define(['./internal/baseAt', './internal/baseFlatten', './rest'], function(baseAt, baseFlatten, rest) {
+
+ /**
+ * Creates an array of values corresponding to `paths` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {...(string|string[])} [paths] The property paths of elements to pick,
+ * specified individually or in arrays.
+ * @returns {Array} Returns the new array of picked elements.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+ *
+ * _.at(object, ['a[0].b.c', 'a[1]']);
+ * // => [3, 4]
+ *
+ * _.at(['a', 'b', 'c'], 0, 2);
+ * // => ['a', 'c']
+ */
+ var at = rest(function(object, paths) {
+ return baseAt(object, baseFlatten(paths));
+ });
+
+ return at;
+});
diff --git a/utility/attempt.js b/attempt.js
similarity index 77%
rename from utility/attempt.js
rename to attempt.js
index 6beac809f..966ab0ad8 100644
--- a/utility/attempt.js
+++ b/attempt.js
@@ -1,4 +1,4 @@
-define(['../lang/isError', '../function/restParam'], function(isError, restParam) {
+define(['./internal/apply', './isError', './rest'], function(apply, isError, rest) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -9,7 +9,7 @@ define(['../lang/isError', '../function/restParam'], function(isError, restParam
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Function} func The function to attempt.
* @returns {*} Returns the `func` result or error object.
* @example
@@ -23,10 +23,10 @@ define(['../lang/isError', '../function/restParam'], function(isError, restParam
* elements = [];
* }
*/
- var attempt = restParam(function(func, args) {
+ var attempt = rest(function(func, args) {
try {
- return func.apply(undefined, args);
- } catch(e) {
+ return apply(func, undefined, args);
+ } catch (e) {
return isError(e) ? e : new Error(e);
}
});
diff --git a/function/before.js b/before.js
similarity index 81%
rename from function/before.js
rename to before.js
index 750a7d1ca..5dcb29c3c 100644
--- a/function/before.js
+++ b/before.js
@@ -1,4 +1,4 @@
-define([], function() {
+define(['./toInteger'], function(toInteger) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -19,20 +19,15 @@ define([], function() {
* @returns {Function} Returns the new restricted function.
* @example
*
- * jQuery('#add').on('click', _.before(5, addContactToList));
+ * jQuery(element).on('click', _.before(5, addContactToList));
* // => allows adding up to 4 contacts to the list
*/
function before(n, func) {
var result;
if (typeof func != 'function') {
- if (typeof n == 'function') {
- var temp = n;
- n = func;
- func = temp;
- } else {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
+ throw new TypeError(FUNC_ERROR_TEXT);
}
+ n = toInteger(n);
return function() {
if (--n > 0) {
result = func.apply(this, arguments);
diff --git a/function/bind.js b/bind.js
similarity index 80%
rename from function/bind.js
rename to bind.js
index 2c51bf006..c1545631c 100644
--- a/function/bind.js
+++ b/bind.js
@@ -1,4 +1,4 @@
-define(['../internal/createWrapper', '../internal/replaceHolders', './restParam'], function(createWrapper, replaceHolders, restParam) {
+define(['./internal/createWrapper', './internal/replaceHolders', './rest'], function(createWrapper, replaceHolders, rest) {
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -12,7 +12,7 @@ define(['../internal/createWrapper', '../internal/replaceHolders', './restParam'
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for partially applied arguments.
*
- * **Note:** Unlike native `Function#bind` this method does not set the "length"
+ * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
* property of bound functions.
*
* @static
@@ -39,7 +39,7 @@ define(['../internal/createWrapper', '../internal/replaceHolders', './restParam'
* bound('hi');
* // => 'hi fred!'
*/
- var bind = restParam(function(func, thisArg, partials) {
+ var bind = rest(function(func, thisArg, partials) {
var bitmask = BIND_FLAG;
if (partials.length) {
var holders = replaceHolders(partials, bind.placeholder);
@@ -48,8 +48,5 @@ define(['../internal/createWrapper', '../internal/replaceHolders', './restParam'
return createWrapper(func, bitmask, thisArg, partials, holders);
});
- // Assign default placeholders.
- bind.placeholder = {};
-
return bind;
});
diff --git a/bindAll.js b/bindAll.js
new file mode 100644
index 000000000..a787ccda0
--- /dev/null
+++ b/bindAll.js
@@ -0,0 +1,37 @@
+define(['./internal/arrayEach', './internal/baseFlatten', './bind', './rest'], function(arrayEach, baseFlatten, bind, rest) {
+
+ /**
+ * Binds methods of an object to the object itself, overwriting the existing
+ * method.
+ *
+ * **Note:** This method doesn't set the "length" property of bound functions.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Object} object The object to bind and assign the bound methods to.
+ * @param {...(string|string[])} methodNames The object method names to bind,
+ * specified individually or in arrays.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var view = {
+ * 'label': 'docs',
+ * 'onClick': function() {
+ * console.log('clicked ' + this.label);
+ * }
+ * };
+ *
+ * _.bindAll(view, 'onClick');
+ * jQuery(element).on('click', view.onClick);
+ * // => logs 'clicked docs' when clicked
+ */
+ var bindAll = rest(function(object, methodNames) {
+ arrayEach(baseFlatten(methodNames), function(key) {
+ object[key] = bind(object[key], object);
+ });
+ return object;
+ });
+
+ return bindAll;
+});
diff --git a/function/bindKey.js b/bindKey.js
similarity index 84%
rename from function/bindKey.js
rename to bindKey.js
index 71f309e68..79055229d 100644
--- a/function/bindKey.js
+++ b/bindKey.js
@@ -1,4 +1,4 @@
-define(['../internal/createWrapper', '../internal/replaceHolders', './restParam'], function(createWrapper, replaceHolders, restParam) {
+define(['./internal/createWrapper', './internal/replaceHolders', './rest'], function(createWrapper, replaceHolders, rest) {
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -20,7 +20,7 @@ define(['../internal/createWrapper', '../internal/replaceHolders', './restParam'
* @static
* @memberOf _
* @category Function
- * @param {Object} object The object the method belongs to.
+ * @param {Object} object The object to invoke the method on.
* @param {string} key The key of the method.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
@@ -49,7 +49,7 @@ define(['../internal/createWrapper', '../internal/replaceHolders', './restParam'
* bound('hi');
* // => 'hiya fred!'
*/
- var bindKey = restParam(function(object, key, partials) {
+ var bindKey = rest(function(object, key, partials) {
var bitmask = BIND_FLAG | BIND_KEY_FLAG;
if (partials.length) {
var holders = replaceHolders(partials, bindKey.placeholder);
@@ -58,8 +58,5 @@ define(['../internal/createWrapper', '../internal/replaceHolders', './restParam'
return createWrapper(key, bitmask, object, partials, holders);
});
- // Assign default placeholders.
- bindKey.placeholder = {};
-
return bindKey;
});
diff --git a/string/camelCase.js b/camelCase.js
similarity index 78%
rename from string/camelCase.js
rename to camelCase.js
index f3f332ba3..c3bf8bb2e 100644
--- a/string/camelCase.js
+++ b/camelCase.js
@@ -1,4 +1,4 @@
-define(['../internal/createCompounder'], function(createCompounder) {
+define(['./capitalize', './internal/createCompounder'], function(capitalize, createCompounder) {
/**
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
@@ -21,7 +21,7 @@ define(['../internal/createCompounder'], function(createCompounder) {
*/
var camelCase = createCompounder(function(result, word, index) {
word = word.toLowerCase();
- return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);
+ return result + (index ? capitalize(word) : word);
});
return camelCase;
diff --git a/string/capitalize.js b/capitalize.js
similarity index 52%
rename from string/capitalize.js
rename to capitalize.js
index b596baa58..0b0b5f24f 100644
--- a/string/capitalize.js
+++ b/capitalize.js
@@ -1,7 +1,8 @@
-define(['../internal/baseToString'], function(baseToString) {
+define(['./toString', './upperFirst'], function(toString, upperFirst) {
/**
- * Capitalizes the first character of `string`.
+ * Converts the first character of `string` to upper case and the remaining
+ * to lower case.
*
* @static
* @memberOf _
@@ -10,12 +11,11 @@ define(['../internal/baseToString'], function(baseToString) {
* @returns {string} Returns the capitalized string.
* @example
*
- * _.capitalize('fred');
+ * _.capitalize('FRED');
* // => 'Fred'
*/
function capitalize(string) {
- string = baseToString(string);
- return string && (string.charAt(0).toUpperCase() + string.slice(1));
+ return upperFirst(toString(string).toLowerCase());
}
return capitalize;
diff --git a/math/ceil.js b/ceil.js
similarity index 70%
rename from math/ceil.js
rename to ceil.js
index 12063c75d..507342488 100644
--- a/math/ceil.js
+++ b/ceil.js
@@ -1,12 +1,12 @@
-define(['../internal/createRound'], function(createRound) {
+define(['./internal/createRound'], function(createRound) {
/**
- * Calculates `n` rounded up to `precision`.
+ * Computes `number` rounded up to `precision`.
*
* @static
* @memberOf _
* @category Math
- * @param {number} n The number to round up.
+ * @param {number} number The number to round up.
* @param {number} [precision=0] The precision to round up to.
* @returns {number} Returns the rounded up number.
* @example
diff --git a/chain.js b/chain.js
index 35b9ddf0f..465a93051 100644
--- a/chain.js
+++ b/chain.js
@@ -1,18 +1,37 @@
-define(['./chain/chain', './chain/commit', './chain/concat', './chain/lodash', './chain/plant', './chain/reverse', './chain/run', './chain/tap', './chain/thru', './chain/toJSON', './chain/toString', './chain/value', './chain/valueOf', './chain/wrapperChain'], function(chain, commit, concat, lodash, plant, reverse, run, tap, thru, toJSON, toString, value, valueOf, wrapperChain) {
- return {
- 'chain': chain,
- 'commit': commit,
- 'concat': concat,
- 'lodash': lodash,
- 'plant': plant,
- 'reverse': reverse,
- 'run': run,
- 'tap': tap,
- 'thru': thru,
- 'toJSON': toJSON,
- 'toString': toString,
- 'value': value,
- 'valueOf': valueOf,
- 'wrapperChain': wrapperChain
- };
+define(['./wrapperLodash'], function(lodash) {
+
+ /**
+ * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
+ * The result of such method chaining must be unwrapped with `_#value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Seq
+ * @param {*} value The value to wrap.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 },
+ * { 'user': 'pebbles', 'age': 1 }
+ * ];
+ *
+ * var youngest = _
+ * .chain(users)
+ * .sortBy('age')
+ * .map(function(o) {
+ * return o.user + ' is ' + o.age;
+ * })
+ * .head()
+ * .value();
+ * // => 'pebbles is 1'
+ */
+ function chain(value) {
+ var result = lodash(value);
+ result.__chain__ = true;
+ return result;
+ }
+
+ return chain;
});
diff --git a/chain/chain.js b/chain/chain.js
deleted file mode 100644
index 81004d830..000000000
--- a/chain/chain.js
+++ /dev/null
@@ -1,36 +0,0 @@
-define(['./lodash'], function(lodash) {
-
- /**
- * Creates a `lodash` object that wraps `value` with explicit method
- * chaining enabled.
- *
- * @static
- * @memberOf _
- * @category Chain
- * @param {*} value The value to wrap.
- * @returns {Object} Returns the new `lodash` wrapper instance.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 },
- * { 'user': 'pebbles', 'age': 1 }
- * ];
- *
- * var youngest = _.chain(users)
- * .sortBy('age')
- * .map(function(chr) {
- * return chr.user + ' is ' + chr.age;
- * })
- * .first()
- * .value();
- * // => 'pebbles is 1'
- */
- function chain(value) {
- var result = lodash(value);
- result.__chain__ = true;
- return result;
- }
-
- return chain;
-});
diff --git a/chain/commit.js b/chain/commit.js
deleted file mode 100644
index 92946c55b..000000000
--- a/chain/commit.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./wrapperCommit"], function(wrapperCommit) {
- return wrapperCommit;
-});
diff --git a/chain/concat.js b/chain/concat.js
deleted file mode 100644
index da9351896..000000000
--- a/chain/concat.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./wrapperConcat"], function(wrapperConcat) {
- return wrapperConcat;
-});
diff --git a/chain/lodash.js b/chain/lodash.js
deleted file mode 100644
index ab022c957..000000000
--- a/chain/lodash.js
+++ /dev/null
@@ -1,121 +0,0 @@
-define(['../internal/LazyWrapper', '../internal/LodashWrapper', '../internal/baseLodash', '../lang/isArray', '../internal/isObjectLike', '../internal/wrapperClone'], function(LazyWrapper, LodashWrapper, baseLodash, isArray, isObjectLike, wrapperClone) {
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- 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 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 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.
- *
- * In addition to lodash methods, wrappers have `Array` and `String` methods.
- *
- * The wrapper `Array` methods are:
- * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
- * `splice`, and `unshift`
- *
- * The wrapper `String` methods are:
- * `replace` and `split`
- *
- * The wrapper methods that support shortcut fusion are:
- * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
- * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
- * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
- * and `where`
- *
- * 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`, `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`, `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.
- *
- * @name _
- * @constructor
- * @category Chain
- * @param {*} value The value to wrap in a `lodash` instance.
- * @returns {Object} Returns the new `lodash` wrapper instance.
- * @example
- *
- * var wrapped = _([1, 2, 3]);
- *
- * // returns an unwrapped value
- * wrapped.reduce(function(total, n) {
- * return total + n;
- * });
- * // => 6
- *
- * // returns a wrapped value
- * var squares = wrapped.map(function(n) {
- * return n * n;
- * });
- *
- * _.isArray(squares);
- * // => false
- *
- * _.isArray(squares.value());
- * // => true
- */
- function lodash(value) {
- if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
- if (value instanceof LodashWrapper) {
- return value;
- }
- if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
- return wrapperClone(value);
- }
- }
- return new LodashWrapper(value);
- }
-
- // Ensure wrappers are instances of `baseLodash`.
- lodash.prototype = baseLodash.prototype;
-
- return lodash;
-});
diff --git a/chain/plant.js b/chain/plant.js
deleted file mode 100644
index 558325202..000000000
--- a/chain/plant.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./wrapperPlant"], function(wrapperPlant) {
- return wrapperPlant;
-});
diff --git a/chain/reverse.js b/chain/reverse.js
deleted file mode 100644
index f313e40cb..000000000
--- a/chain/reverse.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./wrapperReverse"], function(wrapperReverse) {
- return wrapperReverse;
-});
diff --git a/chain/run.js b/chain/run.js
deleted file mode 100644
index 75df47963..000000000
--- a/chain/run.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./wrapperValue"], function(wrapperValue) {
- return wrapperValue;
-});
diff --git a/chain/toString.js b/chain/toString.js
deleted file mode 100644
index ef325d200..000000000
--- a/chain/toString.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./wrapperToString"], function(wrapperToString) {
- return wrapperToString;
-});
diff --git a/chain/wrapperConcat.js b/chain/wrapperConcat.js
deleted file mode 100644
index 926c7e7b1..000000000
--- a/chain/wrapperConcat.js
+++ /dev/null
@@ -1,31 +0,0 @@
-define(['../internal/arrayConcat', '../internal/baseFlatten', '../lang/isArray', '../function/restParam', '../internal/toObject'], function(arrayConcat, baseFlatten, isArray, restParam, 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);
- });
- });
-
- return wrapperConcat;
-});
diff --git a/chain/wrapperToString.js b/chain/wrapperToString.js
deleted file mode 100644
index 534be5dc6..000000000
--- a/chain/wrapperToString.js
+++ /dev/null
@@ -1,20 +0,0 @@
-define([], function() {
-
- /**
- * Produces the result of coercing the unwrapped value to a string.
- *
- * @name toString
- * @memberOf _
- * @category Chain
- * @returns {string} Returns the coerced string value.
- * @example
- *
- * _([1, 2, 3]).toString();
- * // => '1,2,3'
- */
- function wrapperToString() {
- return (this.value() + '');
- }
-
- return wrapperToString;
-});
diff --git a/array/chunk.js b/chunk.js
similarity index 52%
rename from array/chunk.js
rename to chunk.js
index 1cd503067..5f321c187 100644
--- a/array/chunk.js
+++ b/chunk.js
@@ -1,21 +1,19 @@
-define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSlice, isIterateeCall) {
+define(['./internal/baseSlice', './toInteger'], function(baseSlice, toInteger) {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeCeil = Math.ceil,
- nativeFloor = Math.floor,
nativeMax = Math.max;
/**
* Creates an array of elements split into groups the length of `size`.
- * If `collection` can't be split evenly, the final chunk will be the remaining
+ * If `array` can't be split evenly, the final chunk will be the remaining
* elements.
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to process.
- * @param {number} [size=1] The length of each chunk.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param {number} [size=0] The length of each chunk.
* @returns {Array} Returns the new array containing chunks.
* @example
*
@@ -25,14 +23,14 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
* _.chunk(['a', 'b', 'c', 'd'], 3);
* // => [['a', 'b', 'c'], ['d']]
*/
- function chunk(array, size, guard) {
- if (guard ? isIterateeCall(array, size, guard) : size == null) {
- size = 1;
- } else {
- size = nativeMax(nativeFloor(size) || 1, 1);
+ function chunk(array, size) {
+ size = nativeMax(toInteger(size), 0);
+
+ var length = array ? array.length : 0;
+ if (!length || size < 1) {
+ return [];
}
var index = 0,
- length = array ? array.length : 0,
resIndex = -1,
result = Array(nativeCeil(length / size));
diff --git a/clamp.js b/clamp.js
new file mode 100644
index 000000000..0c1fe7ed3
--- /dev/null
+++ b/clamp.js
@@ -0,0 +1,41 @@
+define(['./internal/baseClamp', './toNumber'], function(baseClamp, toNumber) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Clamps `number` within the inclusive `lower` and `upper` bounds.
+ *
+ * @static
+ * @memberOf _
+ * @category Number
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
+ * @example
+ *
+ * _.clamp(-10, -5, 5);
+ * // => -5
+ *
+ * _.clamp(10, -5, 5);
+ * // => 5
+ */
+ function clamp(number, lower, upper) {
+ if (upper === undefined) {
+ upper = lower;
+ lower = undefined;
+ }
+ if (upper !== undefined) {
+ upper = toNumber(upper);
+ upper = upper === upper ? upper : 0;
+ }
+ if (lower !== undefined) {
+ lower = toNumber(lower);
+ lower = lower === lower ? lower : 0;
+ }
+ return baseClamp(toNumber(number), lower, upper);
+ }
+
+ return clamp;
+});
diff --git a/clone.js b/clone.js
new file mode 100644
index 000000000..91be2203e
--- /dev/null
+++ b/clone.js
@@ -0,0 +1,32 @@
+define(['./internal/baseClone'], function(baseClone) {
+
+ /**
+ * Creates a shallow clone of `value`.
+ *
+ * **Note:** This method is loosely based on the
+ * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
+ * and supports cloning arrays, array buffers, booleans, date objects, maps,
+ * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
+ * arrays. The own enumerable properties of `arguments` objects are cloned
+ * as plain objects. An empty object is returned for uncloneable values such
+ * as error objects, functions, DOM nodes, and WeakMaps.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to clone.
+ * @returns {*} Returns the cloned value.
+ * @example
+ *
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
+ *
+ * var shallow = _.clone(objects);
+ * console.log(shallow[0] === objects[0]);
+ * // => true
+ */
+ function clone(value) {
+ return baseClone(value);
+ }
+
+ return clone;
+});
diff --git a/cloneDeep.js b/cloneDeep.js
new file mode 100644
index 000000000..2048c109b
--- /dev/null
+++ b/cloneDeep.js
@@ -0,0 +1,24 @@
+define(['./internal/baseClone'], function(baseClone) {
+
+ /**
+ * This method is like `_.clone` except that it recursively clones `value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to recursively clone.
+ * @returns {*} Returns the deep cloned value.
+ * @example
+ *
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
+ *
+ * var deep = _.cloneDeep(objects);
+ * console.log(deep[0] === objects[0]);
+ * // => false
+ */
+ function cloneDeep(value) {
+ return baseClone(value, true);
+ }
+
+ return cloneDeep;
+});
diff --git a/cloneDeepWith.js b/cloneDeepWith.js
new file mode 100644
index 000000000..2353e976e
--- /dev/null
+++ b/cloneDeepWith.js
@@ -0,0 +1,34 @@
+define(['./internal/baseClone'], function(baseClone) {
+
+ /**
+ * This method is like `_.cloneWith` except that it recursively clones `value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to recursively clone.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @returns {*} Returns the deep cloned value.
+ * @example
+ *
+ * function customizer(value) {
+ * if (_.isElement(value)) {
+ * return value.cloneNode(true);
+ * }
+ * }
+ *
+ * var el = _.cloneDeep(document.body, customizer);
+ *
+ * console.log(el === document.body);
+ * // => false
+ * console.log(el.nodeName);
+ * // => 'BODY'
+ * console.log(el.childNodes.length);
+ * // => 20
+ */
+ function cloneDeepWith(value, customizer) {
+ return baseClone(value, true, customizer);
+ }
+
+ return cloneDeepWith;
+});
diff --git a/cloneWith.js b/cloneWith.js
new file mode 100644
index 000000000..81eb832fe
--- /dev/null
+++ b/cloneWith.js
@@ -0,0 +1,37 @@
+define(['./internal/baseClone'], function(baseClone) {
+
+ /**
+ * This method is like `_.clone` except that it accepts `customizer` which
+ * is invoked to produce the cloned value. If `customizer` returns `undefined`
+ * cloning is handled by the method instead. The `customizer` is invoked with
+ * up to five arguments; (value [, index|key, object, stack]).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to clone.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @returns {*} Returns the cloned value.
+ * @example
+ *
+ * function customizer(value) {
+ * if (_.isElement(value)) {
+ * return value.cloneNode(false);
+ * }
+ * }
+ *
+ * var el = _.clone(document.body, customizer);
+ *
+ * console.log(el === document.body);
+ * // => false
+ * console.log(el.nodeName);
+ * // => 'BODY'
+ * console.log(el.childNodes.length);
+ * // => 0
+ */
+ function cloneWith(value, customizer) {
+ return baseClone(value, false, customizer);
+ }
+
+ return cloneWith;
+});
diff --git a/collection.js b/collection.js
index 13b531f27..fbbf5cfdf 100644
--- a/collection.js
+++ b/collection.js
@@ -1,46 +1,30 @@
-define(['./collection/all', './collection/any', './collection/at', './collection/collect', './collection/contains', './collection/countBy', './collection/detect', './collection/each', './collection/eachRight', './collection/every', './collection/filter', './collection/find', './collection/findLast', './collection/findWhere', './collection/foldl', './collection/foldr', './collection/forEach', './collection/forEachRight', './collection/groupBy', './collection/include', './collection/includes', './collection/indexBy', './collection/inject', './collection/invoke', './collection/map', './math/max', './math/min', './collection/partition', './collection/pluck', './collection/reduce', './collection/reduceRight', './collection/reject', './collection/sample', './collection/select', './collection/shuffle', './collection/size', './collection/some', './collection/sortBy', './collection/sortByAll', './collection/sortByOrder', './math/sum', './collection/where'], function(all, any, at, collect, contains, countBy, detect, each, eachRight, every, filter, find, findLast, findWhere, foldl, foldr, forEach, forEachRight, groupBy, include, includes, indexBy, inject, invoke, map, max, min, partition, pluck, reduce, reduceRight, reject, sample, select, shuffle, size, some, sortBy, sortByAll, sortByOrder, sum, where) {
+define(['./at', './countBy', './each', './eachRight', './every', './filter', './find', './findLast', './forEach', './forEachRight', './groupBy', './includes', './invokeMap', './keyBy', './map', './orderBy', './partition', './reduce', './reduceRight', './reject', './sample', './sampleSize', './shuffle', './size', './some', './sortBy'], function(at, countBy, each, eachRight, every, filter, find, findLast, forEach, forEachRight, groupBy, includes, invokeMap, keyBy, map, orderBy, partition, reduce, reduceRight, reject, sample, sampleSize, shuffle, size, some, sortBy) {
return {
- 'all': all,
- 'any': any,
'at': at,
- 'collect': collect,
- 'contains': contains,
'countBy': countBy,
- 'detect': detect,
'each': each,
'eachRight': eachRight,
'every': every,
'filter': filter,
'find': find,
'findLast': findLast,
- 'findWhere': findWhere,
- 'foldl': foldl,
- 'foldr': foldr,
'forEach': forEach,
'forEachRight': forEachRight,
'groupBy': groupBy,
- 'include': include,
'includes': includes,
- 'indexBy': indexBy,
- 'inject': inject,
- 'invoke': invoke,
+ 'invokeMap': invokeMap,
+ 'keyBy': keyBy,
'map': map,
- 'max': max,
- 'min': min,
+ 'orderBy': orderBy,
'partition': partition,
- 'pluck': pluck,
'reduce': reduce,
'reduceRight': reduceRight,
'reject': reject,
'sample': sample,
- 'select': select,
+ 'sampleSize': sampleSize,
'shuffle': shuffle,
'size': size,
'some': some,
- 'sortBy': sortBy,
- 'sortByAll': sortByAll,
- 'sortByOrder': sortByOrder,
- 'sum': sum,
- 'where': where
+ 'sortBy': sortBy
};
});
diff --git a/collection/all.js b/collection/all.js
deleted file mode 100644
index b3029db1f..000000000
--- a/collection/all.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./every"], function(every) {
- return every;
-});
diff --git a/collection/any.js b/collection/any.js
deleted file mode 100644
index 8606b482f..000000000
--- a/collection/any.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./some"], function(some) {
- return some;
-});
diff --git a/collection/at.js b/collection/at.js
deleted file mode 100644
index 1c4215bd0..000000000
--- a/collection/at.js
+++ /dev/null
@@ -1,28 +0,0 @@
-define(['../internal/baseAt', '../internal/baseFlatten', '../function/restParam'], function(baseAt, baseFlatten, restParam) {
-
- /**
- * Creates an array of elements corresponding to the given keys, or indexes,
- * of `collection`. Keys may be specified as individual arguments or as arrays
- * of keys.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(number|number[]|string|string[])} [props] The property names
- * or indexes of elements to pick, specified individually or in arrays.
- * @returns {Array} Returns the new array of picked elements.
- * @example
- *
- * _.at(['a', 'b', 'c'], [0, 2]);
- * // => ['a', 'c']
- *
- * _.at(['barney', 'fred', 'pebbles'], 0, 2);
- * // => ['barney', 'pebbles']
- */
- var at = restParam(function(collection, props) {
- return baseAt(collection, baseFlatten(props));
- });
-
- return at;
-});
diff --git a/collection/collect.js b/collection/collect.js
deleted file mode 100644
index 219bc52ac..000000000
--- a/collection/collect.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./map"], function(map) {
- return map;
-});
diff --git a/collection/contains.js b/collection/contains.js
deleted file mode 100644
index 3dd2fb11b..000000000
--- a/collection/contains.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./includes"], function(includes) {
- return includes;
-});
diff --git a/collection/countBy.js b/collection/countBy.js
deleted file mode 100644
index 7bf87281f..000000000
--- a/collection/countBy.js
+++ /dev/null
@@ -1,55 +0,0 @@
-define(['../internal/createAggregator'], function(createAggregator) {
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty = objectProto.hasOwnProperty;
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through `iteratee`. The corresponding value
- * of each key is the number of times the key was returned by `iteratee`.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.countBy([4.3, 6.1, 6.4], function(n) {
- * return Math.floor(n);
- * });
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy([4.3, 6.1, 6.4], function(n) {
- * return this.floor(n);
- * }, Math);
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy(['one', 'two', 'three'], 'length');
- * // => { '3': 2, '5': 1 }
- */
- var countBy = createAggregator(function(result, value, key) {
- hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
- });
-
- return countBy;
-});
diff --git a/collection/detect.js b/collection/detect.js
deleted file mode 100644
index 2a8cb1c45..000000000
--- a/collection/detect.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./find"], function(find) {
- return find;
-});
diff --git a/collection/every.js b/collection/every.js
deleted file mode 100644
index 11eb21281..000000000
--- a/collection/every.js
+++ /dev/null
@@ -1,66 +0,0 @@
-define(['../internal/arrayEvery', '../internal/baseCallback', '../internal/baseEvery', '../lang/isArray', '../internal/isIterateeCall'], function(arrayEvery, baseCallback, baseEvery, isArray, isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Checks if `predicate` returns truthy for **all** elements of `collection`.
- * The predicate is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @alias all
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`.
- * @example
- *
- * _.every([true, 1, null, 'yes'], Boolean);
- * // => false
- *
- * var users = [
- * { 'user': 'barney', 'active': false },
- * { 'user': 'fred', 'active': false }
- * ];
- *
- * // using the `_.matches` callback shorthand
- * _.every(users, { 'user': 'barney', 'active': false });
- * // => false
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.every(users, 'active', false);
- * // => true
- *
- * // using the `_.property` callback shorthand
- * _.every(users, 'active');
- * // => false
- */
- function every(collection, predicate, thisArg) {
- var func = isArray(collection) ? arrayEvery : baseEvery;
- if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
- predicate = undefined;
- }
- if (typeof predicate != 'function' || thisArg !== undefined) {
- predicate = baseCallback(predicate, thisArg, 3);
- }
- return func(collection, predicate);
- }
-
- return every;
-});
diff --git a/collection/filter.js b/collection/filter.js
deleted file mode 100644
index 1c66ae8a5..000000000
--- a/collection/filter.js
+++ /dev/null
@@ -1,59 +0,0 @@
-define(['../internal/arrayFilter', '../internal/baseCallback', '../internal/baseFilter', '../lang/isArray'], function(arrayFilter, baseCallback, baseFilter, isArray) {
-
- /**
- * Iterates over elements of `collection`, returning an array of all elements
- * `predicate` returns truthy for. The predicate is bound to `thisArg` and
- * invoked with three arguments: (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @alias select
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Array} Returns the new filtered array.
- * @example
- *
- * _.filter([4, 5, 6], function(n) {
- * return n % 2 == 0;
- * });
- * // => [4, 6]
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': true },
- * { 'user': 'fred', 'age': 40, 'active': false }
- * ];
- *
- * // using the `_.matches` callback shorthand
- * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user');
- * // => ['barney']
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.filter(users, 'active', false), 'user');
- * // => ['fred']
- *
- * // using the `_.property` callback shorthand
- * _.pluck(_.filter(users, 'active'), 'user');
- * // => ['barney']
- */
- function filter(collection, predicate, thisArg) {
- var func = isArray(collection) ? arrayFilter : baseFilter;
- predicate = baseCallback(predicate, thisArg, 3);
- return func(collection, predicate);
- }
-
- return filter;
-});
diff --git a/collection/find.js b/collection/find.js
deleted file mode 100644
index 1da1d77c7..000000000
--- a/collection/find.js
+++ /dev/null
@@ -1,56 +0,0 @@
-define(['../internal/baseEach', '../internal/createFind'], function(baseEach, createFind) {
-
- /**
- * Iterates over elements of `collection`, returning the first element
- * `predicate` returns truthy for. The predicate is bound to `thisArg` and
- * invoked with three arguments: (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @alias detect
- * @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {*} Returns the matched element, else `undefined`.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': true },
- * { 'user': 'fred', 'age': 40, 'active': false },
- * { 'user': 'pebbles', 'age': 1, 'active': true }
- * ];
- *
- * _.result(_.find(users, function(chr) {
- * return chr.age < 40;
- * }), 'user');
- * // => 'barney'
- *
- * // using the `_.matches` callback shorthand
- * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');
- * // => 'pebbles'
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.result(_.find(users, 'active', false), 'user');
- * // => 'fred'
- *
- * // using the `_.property` callback shorthand
- * _.result(_.find(users, 'active'), 'user');
- * // => 'barney'
- */
- var find = createFind(baseEach);
-
- return find;
-});
diff --git a/collection/findLast.js b/collection/findLast.js
deleted file mode 100644
index 2843eda55..000000000
--- a/collection/findLast.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define(['../internal/baseEachRight', '../internal/createFind'], function(baseEachRight, createFind) {
-
- /**
- * This method is like `_.find` except that it iterates over elements of
- * `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {*} Returns the matched element, else `undefined`.
- * @example
- *
- * _.findLast([1, 2, 3, 4], function(n) {
- * return n % 2 == 1;
- * });
- * // => 3
- */
- var findLast = createFind(baseEachRight, true);
-
- return findLast;
-});
diff --git a/collection/findWhere.js b/collection/findWhere.js
deleted file mode 100644
index 0b4e41f1f..000000000
--- a/collection/findWhere.js
+++ /dev/null
@@ -1,37 +0,0 @@
-define(['../internal/baseMatches', './find'], function(baseMatches, find) {
-
- /**
- * Performs a deep comparison between each element in `collection` and the
- * source object, returning the first element that has equivalent property
- * values.
- *
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties. For comparing a single
- * own or inherited property value see `_.matchesProperty`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {Object} source The object of property values to match.
- * @returns {*} Returns the matched element, else `undefined`.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': true },
- * { 'user': 'fred', 'age': 40, 'active': false }
- * ];
- *
- * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user');
- * // => 'barney'
- *
- * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user');
- * // => 'fred'
- */
- function findWhere(collection, source) {
- return find(collection, baseMatches(source));
- }
-
- return findWhere;
-});
diff --git a/collection/foldl.js b/collection/foldl.js
deleted file mode 100644
index b88106b84..000000000
--- a/collection/foldl.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./reduce"], function(reduce) {
- return reduce;
-});
diff --git a/collection/foldr.js b/collection/foldr.js
deleted file mode 100644
index d57e83fc7..000000000
--- a/collection/foldr.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./reduceRight"], function(reduceRight) {
- return reduceRight;
-});
diff --git a/collection/forEach.js b/collection/forEach.js
deleted file mode 100644
index 5c44cca5a..000000000
--- a/collection/forEach.js
+++ /dev/null
@@ -1,36 +0,0 @@
-define(['../internal/arrayEach', '../internal/baseEach', '../internal/createForEach'], function(arrayEach, baseEach, createForEach) {
-
- /**
- * Iterates over elements of `collection` invoking `iteratee` for each element.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection). Iteratee functions may exit iteration early
- * by explicitly returning `false`.
- *
- * **Note:** As with other "Collections" methods, objects with a "length" property
- * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
- * may be used for object iteration.
- *
- * @static
- * @memberOf _
- * @alias each
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2]).forEach(function(n) {
- * console.log(n);
- * }).value();
- * // => logs each value from left to right and returns the array
- *
- * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
- * console.log(n, key);
- * });
- * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
- */
- var forEach = createForEach(arrayEach, baseEach);
-
- return forEach;
-});
diff --git a/collection/forEachRight.js b/collection/forEachRight.js
deleted file mode 100644
index 77e594416..000000000
--- a/collection/forEachRight.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define(['../internal/arrayEachRight', '../internal/baseEachRight', '../internal/createForEach'], function(arrayEachRight, baseEachRight, createForEach) {
-
- /**
- * This method is like `_.forEach` except that it iterates over elements of
- * `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias eachRight
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2]).forEachRight(function(n) {
- * console.log(n);
- * }).value();
- * // => logs each value from right to left and returns the array
- */
- var forEachRight = createForEach(arrayEachRight, baseEachRight);
-
- return forEachRight;
-});
diff --git a/collection/groupBy.js b/collection/groupBy.js
deleted file mode 100644
index 1480304a4..000000000
--- a/collection/groupBy.js
+++ /dev/null
@@ -1,60 +0,0 @@
-define(['../internal/createAggregator'], function(createAggregator) {
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty = objectProto.hasOwnProperty;
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through `iteratee`. The corresponding value
- * of each key is an array of the elements responsible for generating the key.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.groupBy([4.2, 6.1, 6.4], function(n) {
- * return Math.floor(n);
- * });
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * _.groupBy([4.2, 6.1, 6.4], function(n) {
- * return this.floor(n);
- * }, Math);
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * // using the `_.property` callback shorthand
- * _.groupBy(['one', 'two', 'three'], 'length');
- * // => { '3': ['one', 'two'], '5': ['three'] }
- */
- var groupBy = createAggregator(function(result, value, key) {
- if (hasOwnProperty.call(result, key)) {
- result[key].push(value);
- } else {
- result[key] = [value];
- }
- });
-
- return groupBy;
-});
diff --git a/collection/include.js b/collection/include.js
deleted file mode 100644
index 3dd2fb11b..000000000
--- a/collection/include.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./includes"], function(includes) {
- return includes;
-});
diff --git a/collection/includes.js b/collection/includes.js
deleted file mode 100644
index 45adb83c7..000000000
--- a/collection/includes.js
+++ /dev/null
@@ -1,52 +0,0 @@
-define(['../internal/baseIndexOf', '../internal/getLength', '../lang/isArray', '../internal/isIterateeCall', '../internal/isLength', '../lang/isString', '../object/values'], function(baseIndexOf, getLength, isArray, isIterateeCall, isLength, isString, values) {
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeMax = Math.max;
-
- /**
- * Checks if `target` is in `collection` using
- * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons. If `fromIndex` is negative, it's used as the offset
- * from the end of `collection`.
- *
- * @static
- * @memberOf _
- * @alias contains, include
- * @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {*} target The value to search for.
- * @param {number} [fromIndex=0] The index to search from.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
- * @returns {boolean} Returns `true` if a matching element is found, else `false`.
- * @example
- *
- * _.includes([1, 2, 3], 1);
- * // => true
- *
- * _.includes([1, 2, 3], 1, 2);
- * // => false
- *
- * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
- * // => true
- *
- * _.includes('pebbles', 'eb');
- * // => true
- */
- function includes(collection, target, fromIndex, guard) {
- var length = collection ? getLength(collection) : 0;
- if (!isLength(length)) {
- collection = values(collection);
- length = collection.length;
- }
- 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)
- : (!!length && baseIndexOf(collection, target, fromIndex) > -1);
- }
-
- return includes;
-});
diff --git a/collection/indexBy.js b/collection/indexBy.js
deleted file mode 100644
index 07200fafa..000000000
--- a/collection/indexBy.js
+++ /dev/null
@@ -1,54 +0,0 @@
-define(['../internal/createAggregator'], function(createAggregator) {
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through `iteratee`. The corresponding value
- * of each key is the last element responsible for generating the key. The
- * iteratee function is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * var keyData = [
- * { 'dir': 'left', 'code': 97 },
- * { 'dir': 'right', 'code': 100 }
- * ];
- *
- * _.indexBy(keyData, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(keyData, function(object) {
- * return String.fromCharCode(object.code);
- * });
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(keyData, function(object) {
- * return this.fromCharCode(object.code);
- * }, String);
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- */
- var indexBy = createAggregator(function(result, value, key) {
- result[key] = value;
- });
-
- return indexBy;
-});
diff --git a/collection/inject.js b/collection/inject.js
deleted file mode 100644
index b88106b84..000000000
--- a/collection/inject.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./reduce"], function(reduce) {
- return reduce;
-});
diff --git a/collection/map.js b/collection/map.js
deleted file mode 100644
index 330524b68..000000000
--- a/collection/map.js
+++ /dev/null
@@ -1,66 +0,0 @@
-define(['../internal/arrayMap', '../internal/baseCallback', '../internal/baseMap', '../lang/isArray'], function(arrayMap, baseCallback, baseMap, isArray) {
-
- /**
- * Creates an array of values by running each element in `collection` through
- * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * Many lodash methods are guarded to work as iteratees for methods like
- * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
- *
- * The guarded methods are:
- * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
- * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
- * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
- * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
- * `sum`, `uniq`, and `words`
- *
- * @static
- * @memberOf _
- * @alias collect
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the new mapped array.
- * @example
- *
- * function timesThree(n) {
- * return n * 3;
- * }
- *
- * _.map([1, 2], timesThree);
- * // => [3, 6]
- *
- * _.map({ 'a': 1, 'b': 2 }, timesThree);
- * // => [3, 6] (iteration order is not guaranteed)
- *
- * var users = [
- * { 'user': 'barney' },
- * { 'user': 'fred' }
- * ];
- *
- * // using the `_.property` callback shorthand
- * _.map(users, 'user');
- * // => ['barney', 'fred']
- */
- function map(collection, iteratee, thisArg) {
- var func = isArray(collection) ? arrayMap : baseMap;
- iteratee = baseCallback(iteratee, thisArg, 3);
- return func(collection, iteratee);
- }
-
- return map;
-});
diff --git a/collection/max.js b/collection/max.js
deleted file mode 100644
index b109ef0ee..000000000
--- a/collection/max.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["../math/max"], function(max) {
- return max;
-});
diff --git a/collection/min.js b/collection/min.js
deleted file mode 100644
index 6c9b4faa2..000000000
--- a/collection/min.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["../math/min"], function(min) {
- return min;
-});
diff --git a/collection/partition.js b/collection/partition.js
deleted file mode 100644
index 0315c25fb..000000000
--- a/collection/partition.js
+++ /dev/null
@@ -1,67 +0,0 @@
-define(['../internal/createAggregator'], function(createAggregator) {
-
- /**
- * Creates an array of elements split into two groups, the first of which
- * contains elements `predicate` returns truthy for, while the second of which
- * contains elements `predicate` returns falsey for. The predicate is bound
- * to `thisArg` and invoked with three arguments: (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Array} Returns the array of grouped elements.
- * @example
- *
- * _.partition([1, 2, 3], function(n) {
- * return n % 2;
- * });
- * // => [[1, 3], [2]]
- *
- * _.partition([1.2, 2.3, 3.4], function(n) {
- * return this.floor(n) % 2;
- * }, Math);
- * // => [[1.2, 3.4], [2.3]]
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': false },
- * { 'user': 'fred', 'age': 40, 'active': true },
- * { 'user': 'pebbles', 'age': 1, 'active': false }
- * ];
- *
- * var mapper = function(array) {
- * return _.pluck(array, 'user');
- * };
- *
- * // using the `_.matches` callback shorthand
- * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper);
- * // => [['pebbles'], ['barney', 'fred']]
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.map(_.partition(users, 'active', false), mapper);
- * // => [['barney', 'pebbles'], ['fred']]
- *
- * // using the `_.property` callback shorthand
- * _.map(_.partition(users, 'active'), mapper);
- * // => [['fred'], ['barney', 'pebbles']]
- */
- var partition = createAggregator(function(result, value, key) {
- result[key ? 0 : 1].push(value);
- }, function() { return [[], []]; });
-
- return partition;
-});
diff --git a/collection/pluck.js b/collection/pluck.js
deleted file mode 100644
index bcad0dcc2..000000000
--- a/collection/pluck.js
+++ /dev/null
@@ -1,31 +0,0 @@
-define(['./map', '../utility/property'], function(map, property) {
-
- /**
- * Gets the property value of `path` from all elements in `collection`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Array|string} path The path of the property to pluck.
- * @returns {Array} Returns the property values.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 }
- * ];
- *
- * _.pluck(users, 'user');
- * // => ['barney', 'fred']
- *
- * var userIndex = _.indexBy(users, 'user');
- * _.pluck(userIndex, 'age');
- * // => [36, 40] (iteration order is not guaranteed)
- */
- function pluck(collection, path) {
- return map(collection, property(path));
- }
-
- return pluck;
-});
diff --git a/collection/reject.js b/collection/reject.js
deleted file mode 100644
index e94a1996c..000000000
--- a/collection/reject.js
+++ /dev/null
@@ -1,48 +0,0 @@
-define(['../internal/arrayFilter', '../internal/baseCallback', '../internal/baseFilter', '../lang/isArray'], function(arrayFilter, baseCallback, baseFilter, isArray) {
-
- /**
- * The opposite of `_.filter`; this method returns the elements of `collection`
- * that `predicate` does **not** return truthy for.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Array} Returns the new filtered array.
- * @example
- *
- * _.reject([1, 2, 3, 4], function(n) {
- * return n % 2 == 0;
- * });
- * // => [1, 3]
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': false },
- * { 'user': 'fred', 'age': 40, 'active': true }
- * ];
- *
- * // using the `_.matches` callback shorthand
- * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user');
- * // => ['barney']
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.reject(users, 'active', false), 'user');
- * // => ['fred']
- *
- * // using the `_.property` callback shorthand
- * _.pluck(_.reject(users, 'active'), 'user');
- * // => ['barney']
- */
- function reject(collection, predicate, thisArg) {
- var func = isArray(collection) ? arrayFilter : baseFilter;
- predicate = baseCallback(predicate, thisArg, 3);
- return func(collection, function(value, index, collection) {
- return !predicate(value, index, collection);
- });
- }
-
- return reject;
-});
diff --git a/collection/sample.js b/collection/sample.js
deleted file mode 100644
index 50cab799b..000000000
--- a/collection/sample.js
+++ /dev/null
@@ -1,51 +0,0 @@
-define(['../internal/baseRandom', '../internal/isIterateeCall', '../lang/toArray', '../internal/toIterable'], function(baseRandom, isIterateeCall, toArray, toIterable) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeMin = Math.min;
-
- /**
- * Gets a random element or `n` random elements from a collection.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to sample.
- * @param {number} [n] The number of elements to sample.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {*} Returns the random sample(s).
- * @example
- *
- * _.sample([1, 2, 3, 4]);
- * // => 2
- *
- * _.sample([1, 2, 3, 4], 2);
- * // => [3, 1]
- */
- function sample(collection, n, guard) {
- if (guard ? isIterateeCall(collection, n, guard) : n == null) {
- collection = toIterable(collection);
- var length = collection.length;
- return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;
- }
- var index = -1,
- result = toArray(collection),
- length = result.length,
- lastIndex = length - 1;
-
- n = nativeMin(n < 0 ? 0 : (+n || 0), length);
- while (++index < n) {
- var rand = baseRandom(index, lastIndex),
- value = result[rand];
-
- result[rand] = result[index];
- result[index] = value;
- }
- result.length = n;
- return result;
- }
-
- return sample;
-});
diff --git a/collection/select.js b/collection/select.js
deleted file mode 100644
index 6e5fcb858..000000000
--- a/collection/select.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./filter"], function(filter) {
- return filter;
-});
diff --git a/collection/size.js b/collection/size.js
deleted file mode 100644
index c614e27d7..000000000
--- a/collection/size.js
+++ /dev/null
@@ -1,29 +0,0 @@
-define(['../internal/getLength', '../internal/isLength', '../object/keys'], function(getLength, isLength, keys) {
-
- /**
- * Gets the size of `collection` by returning its length for array-like
- * values or the number of own enumerable properties for objects.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to inspect.
- * @returns {number} Returns the size of `collection`.
- * @example
- *
- * _.size([1, 2, 3]);
- * // => 3
- *
- * _.size({ 'a': 1, 'b': 2 });
- * // => 2
- *
- * _.size('pebbles');
- * // => 7
- */
- function size(collection) {
- var length = collection ? getLength(collection) : 0;
- return isLength(length) ? length : keys(collection).length;
- }
-
- return size;
-});
diff --git a/collection/some.js b/collection/some.js
deleted file mode 100644
index f240f3cfa..000000000
--- a/collection/some.js
+++ /dev/null
@@ -1,67 +0,0 @@
-define(['../internal/arraySome', '../internal/baseCallback', '../internal/baseSome', '../lang/isArray', '../internal/isIterateeCall'], function(arraySome, baseCallback, baseSome, isArray, isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Checks if `predicate` returns truthy for **any** element of `collection`.
- * The function returns as soon as it finds a passing value and does not iterate
- * over the entire collection. The predicate is bound to `thisArg` and invoked
- * with three arguments: (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @alias any
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
- * @example
- *
- * _.some([null, 0, 'yes', false], Boolean);
- * // => true
- *
- * var users = [
- * { 'user': 'barney', 'active': true },
- * { 'user': 'fred', 'active': false }
- * ];
- *
- * // using the `_.matches` callback shorthand
- * _.some(users, { 'user': 'barney', 'active': false });
- * // => false
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.some(users, 'active', false);
- * // => true
- *
- * // using the `_.property` callback shorthand
- * _.some(users, 'active');
- * // => true
- */
- function some(collection, predicate, thisArg) {
- var func = isArray(collection) ? arraySome : baseSome;
- if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
- predicate = undefined;
- }
- if (typeof predicate != 'function' || thisArg !== undefined) {
- predicate = baseCallback(predicate, thisArg, 3);
- }
- return func(collection, predicate);
- }
-
- return some;
-});
diff --git a/collection/sortBy.js b/collection/sortBy.js
deleted file mode 100644
index c312c83be..000000000
--- a/collection/sortBy.js
+++ /dev/null
@@ -1,71 +0,0 @@
-define(['../internal/baseCallback', '../internal/baseMap', '../internal/baseSortBy', '../internal/compareAscending', '../internal/isIterateeCall'], function(baseCallback, baseMap, baseSortBy, compareAscending, isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates an array of elements, sorted in ascending order by the results of
- * running each element in a collection through `iteratee`. This method performs
- * a stable sort, that is, it preserves the original sort order of equal elements.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the new sorted array.
- * @example
- *
- * _.sortBy([1, 2, 3], function(n) {
- * return Math.sin(n);
- * });
- * // => [3, 1, 2]
- *
- * _.sortBy([1, 2, 3], function(n) {
- * return this.sin(n);
- * }, Math);
- * // => [3, 1, 2]
- *
- * var users = [
- * { 'user': 'fred' },
- * { 'user': 'pebbles' },
- * { 'user': 'barney' }
- * ];
- *
- * // using the `_.property` callback shorthand
- * _.pluck(_.sortBy(users, 'user'), 'user');
- * // => ['barney', 'fred', 'pebbles']
- */
- function sortBy(collection, iteratee, thisArg) {
- if (collection == null) {
- return [];
- }
- if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = undefined;
- }
- var index = -1;
- iteratee = baseCallback(iteratee, thisArg, 3);
-
- var result = baseMap(collection, function(value, key, collection) {
- return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value };
- });
- return baseSortBy(result, compareAscending);
- }
-
- return sortBy;
-});
diff --git a/collection/sortByAll.js b/collection/sortByAll.js
deleted file mode 100644
index 1184b98ef..000000000
--- a/collection/sortByAll.js
+++ /dev/null
@@ -1,50 +0,0 @@
-define(['../internal/baseFlatten', '../internal/baseSortByOrder', '../internal/isIterateeCall', '../function/restParam'], function(baseFlatten, baseSortByOrder, isIterateeCall, restParam) {
-
- /**
- * This method is like `_.sortBy` except that it can sort by multiple iteratees
- * or property names.
- *
- * If a property name is provided for an iteratee the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If an object is provided for an iteratee the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees
- * The iteratees to sort by, specified as individual values or arrays of values.
- * @returns {Array} Returns the new sorted array.
- * @example
- *
- * var users = [
- * { 'user': 'fred', 'age': 48 },
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 42 },
- * { 'user': 'barney', 'age': 34 }
- * ];
- *
- * _.map(_.sortByAll(users, ['user', 'age']), _.values);
- * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
- *
- * _.map(_.sortByAll(users, 'user', function(chr) {
- * return Math.floor(chr.age / 10);
- * }), _.values);
- * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
- */
- var sortByAll = restParam(function(collection, iteratees) {
- if (collection == null) {
- return [];
- }
- var guard = iteratees[2];
- if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) {
- iteratees.length = 1;
- }
- return baseSortByOrder(collection, baseFlatten(iteratees), []);
- });
-
- return sortByAll;
-});
diff --git a/collection/sortByOrder.js b/collection/sortByOrder.js
deleted file mode 100644
index cdaafc0cb..000000000
--- a/collection/sortByOrder.js
+++ /dev/null
@@ -1,57 +0,0 @@
-define(['../internal/baseSortByOrder', '../lang/isArray', '../internal/isIterateeCall'], function(baseSortByOrder, isArray, isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * This method is like `_.sortByAll` except that it allows specifying the
- * 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.
- *
- * If an object is provided for an iteratee the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @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- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
- * @returns {Array} Returns the new sorted array.
- * @example
- *
- * var users = [
- * { 'user': 'fred', 'age': 48 },
- * { 'user': 'barney', 'age': 34 },
- * { 'user': 'fred', 'age': 42 },
- * { 'user': 'barney', 'age': 36 }
- * ];
- *
- * // sort by `user` in ascending order and by `age` in descending order
- * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values);
- * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
- */
- function sortByOrder(collection, iteratees, orders, guard) {
- if (collection == null) {
- return [];
- }
- if (guard && isIterateeCall(iteratees, orders, guard)) {
- orders = undefined;
- }
- if (!isArray(iteratees)) {
- iteratees = iteratees == null ? [] : [iteratees];
- }
- if (!isArray(orders)) {
- orders = orders == null ? [] : [orders];
- }
- return baseSortByOrder(collection, iteratees, orders);
- }
-
- return sortByOrder;
-});
diff --git a/collection/sum.js b/collection/sum.js
deleted file mode 100644
index 9f45380b9..000000000
--- a/collection/sum.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["../math/sum"], function(sum) {
- return sum;
-});
diff --git a/collection/where.js b/collection/where.js
deleted file mode 100644
index 154fd159c..000000000
--- a/collection/where.js
+++ /dev/null
@@ -1,37 +0,0 @@
-define(['../internal/baseMatches', './filter'], function(baseMatches, filter) {
-
- /**
- * Performs a deep comparison between each element in `collection` and the
- * source object, returning an array of all elements that have equivalent
- * property values.
- *
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties. For comparing a single
- * own or inherited property value see `_.matchesProperty`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {Object} source The object of property values to match.
- * @returns {Array} Returns the new filtered array.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] },
- * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user');
- * // => ['barney']
- *
- * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user');
- * // => ['fred']
- */
- function where(collection, source) {
- return filter(collection, baseMatches(source));
- }
-
- return where;
-});
diff --git a/chain/wrapperCommit.js b/commit.js
similarity index 87%
rename from chain/wrapperCommit.js
rename to commit.js
index 576ec1c30..f8f082c98 100644
--- a/chain/wrapperCommit.js
+++ b/commit.js
@@ -1,11 +1,11 @@
-define(['../internal/LodashWrapper'], function(LodashWrapper) {
+define(['./internal/LodashWrapper'], function(LodashWrapper) {
/**
* Executes the chained sequence and returns the wrapped result.
*
* @name commit
* @memberOf _
- * @category Chain
+ * @category Seq
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
diff --git a/array/compact.js b/compact.js
similarity index 100%
rename from array/compact.js
rename to compact.js
diff --git a/concat.js b/concat.js
new file mode 100644
index 000000000..ee9d66216
--- /dev/null
+++ b/concat.js
@@ -0,0 +1,30 @@
+define(['./internal/arrayConcat', './internal/baseFlatten', './isArray', './rest'], function(arrayConcat, baseFlatten, isArray, rest) {
+
+ /**
+ * Creates a new array concatenating `array` with any additional arrays
+ * and/or values.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to concatenate.
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var other = _.concat(array, 2, [3], [[4]]);
+ *
+ * console.log(other);
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */
+ var concat = rest(function(array, values) {
+ values = baseFlatten(values);
+ return arrayConcat(isArray(array) ? array : [Object(array)], values);
+ });
+
+ return concat;
+});
diff --git a/cond.js b/cond.js
new file mode 100644
index 000000000..0b8aebca1
--- /dev/null
+++ b/cond.js
@@ -0,0 +1,56 @@
+define(['./internal/apply', './internal/arrayMap', './internal/baseIteratee', './rest'], function(apply, arrayMap, baseIteratee, rest) {
+
+ /** Used as the `TypeError` message for "Functions" methods. */
+ var FUNC_ERROR_TEXT = 'Expected a function';
+
+ /**
+ * Creates a function that iterates over `pairs` invoking the corresponding
+ * function of the first predicate to return truthy. The predicate-function
+ * pairs are invoked with the `this` binding and arguments of the created
+ * function.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Array} pairs The predicate-function pairs.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.cond([
+ * [_.matches({ 'a': 1 }), _.constant('matches A')],
+ * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
+ * [_.constant(true), _.constant('no match')]
+ * ])
+ *
+ * func({ 'a': 1, 'b': 2 });
+ * // => 'matches A'
+ *
+ * func({ 'a': 0, 'b': 1 });
+ * // => 'matches B'
+ *
+ * func({ 'a': '1', 'b': '2' });
+ * // => 'no match'
+ */
+ function cond(pairs) {
+ var length = pairs ? pairs.length : 0;
+
+ pairs = !length ? [] : arrayMap(pairs, function(pair) {
+ if (typeof pair[1] != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ return [baseIteratee(pair[0]), pair[1]];
+ });
+
+ return rest(function(args) {
+ var index = -1;
+ while (++index < length) {
+ var pair = pairs[index];
+ if (apply(pair[0], this, args)) {
+ return apply(pair[1], this, args);
+ }
+ }
+ });
+ }
+
+ return cond;
+});
diff --git a/conforms.js b/conforms.js
new file mode 100644
index 000000000..9c042c209
--- /dev/null
+++ b/conforms.js
@@ -0,0 +1,28 @@
+define(['./internal/baseClone', './internal/baseConforms'], function(baseClone, baseConforms) {
+
+ /**
+ * Creates a function that invokes the predicate properties of `source` with
+ * the corresponding property values of a given object, returning `true` if
+ * all predicates return truthy, else `false`.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 }
+ * ];
+ *
+ * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
+ * // => [{ 'user': 'fred', 'age': 40 }]
+ */
+ function conforms(source) {
+ return baseConforms(baseClone(source, true));
+ }
+
+ return conforms;
+});
diff --git a/utility/constant.js b/constant.js
similarity index 95%
rename from utility/constant.js
rename to constant.js
index 4782c739b..53f88e439 100644
--- a/utility/constant.js
+++ b/constant.js
@@ -5,7 +5,7 @@ define([], function() {
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {*} value The value to return from the new function.
* @returns {Function} Returns the new function.
* @example
diff --git a/countBy.js b/countBy.js
new file mode 100644
index 000000000..676508329
--- /dev/null
+++ b/countBy.js
@@ -0,0 +1,34 @@
+define(['./internal/createAggregator'], function(createAggregator) {
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` through `iteratee`. The corresponding value
+ * of each key is the number of times the key was returned by `iteratee`.
+ * The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * _.countBy([6.1, 4.2, 6.3], Math.floor);
+ * // => { '4': 1, '6': 2 }
+ *
+ * _.countBy(['one', 'two', 'three'], 'length');
+ * // => { '3': 2, '5': 1 }
+ */
+ var countBy = createAggregator(function(result, value, key) {
+ hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
+ });
+
+ return countBy;
+});
diff --git a/object/create.js b/create.js
similarity index 53%
rename from object/create.js
rename to create.js
index c5babe0b0..ebba02bff 100644
--- a/object/create.js
+++ b/create.js
@@ -1,19 +1,14 @@
-define(['../internal/baseAssign', '../internal/baseCreate', '../internal/isIterateeCall'], function(baseAssign, baseCreate, isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
+define(['./internal/baseAssign', './internal/baseCreate'], function(baseAssign, baseCreate) {
/**
- * Creates an object that inherits from the given `prototype` object. If a
- * `properties` object is provided its own enumerable properties are assigned
- * to the created object.
+ * Creates an object that inherits from the `prototype` object. If a `properties`
+ * object is provided its own enumerable properties are assigned to the created object.
*
* @static
* @memberOf _
* @category Object
* @param {Object} prototype The object to inherit from.
* @param {Object} [properties] The properties to assign to the object.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
* @returns {Object} Returns the new object.
* @example
*
@@ -37,11 +32,8 @@ define(['../internal/baseAssign', '../internal/baseCreate', '../internal/isItera
* circle instanceof Shape;
* // => true
*/
- function create(prototype, properties, guard) {
+ function create(prototype, properties) {
var result = baseCreate(prototype);
- if (guard && isIterateeCall(prototype, properties, guard)) {
- properties = undefined;
- }
return properties ? baseAssign(result, properties) : result;
}
diff --git a/curry.js b/curry.js
new file mode 100644
index 000000000..810588509
--- /dev/null
+++ b/curry.js
@@ -0,0 +1,57 @@
+define(['./internal/createWrapper'], function(createWrapper) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to compose bitmasks for wrapper metadata. */
+ var CURRY_FLAG = 8;
+
+ /**
+ * Creates a function that accepts arguments of `func` and either invokes
+ * `func` returning its result, if at least `arity` number of arguments have
+ * been provided, or returns a function that accepts the remaining `func`
+ * arguments, and so on. The arity of `func` may be specified if `func.length`
+ * is not sufficient.
+ *
+ * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
+ * may be used as a placeholder for provided arguments.
+ *
+ * **Note:** This method doesn't set the "length" property of curried functions.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to curry.
+ * @param {number} [arity=func.length] The arity of `func`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {Function} Returns the new curried function.
+ * @example
+ *
+ * var abc = function(a, b, c) {
+ * return [a, b, c];
+ * };
+ *
+ * var curried = _.curry(abc);
+ *
+ * curried(1)(2)(3);
+ * // => [1, 2, 3]
+ *
+ * curried(1, 2)(3);
+ * // => [1, 2, 3]
+ *
+ * curried(1, 2, 3);
+ * // => [1, 2, 3]
+ *
+ * // using placeholders
+ * curried(1)(_, 3)(2);
+ * // => [1, 2, 3]
+ */
+ function curry(func, arity, guard) {
+ arity = guard ? undefined : arity;
+ var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
+ result.placeholder = curry.placeholder;
+ return result;
+ }
+
+ return curry;
+});
diff --git a/function/curryRight.js b/curryRight.js
similarity index 62%
rename from function/curryRight.js
rename to curryRight.js
index de46193cd..c1d4ea2ea 100644
--- a/function/curryRight.js
+++ b/curryRight.js
@@ -1,4 +1,7 @@
-define(['../internal/createCurry'], function(createCurry) {
+define(['./internal/createWrapper'], function(createWrapper) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/** Used to compose bitmasks for wrapper metadata. */
var CURRY_RIGHT_FLAG = 16;
@@ -10,14 +13,14 @@ define(['../internal/createCurry'], function(createCurry) {
* The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for provided arguments.
*
- * **Note:** This method does not set the "length" property of curried functions.
+ * **Note:** This method doesn't set the "length" property of curried functions.
*
* @static
* @memberOf _
* @category Function
* @param {Function} func The function to curry.
* @param {number} [arity=func.length] The arity of `func`.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the new curried function.
* @example
*
@@ -40,10 +43,12 @@ define(['../internal/createCurry'], function(createCurry) {
* curried(3)(1, _)(2);
* // => [1, 2, 3]
*/
- var curryRight = createCurry(CURRY_RIGHT_FLAG);
-
- // Assign default placeholders.
- curryRight.placeholder = {};
+ function curryRight(func, arity, guard) {
+ arity = guard ? undefined : arity;
+ var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
+ result.placeholder = curryRight.placeholder;
+ return result;
+ }
return curryRight;
});
diff --git a/date.js b/date.js
index 45cd23efd..51ef082af 100644
--- a/date.js
+++ b/date.js
@@ -1,4 +1,4 @@
-define(['./date/now'], function(now) {
+define(['./now'], function(now) {
return {
'now': now
};
diff --git a/date/now.js b/date/now.js
deleted file mode 100644
index 858be9f30..000000000
--- a/date/now.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define(['../internal/getNative'], function(getNative) {
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeNow = getNative(Date, 'now');
-
- /**
- * Gets the number of milliseconds that have elapsed since the Unix epoch
- * (1 January 1970 00:00:00 UTC).
- *
- * @static
- * @memberOf _
- * @category Date
- * @example
- *
- * _.defer(function(stamp) {
- * console.log(_.now() - stamp);
- * }, _.now());
- * // => logs the number of milliseconds it took for the deferred function to be invoked
- */
- var now = nativeNow || function() {
- return new Date().getTime();
- };
-
- return now;
-});
diff --git a/function/debounce.js b/debounce.js
similarity index 74%
rename from function/debounce.js
rename to debounce.js
index 293e6672a..af8b23c4f 100644
--- a/function/debounce.js
+++ b/debounce.js
@@ -1,4 +1,4 @@
-define(['../lang/isObject', '../date/now'], function(isObject, now) {
+define(['./isObject', './now', './toNumber'], function(isObject, now, toNumber) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -6,17 +6,18 @@ define(['../lang/isObject', '../date/now'], function(isObject, now) {
/** 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. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
- * delayed invocations. Provide an options object to indicate that `func`
- * should be invoked on the leading and/or trailing edge of the `wait` timeout.
- * Subsequent calls to the debounced function return the result of the last
- * `func` invocation.
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
+ * Provide an options object to indicate whether `func` should be invoked on
+ * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
+ * with the last arguments provided to the debounced function. Subsequent calls
+ * to the debounced function return the result of the last `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
* on the trailing edge of the timeout only if the the debounced function is
@@ -43,34 +44,19 @@ define(['../lang/isObject', '../date/now'], function(isObject, now) {
* // avoid costly calculations while the window size is in flux
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
*
- * // invoke `sendMail` when the click event is fired, debouncing subsequent calls
- * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
+ * // invoke `sendMail` when clicked, debouncing subsequent calls
+ * jQuery(element).on('click', _.debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // ensure `batchLog` is invoked once after 1 second of debounced calls
+ * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
- * jQuery(source).on('message', _.debounce(batchLog, 250, {
- * 'maxWait': 1000
- * }));
+ * jQuery(source).on('message', debounced);
*
- * // cancel a debounced call
- * var todoChanges = _.debounce(batchLog, 1000);
- * Object.observe(models.todo, todoChanges);
- *
- * Object.observe(models, function(changes) {
- * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {
- * todoChanges.cancel();
- * }
- * }, ['delete']);
- *
- * // ...at some point `models.todo` is changed
- * models.todo.completed = true;
- *
- * // ...before 1 second has passed `models.todo` is deleted
- * // which cancels the debounced `todoChanges` call
- * delete models.todo;
+ * // cancel a trailing debounced invocation
+ * jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var args,
@@ -81,19 +67,17 @@ define(['../lang/isObject', '../date/now'], function(isObject, now) {
timeoutId,
trailingCall,
lastCalled = 0,
+ leading = false,
maxWait = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- wait = wait < 0 ? 0 : (+wait || 0);
- if (options === true) {
- var leading = true;
- trailing = false;
- } else if (isObject(options)) {
+ wait = toNumber(wait) || 0;
+ if (isObject(options)) {
leading = !!options.leading;
- maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
+ maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
@@ -105,7 +89,7 @@ define(['../lang/isObject', '../date/now'], function(isObject, now) {
clearTimeout(maxTimeoutId);
}
lastCalled = 0;
- maxTimeoutId = timeoutId = trailingCall = undefined;
+ args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
}
function complete(isCalled, id) {
@@ -131,6 +115,14 @@ define(['../lang/isObject', '../date/now'], function(isObject, now) {
}
}
+ function flush() {
+ if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
+ result = func.apply(thisArg, args);
+ }
+ cancel();
+ return result;
+ }
+
function maxDelayed() {
complete(trailing, timeoutId);
}
@@ -177,6 +169,7 @@ define(['../lang/isObject', '../date/now'], function(isObject, now) {
return result;
}
debounced.cancel = cancel;
+ debounced.flush = flush;
return debounced;
}
diff --git a/string/deburr.js b/deburr.js
similarity index 72%
rename from string/deburr.js
rename to deburr.js
index b5e423921..3e709fdd1 100644
--- a/string/deburr.js
+++ b/deburr.js
@@ -1,11 +1,17 @@
-define(['../internal/baseToString', '../internal/deburrLetter'], function(baseToString, deburrLetter) {
-
- /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
- var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g;
+define(['./internal/deburrLetter', './toString'], function(deburrLetter, toString) {
/** Used to match latin-1 supplementary letters (excluding mathematical operators). */
var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
+ /** Used to compose unicode character classes. */
+ var rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23';
+
+ /** Used to compose unicode capture groups. */
+ var rsCombo = '[' + rsComboRange + ']';
+
+ /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
+ var reComboMark = RegExp(rsCombo, 'g');
+
/**
* Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
* to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
@@ -21,7 +27,7 @@ define(['../internal/baseToString', '../internal/deburrLetter'], function(baseTo
* // => 'deja vu'
*/
function deburr(string) {
- string = baseToString(string);
+ string = toString(string);
return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
}
diff --git a/defaults.js b/defaults.js
new file mode 100644
index 000000000..d1247afcd
--- /dev/null
+++ b/defaults.js
@@ -0,0 +1,31 @@
+define(['./internal/apply', './internal/assignInDefaults', './assignInWith', './rest'], function(apply, assignInDefaults, assignInWith, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Assigns own and inherited enumerable properties of source objects to the
+ * destination object for all destination properties that resolve to `undefined`.
+ * Source objects are applied from left to right. Once a property is set,
+ * additional values of the same property are ignored.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
+ * // => { 'user': 'barney', 'age': 36 }
+ */
+ var defaults = rest(function(args) {
+ args.push(undefined, assignInDefaults);
+ return apply(assignInWith, undefined, args);
+ });
+
+ return defaults;
+});
diff --git a/object/defaultsDeep.js b/defaultsDeep.js
similarity index 61%
rename from object/defaultsDeep.js
rename to defaultsDeep.js
index d3e276f2b..8c8cff727 100644
--- a/object/defaultsDeep.js
+++ b/defaultsDeep.js
@@ -1,4 +1,7 @@
-define(['../internal/createDefaults', './merge', '../internal/mergeDefaults'], function(createDefaults, merge, mergeDefaults) {
+define(['./internal/apply', './internal/mergeDefaults', './mergeWith', './rest'], function(apply, mergeDefaults, mergeWith, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* This method is like `_.defaults` except that it recursively assigns
@@ -18,7 +21,10 @@ define(['../internal/createDefaults', './merge', '../internal/mergeDefaults'], f
* // => { 'user': { 'name': 'barney', 'age': 36 } }
*
*/
- var defaultsDeep = createDefaults(merge, mergeDefaults);
+ var defaultsDeep = rest(function(args) {
+ args.push(undefined, mergeDefaults);
+ return apply(mergeWith, undefined, args);
+ });
return defaultsDeep;
});
diff --git a/function/defer.js b/defer.js
similarity index 72%
rename from function/defer.js
rename to defer.js
index 1f2467519..540bee383 100644
--- a/function/defer.js
+++ b/defer.js
@@ -1,4 +1,4 @@
-define(['../internal/baseDelay', './restParam'], function(baseDelay, restParam) {
+define(['./internal/baseDelay', './rest'], function(baseDelay, rest) {
/**
* Defers invoking the `func` until the current call stack has cleared. Any
@@ -8,7 +8,7 @@ define(['../internal/baseDelay', './restParam'], function(baseDelay, restParam)
* @memberOf _
* @category Function
* @param {Function} func The function to defer.
- * @param {...*} [args] The arguments to invoke the function with.
+ * @param {...*} [args] The arguments to invoke `func` with.
* @returns {number} Returns the timer id.
* @example
*
@@ -17,7 +17,7 @@ define(['../internal/baseDelay', './restParam'], function(baseDelay, restParam)
* }, 'deferred');
* // logs 'deferred' after one or more milliseconds
*/
- var defer = restParam(function(func, args) {
+ var defer = rest(function(func, args) {
return baseDelay(func, 1, args);
});
diff --git a/function/delay.js b/delay.js
similarity index 66%
rename from function/delay.js
rename to delay.js
index 6d0f4fc90..a780f2960 100644
--- a/function/delay.js
+++ b/delay.js
@@ -1,4 +1,4 @@
-define(['../internal/baseDelay', './restParam'], function(baseDelay, restParam) {
+define(['./internal/baseDelay', './rest', './toNumber'], function(baseDelay, rest, toNumber) {
/**
* Invokes `func` after `wait` milliseconds. Any additional arguments are
@@ -9,7 +9,7 @@ define(['../internal/baseDelay', './restParam'], function(baseDelay, restParam)
* @category Function
* @param {Function} func The function to delay.
* @param {number} wait The number of milliseconds to delay invocation.
- * @param {...*} [args] The arguments to invoke the function with.
+ * @param {...*} [args] The arguments to invoke `func` with.
* @returns {number} Returns the timer id.
* @example
*
@@ -18,8 +18,8 @@ define(['../internal/baseDelay', './restParam'], function(baseDelay, restParam)
* }, 1000, 'later');
* // => logs 'later' after one second
*/
- var delay = restParam(function(func, wait, args) {
- return baseDelay(func, wait, args);
+ var delay = rest(function(func, wait, args) {
+ return baseDelay(func, toNumber(wait) || 0, args);
});
return delay;
diff --git a/array/difference.js b/difference.js
similarity index 53%
rename from array/difference.js
rename to difference.js
index 5ca1e4294..6c104e962 100644
--- a/array/difference.js
+++ b/difference.js
@@ -1,4 +1,4 @@
-define(['../internal/baseDifference', '../internal/baseFlatten', '../internal/isArrayLike', '../internal/isObjectLike', '../function/restParam'], function(baseDifference, baseFlatten, isArrayLike, isObjectLike, restParam) {
+define(['./internal/baseDifference', './internal/baseFlatten', './isArrayLikeObject', './rest'], function(baseDifference, baseFlatten, isArrayLikeObject, rest) {
/**
* Creates an array of unique `array` values not included in the other
@@ -9,15 +9,15 @@ define(['../internal/baseDifference', '../internal/baseFlatten', '../internal/is
* @memberOf _
* @category Array
* @param {Array} array The array to inspect.
- * @param {...Array} [values] The arrays of values to exclude.
+ * @param {...Array} [values] The values to exclude.
* @returns {Array} Returns the new array of filtered values.
* @example
*
- * _.difference([1, 2, 3], [4, 2]);
- * // => [1, 3]
+ * _.difference([3, 2, 1], [4, 2]);
+ * // => [3, 1]
*/
- var difference = restParam(function(array, values) {
- return (isObjectLike(array) && isArrayLike(array))
+ var difference = rest(function(array, values) {
+ return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, false, true))
: [];
});
diff --git a/differenceBy.js b/differenceBy.js
new file mode 100644
index 000000000..b866be8d8
--- /dev/null
+++ b/differenceBy.js
@@ -0,0 +1,38 @@
+define(['./internal/baseDifference', './internal/baseFlatten', './internal/baseIteratee', './isArrayLikeObject', './last', './rest'], function(baseDifference, baseFlatten, baseIteratee, isArrayLikeObject, last, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.difference` except that it accepts `iteratee` which
+ * is invoked for each element of `array` and `values` to generate the criterion
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
+ * // => [3.1, 1.3]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+ * // => [{ 'x': 2 }]
+ */
+ var differenceBy = rest(function(array, values) {
+ var iteratee = last(values);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
+ }
+ return isArrayLikeObject(array)
+ ? baseDifference(array, baseFlatten(values, false, true), baseIteratee(iteratee))
+ : [];
+ });
+
+ return differenceBy;
+});
diff --git a/differenceWith.js b/differenceWith.js
new file mode 100644
index 000000000..c2d23f0e1
--- /dev/null
+++ b/differenceWith.js
@@ -0,0 +1,36 @@
+define(['./internal/baseDifference', './internal/baseFlatten', './isArrayLikeObject', './last', './rest'], function(baseDifference, baseFlatten, isArrayLikeObject, last, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.difference` except that it accepts `comparator`
+ * which is invoked to compare elements of `array` to `values`. The comparator
+ * is invoked with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ *
+ * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
+ * // => [{ 'x': 2, 'y': 1 }]
+ */
+ var differenceWith = rest(function(array, values) {
+ var comparator = last(values);
+ if (isArrayLikeObject(comparator)) {
+ comparator = undefined;
+ }
+ return isArrayLikeObject(array)
+ ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator)
+ : [];
+ });
+
+ return differenceWith;
+});
diff --git a/array/drop.js b/drop.js
similarity index 64%
rename from array/drop.js
rename to drop.js
index 9b332eccf..d1b5d6d4f 100644
--- a/array/drop.js
+++ b/drop.js
@@ -1,4 +1,7 @@
-define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSlice, isIterateeCall) {
+define(['./internal/baseSlice', './toInteger'], function(baseSlice, toInteger) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* Creates a slice of `array` with `n` elements dropped from the beginning.
@@ -8,7 +11,7 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to drop.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
@@ -29,10 +32,8 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
if (!length) {
return [];
}
- if (guard ? isIterateeCall(array, n, guard) : n == null) {
- n = 1;
- }
- return baseSlice(array, n < 0 ? 0 : n);
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ return baseSlice(array, n < 0 ? 0 : n, length);
}
return drop;
diff --git a/array/dropRight.js b/dropRight.js
similarity index 68%
rename from array/dropRight.js
rename to dropRight.js
index 888f726df..5dac9a39a 100644
--- a/array/dropRight.js
+++ b/dropRight.js
@@ -1,4 +1,7 @@
-define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSlice, isIterateeCall) {
+define(['./internal/baseSlice', './toInteger'], function(baseSlice, toInteger) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* Creates a slice of `array` with `n` elements dropped from the end.
@@ -8,7 +11,7 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to drop.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
@@ -29,10 +32,8 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
if (!length) {
return [];
}
- if (guard ? isIterateeCall(array, n, guard) : n == null) {
- n = 1;
- }
- n = length - (+n || 0);
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ n = length - n;
return baseSlice(array, 0, n < 0 ? 0 : n);
}
diff --git a/dropRightWhile.js b/dropRightWhile.js
new file mode 100644
index 000000000..b660b589b
--- /dev/null
+++ b/dropRightWhile.js
@@ -0,0 +1,44 @@
+define(['./internal/baseIteratee', './internal/baseWhile'], function(baseIteratee, baseWhile) {
+
+ /**
+ * Creates a slice of `array` excluding elements dropped from the end.
+ * Elements are dropped until `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.dropRightWhile(users, function(o) { return !o.active; });
+ * // => objects for ['barney']
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
+ * // => objects for ['barney', 'fred']
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.dropRightWhile(users, ['active', false]);
+ * // => objects for ['barney']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.dropRightWhile(users, 'active');
+ * // => objects for ['barney', 'fred', 'pebbles']
+ */
+ function dropRightWhile(array, predicate) {
+ return (array && array.length)
+ ? baseWhile(array, baseIteratee(predicate, 3), true, true)
+ : [];
+ }
+
+ return dropRightWhile;
+});
diff --git a/dropWhile.js b/dropWhile.js
new file mode 100644
index 000000000..054cae5b1
--- /dev/null
+++ b/dropWhile.js
@@ -0,0 +1,44 @@
+define(['./internal/baseIteratee', './internal/baseWhile'], function(baseIteratee, baseWhile) {
+
+ /**
+ * Creates a slice of `array` excluding elements dropped from the beginning.
+ * Elements are dropped until `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.dropWhile(users, function(o) { return !o.active; });
+ * // => objects for ['pebbles']
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.dropWhile(users, { 'user': 'barney', 'active': false });
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.dropWhile(users, ['active', false]);
+ * // => objects for ['pebbles']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.dropWhile(users, 'active');
+ * // => objects for ['barney', 'fred', 'pebbles']
+ */
+ function dropWhile(array, predicate) {
+ return (array && array.length)
+ ? baseWhile(array, baseIteratee(predicate, 3), true)
+ : [];
+ }
+
+ return dropWhile;
+});
diff --git a/collection/each.js b/each.js
similarity index 100%
rename from collection/each.js
rename to each.js
diff --git a/collection/eachRight.js b/eachRight.js
similarity index 100%
rename from collection/eachRight.js
rename to eachRight.js
diff --git a/string/endsWith.js b/endsWith.js
similarity index 75%
rename from string/endsWith.js
rename to endsWith.js
index 999daf554..149dab687 100644
--- a/string/endsWith.js
+++ b/endsWith.js
@@ -1,11 +1,8 @@
-define(['../internal/baseToString'], function(baseToString) {
+define(['./internal/baseClamp', './toInteger', './toString'], function(baseClamp, toInteger, toString) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeMin = Math.min;
-
/**
* Checks if `string` ends with the given target string.
*
@@ -28,13 +25,13 @@ define(['../internal/baseToString'], function(baseToString) {
* // => true
*/
function endsWith(string, target, position) {
- string = baseToString(string);
- target = (target + '');
+ string = toString(string);
+ target = typeof target == 'string' ? target : (target + '');
var length = string.length;
position = position === undefined
? length
- : nativeMin(position < 0 ? 0 : (+position || 0), length);
+ : baseClamp(toInteger(position), 0, length);
position -= target.length;
return position >= 0 && string.indexOf(target, position) == position;
diff --git a/eq.js b/eq.js
new file mode 100644
index 000000000..11fad7058
--- /dev/null
+++ b/eq.js
@@ -0,0 +1,38 @@
+define([], function() {
+
+ /**
+ * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * comparison between two values to determine if they are equivalent.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var other = { 'user': 'fred' };
+ *
+ * _.eq(object, object);
+ * // => true
+ *
+ * _.eq(object, other);
+ * // => false
+ *
+ * _.eq('a', 'a');
+ * // => true
+ *
+ * _.eq('a', Object('a'));
+ * // => false
+ *
+ * _.eq(NaN, NaN);
+ * // => true
+ */
+ function eq(value, other) {
+ return value === other || (value !== value && other !== other);
+ }
+
+ return eq;
+});
diff --git a/string/escape.js b/escape.js
similarity index 72%
rename from string/escape.js
rename to escape.js
index 41e798367..b270a8858 100644
--- a/string/escape.js
+++ b/escape.js
@@ -1,15 +1,15 @@
-define(['../internal/baseToString', '../internal/escapeHtmlChar'], function(baseToString, escapeHtmlChar) {
+define(['./internal/escapeHtmlChar', './toString'], function(escapeHtmlChar, toString) {
/** Used to match HTML entities and HTML characters. */
var reUnescapedHtml = /[&<>"'`]/g,
reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
/**
- * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to
+ * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
* their corresponding HTML entities.
*
- * **Note:** No other characters are escaped. To escape additional characters
- * use a third-party library like [_he_](https://mths.be/he).
+ * **Note:** No other characters are escaped. To escape additional
+ * characters use a third-party library like [_he_](https://mths.be/he).
*
* Though the ">" character is escaped for symmetry, characters like
* ">" and "/" don't need escaping in HTML and have no special meaning
@@ -17,8 +17,8 @@ define(['../internal/baseToString', '../internal/escapeHtmlChar'], function(base
* See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
* (under "semi-related fun fact") for more details.
*
- * Backticks are escaped because in Internet Explorer < 9, they can break out
- * of attribute values or HTML comments. See [#59](https://html5sec.org/#59),
+ * Backticks are escaped because in IE < 9, they can break out of
+ * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
* [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
* [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
* for more details.
@@ -37,8 +37,7 @@ define(['../internal/baseToString', '../internal/escapeHtmlChar'], function(base
* // => 'fred, barney, & pebbles'
*/
function escape(string) {
- // Reset `lastIndex` because in IE < 9 `String#replace` does not.
- string = baseToString(string);
+ string = toString(string);
return (string && reHasUnescapedHtml.test(string))
? string.replace(reUnescapedHtml, escapeHtmlChar)
: string;
diff --git a/escapeRegExp.js b/escapeRegExp.js
new file mode 100644
index 000000000..e08ca8030
--- /dev/null
+++ b/escapeRegExp.js
@@ -0,0 +1,29 @@
+define(['./toString'], function(toString) {
+
+ /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
+ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
+ reHasRegExpChar = RegExp(reRegExpChar.source);
+
+ /**
+ * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
+ * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escapeRegExp('[lodash](https://lodash.com/)');
+ * // => '\[lodash\]\(https://lodash\.com/\)'
+ */
+ function escapeRegExp(string) {
+ string = toString(string);
+ return (string && reHasRegExpChar.test(string))
+ ? string.replace(reRegExpChar, '\\$&')
+ : string;
+ }
+
+ return escapeRegExp;
+});
diff --git a/every.js b/every.js
new file mode 100644
index 000000000..56961ed47
--- /dev/null
+++ b/every.js
@@ -0,0 +1,49 @@
+define(['./internal/arrayEvery', './internal/baseEvery', './internal/baseIteratee', './isArray', './internal/isIterateeCall'], function(arrayEvery, baseEvery, baseIteratee, isArray, isIterateeCall) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Checks if `predicate` returns truthy for **all** elements of `collection`.
+ * Iteration is stopped once `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
+ * @example
+ *
+ * _.every([true, 1, null, 'yes'], Boolean);
+ * // => false
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false }
+ * ];
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.every(users, { 'user': 'barney', 'active': false });
+ * // => false
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.every(users, ['active', false]);
+ * // => true
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.every(users, 'active');
+ * // => false
+ */
+ function every(collection, predicate, guard) {
+ var func = isArray(collection) ? arrayEvery : baseEvery;
+ if (guard && isIterateeCall(collection, predicate, guard)) {
+ predicate = undefined;
+ }
+ return func(collection, baseIteratee(predicate, 3));
+ }
+
+ return every;
+});
diff --git a/array/fill.js b/fill.js
similarity index 85%
rename from array/fill.js
rename to fill.js
index a8e067839..1bd870271 100644
--- a/array/fill.js
+++ b/fill.js
@@ -1,4 +1,4 @@
-define(['../internal/baseFill', '../internal/isIterateeCall'], function(baseFill, isIterateeCall) {
+define(['./internal/baseFill', './internal/isIterateeCall'], function(baseFill, isIterateeCall) {
/**
* Fills elements of `array` with `value` from `start` up to, but not
@@ -25,8 +25,8 @@ define(['../internal/baseFill', '../internal/isIterateeCall'], function(baseFill
* _.fill(Array(3), 2);
* // => [2, 2, 2]
*
- * _.fill([4, 6, 8], '*', 1, 2);
- * // => [4, '*', 8]
+ * _.fill([4, 6, 8, 10], '*', 1, 3);
+ * // => [4, '*', '*', 10]
*/
function fill(array, value, start, end) {
var length = array ? array.length : 0;
diff --git a/filter.js b/filter.js
new file mode 100644
index 000000000..596d31b5e
--- /dev/null
+++ b/filter.js
@@ -0,0 +1,42 @@
+define(['./internal/arrayFilter', './internal/baseFilter', './internal/baseIteratee', './isArray'], function(arrayFilter, baseFilter, baseIteratee, isArray) {
+
+ /**
+ * Iterates over elements of `collection`, returning an array of all elements
+ * `predicate` returns truthy for. The predicate is invoked with three arguments:
+ * (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * _.filter(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.filter(users, { 'age': 36, 'active': true });
+ * // => objects for ['barney']
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.filter(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.filter(users, 'active');
+ * // => objects for ['barney']
+ */
+ function filter(collection, predicate) {
+ var func = isArray(collection) ? arrayFilter : baseFilter;
+ return func(collection, baseIteratee(predicate, 3));
+ }
+
+ return filter;
+});
diff --git a/find.js b/find.js
new file mode 100644
index 000000000..a944af14e
--- /dev/null
+++ b/find.js
@@ -0,0 +1,50 @@
+define(['./internal/baseEach', './internal/baseFind', './internal/baseFindIndex', './internal/baseIteratee', './isArray'], function(baseEach, baseFind, baseFindIndex, baseIteratee, isArray) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Iterates over elements of `collection`, returning the first element
+ * `predicate` returns truthy for. The predicate is invoked with three arguments:
+ * (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false },
+ * { 'user': 'pebbles', 'age': 1, 'active': true }
+ * ];
+ *
+ * _.find(users, function(o) { return o.age < 40; });
+ * // => object for 'barney'
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.find(users, { 'age': 1, 'active': true });
+ * // => object for 'pebbles'
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.find(users, ['active', false]);
+ * // => object for 'fred'
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.find(users, 'active');
+ * // => object for 'barney'
+ */
+ function find(collection, predicate) {
+ predicate = baseIteratee(predicate, 3);
+ if (isArray(collection)) {
+ var index = baseFindIndex(collection, predicate);
+ return index > -1 ? collection[index] : undefined;
+ }
+ return baseFind(collection, predicate, baseEach);
+ }
+
+ return find;
+});
diff --git a/findIndex.js b/findIndex.js
new file mode 100644
index 000000000..e90650b18
--- /dev/null
+++ b/findIndex.js
@@ -0,0 +1,43 @@
+define(['./internal/baseFindIndex', './internal/baseIteratee'], function(baseFindIndex, baseIteratee) {
+
+ /**
+ * This method is like `_.find` except that it returns the index of the first
+ * element `predicate` returns truthy for instead of the element itself.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {number} Returns the index of the found element, else `-1`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.findIndex(users, function(o) { return o.user == 'barney'; });
+ * // => 0
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.findIndex(users, { 'user': 'fred', 'active': false });
+ * // => 1
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.findIndex(users, ['active', false]);
+ * // => 0
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.findIndex(users, 'active');
+ * // => 2
+ */
+ function findIndex(array, predicate) {
+ return (array && array.length)
+ ? baseFindIndex(array, baseIteratee(predicate, 3))
+ : -1;
+ }
+
+ return findIndex;
+});
diff --git a/findKey.js b/findKey.js
new file mode 100644
index 000000000..2afa442d7
--- /dev/null
+++ b/findKey.js
@@ -0,0 +1,41 @@
+define(['./internal/baseFind', './internal/baseForOwn', './internal/baseIteratee'], function(baseFind, baseForOwn, baseIteratee) {
+
+ /**
+ * This method is like `_.find` except that it returns the key of the first
+ * element `predicate` returns truthy for instead of the element itself.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
+ * @example
+ *
+ * var users = {
+ * 'barney': { 'age': 36, 'active': true },
+ * 'fred': { 'age': 40, 'active': false },
+ * 'pebbles': { 'age': 1, 'active': true }
+ * };
+ *
+ * _.findKey(users, function(o) { return o.age < 40; });
+ * // => 'barney' (iteration order is not guaranteed)
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.findKey(users, { 'age': 1, 'active': true });
+ * // => 'pebbles'
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.findKey(users, ['active', false]);
+ * // => 'fred'
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.findKey(users, 'active');
+ * // => 'barney'
+ */
+ function findKey(object, predicate) {
+ return baseFind(object, baseIteratee(predicate, 3), baseForOwn, true);
+ }
+
+ return findKey;
+});
diff --git a/findLast.js b/findLast.js
new file mode 100644
index 000000000..6a22449b9
--- /dev/null
+++ b/findLast.js
@@ -0,0 +1,33 @@
+define(['./internal/baseEachRight', './internal/baseFind', './internal/baseFindIndex', './internal/baseIteratee', './isArray'], function(baseEachRight, baseFind, baseFindIndex, baseIteratee, isArray) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.find` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * _.findLast([1, 2, 3, 4], function(n) {
+ * return n % 2 == 1;
+ * });
+ * // => 3
+ */
+ function findLast(collection, predicate) {
+ predicate = baseIteratee(predicate, 3);
+ if (isArray(collection)) {
+ var index = baseFindIndex(collection, predicate, true);
+ return index > -1 ? collection[index] : undefined;
+ }
+ return baseFind(collection, predicate, baseEachRight);
+ }
+
+ return findLast;
+});
diff --git a/findLastIndex.js b/findLastIndex.js
new file mode 100644
index 000000000..3568dd2de
--- /dev/null
+++ b/findLastIndex.js
@@ -0,0 +1,43 @@
+define(['./internal/baseFindIndex', './internal/baseIteratee'], function(baseFindIndex, baseIteratee) {
+
+ /**
+ * This method is like `_.findIndex` except that it iterates over elements
+ * of `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {number} Returns the index of the found element, else `-1`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
+ * // => 2
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.findLastIndex(users, { 'user': 'barney', 'active': true });
+ * // => 0
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.findLastIndex(users, ['active', false]);
+ * // => 2
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.findLastIndex(users, 'active');
+ * // => 0
+ */
+ function findLastIndex(array, predicate) {
+ return (array && array.length)
+ ? baseFindIndex(array, baseIteratee(predicate, 3), true)
+ : -1;
+ }
+
+ return findLastIndex;
+});
diff --git a/findLastKey.js b/findLastKey.js
new file mode 100644
index 000000000..8b7c5e7ec
--- /dev/null
+++ b/findLastKey.js
@@ -0,0 +1,41 @@
+define(['./internal/baseFind', './internal/baseForOwnRight', './internal/baseIteratee'], function(baseFind, baseForOwnRight, baseIteratee) {
+
+ /**
+ * This method is like `_.findKey` except that it iterates over elements of
+ * a collection in the opposite order.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
+ * @example
+ *
+ * var users = {
+ * 'barney': { 'age': 36, 'active': true },
+ * 'fred': { 'age': 40, 'active': false },
+ * 'pebbles': { 'age': 1, 'active': true }
+ * };
+ *
+ * _.findLastKey(users, function(o) { return o.age < 40; });
+ * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.findLastKey(users, { 'age': 36, 'active': true });
+ * // => 'barney'
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.findLastKey(users, ['active', false]);
+ * // => 'fred'
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.findLastKey(users, 'active');
+ * // => 'pebbles'
+ */
+ function findLastKey(object, predicate) {
+ return baseFind(object, baseIteratee(predicate, 3), baseForOwnRight, true);
+ }
+
+ return findLastKey;
+});
diff --git a/flatMap.js b/flatMap.js
new file mode 100644
index 000000000..8268363ea
--- /dev/null
+++ b/flatMap.js
@@ -0,0 +1,29 @@
+define(['./internal/arrayMap', './internal/baseFlatten', './internal/baseIteratee'], function(arrayMap, baseFlatten, baseIteratee) {
+
+ /**
+ * Creates an array of flattened values by running each element in `array`
+ * through `iteratee` and concating its result to the other mapped values.
+ * The iteratee is invoked with three arguments: (value, index|key, array).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new array.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [n, n];
+ * }
+ *
+ * _.flatMap([1, 2], duplicate);
+ * // => [1, 1, 2, 2]
+ */
+ function flatMap(array, iteratee) {
+ var length = array ? array.length : 0;
+ return length ? baseFlatten(arrayMap(array, baseIteratee(iteratee, 3))) : [];
+ }
+
+ return flatMap;
+});
diff --git a/flatten.js b/flatten.js
new file mode 100644
index 000000000..12117b0b6
--- /dev/null
+++ b/flatten.js
@@ -0,0 +1,22 @@
+define(['./internal/baseFlatten'], function(baseFlatten) {
+
+ /**
+ * Flattens `array` a single level.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * _.flatten([1, [2, 3, [4]]]);
+ * // => [1, 2, 3, [4]]
+ */
+ function flatten(array) {
+ var length = array ? array.length : 0;
+ return length ? baseFlatten(array) : [];
+ }
+
+ return flatten;
+});
diff --git a/array/flattenDeep.js b/flattenDeep.js
similarity index 74%
rename from array/flattenDeep.js
rename to flattenDeep.js
index 3245d8670..6f2605077 100644
--- a/array/flattenDeep.js
+++ b/flattenDeep.js
@@ -1,7 +1,7 @@
-define(['../internal/baseFlatten'], function(baseFlatten) {
+define(['./internal/baseFlatten'], function(baseFlatten) {
/**
- * Recursively flattens a nested array.
+ * This method is like `_.flatten` except that it recursively flattens `array`.
*
* @static
* @memberOf _
diff --git a/flip.js b/flip.js
new file mode 100644
index 000000000..69c527d1f
--- /dev/null
+++ b/flip.js
@@ -0,0 +1,28 @@
+define(['./internal/createWrapper'], function(createWrapper) {
+
+ /** Used to compose bitmasks for wrapper metadata. */
+ var FLIP_FLAG = 512;
+
+ /**
+ * Creates a function that invokes `func` with arguments reversed.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to flip arguments for.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var flipped = _.flip(function() {
+ * return _.toArray(arguments);
+ * });
+ *
+ * flipped('a', 'b', 'c', 'd');
+ * // => ['d', 'c', 'b', 'a']
+ */
+ function flip(func) {
+ return createWrapper(func, FLIP_FLAG);
+ }
+
+ return flip;
+});
diff --git a/math/floor.js b/floor.js
similarity index 70%
rename from math/floor.js
rename to floor.js
index eb1d97649..e5c4fe812 100644
--- a/math/floor.js
+++ b/floor.js
@@ -1,12 +1,12 @@
-define(['../internal/createRound'], function(createRound) {
+define(['./internal/createRound'], function(createRound) {
/**
- * Calculates `n` rounded down to `precision`.
+ * Computes `number` rounded down to `precision`.
*
* @static
* @memberOf _
* @category Math
- * @param {number} n The number to round down.
+ * @param {number} number The number to round down.
* @param {number} [precision=0] The precision to round down to.
* @returns {number} Returns the rounded down number.
* @example
diff --git a/function/flow.js b/flow.js
similarity index 78%
rename from function/flow.js
rename to flow.js
index 8ad1fcbfd..b9c223bf8 100644
--- a/function/flow.js
+++ b/flow.js
@@ -1,4 +1,4 @@
-define(['../internal/createFlow'], function(createFlow) {
+define(['./internal/createFlow'], function(createFlow) {
/**
* Creates a function that returns the result of invoking the provided
@@ -7,8 +7,8 @@ define(['../internal/createFlow'], function(createFlow) {
*
* @static
* @memberOf _
- * @category Function
- * @param {...Function} [funcs] Functions to invoke.
+ * @category Util
+ * @param {...(Function|Function[])} [funcs] Functions to invoke.
* @returns {Function} Returns the new function.
* @example
*
diff --git a/function/flowRight.js b/flowRight.js
similarity index 72%
rename from function/flowRight.js
rename to flowRight.js
index b9a66ca3f..d264208bc 100644
--- a/function/flowRight.js
+++ b/flowRight.js
@@ -1,4 +1,4 @@
-define(['../internal/createFlow'], function(createFlow) {
+define(['./internal/createFlow'], function(createFlow) {
/**
* This method is like `_.flow` except that it creates a function that
@@ -6,9 +6,8 @@ define(['../internal/createFlow'], function(createFlow) {
*
* @static
* @memberOf _
- * @alias backflow, compose
- * @category Function
- * @param {...Function} [funcs] Functions to invoke.
+ * @category Util
+ * @param {...(Function|Function[])} [funcs] Functions to invoke.
* @returns {Function} Returns the new function.
* @example
*
diff --git a/forEach.js b/forEach.js
new file mode 100644
index 000000000..f78234c9b
--- /dev/null
+++ b/forEach.js
@@ -0,0 +1,38 @@
+define(['./internal/arrayEach', './internal/baseEach', './isArray', './internal/toFunction'], function(arrayEach, baseEach, isArray, toFunction) {
+
+ /**
+ * Iterates over elements of `collection` invoking `iteratee` for each element.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length" property
+ * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
+ * for object iteration.
+ *
+ * @static
+ * @memberOf _
+ * @alias each
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @example
+ *
+ * _([1, 2]).forEach(function(value) {
+ * console.log(value);
+ * });
+ * // => logs `1` then `2`
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
+ * console.log(key);
+ * });
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
+ */
+ function forEach(collection, iteratee) {
+ return (typeof iteratee == 'function' && isArray(collection))
+ ? arrayEach(collection, iteratee)
+ : baseEach(collection, toFunction(iteratee));
+ }
+
+ return forEach;
+});
diff --git a/forEachRight.js b/forEachRight.js
new file mode 100644
index 000000000..5361ec4e0
--- /dev/null
+++ b/forEachRight.js
@@ -0,0 +1,28 @@
+define(['./internal/arrayEachRight', './internal/baseEachRight', './isArray', './internal/toFunction'], function(arrayEachRight, baseEachRight, isArray, toFunction) {
+
+ /**
+ * This method is like `_.forEach` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @alias eachRight
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @example
+ *
+ * _.forEachRight([1, 2], function(value) {
+ * console.log(value);
+ * });
+ * // => logs `2` then `1`
+ */
+ function forEachRight(collection, iteratee) {
+ return (typeof iteratee == 'function' && isArray(collection))
+ ? arrayEachRight(collection, iteratee)
+ : baseEachRight(collection, toFunction(iteratee));
+ }
+
+ return forEachRight;
+});
diff --git a/object/forIn.js b/forIn.js
similarity index 52%
rename from object/forIn.js
rename to forIn.js
index be2ebdb23..1be3f1ae8 100644
--- a/object/forIn.js
+++ b/forIn.js
@@ -1,17 +1,16 @@
-define(['../internal/baseFor', '../internal/createForIn'], function(baseFor, createForIn) {
+define(['./internal/baseFor', './keysIn', './internal/toFunction'], function(baseFor, keysIn, toFunction) {
/**
* Iterates over own and inherited enumerable properties of an object invoking
- * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked
- * with three arguments: (value, key, object). Iteratee functions may exit
- * iteration early by explicitly returning `false`.
+ * `iteratee` for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Object} Returns `object`.
* @example
*
@@ -25,9 +24,11 @@ define(['../internal/baseFor', '../internal/createForIn'], function(baseFor, cre
* _.forIn(new Foo, function(value, key) {
* console.log(key);
* });
- * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed)
+ * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
*/
- var forIn = createForIn(baseFor);
+ function forIn(object, iteratee) {
+ return object == null ? object : baseFor(object, toFunction(iteratee), keysIn);
+ }
return forIn;
});
diff --git a/object/forInRight.js b/forInRight.js
similarity index 64%
rename from object/forInRight.js
rename to forInRight.js
index ce2dfc203..84042b36a 100644
--- a/object/forInRight.js
+++ b/forInRight.js
@@ -1,4 +1,4 @@
-define(['../internal/baseForRight', '../internal/createForIn'], function(baseForRight, createForIn) {
+define(['./internal/baseForRight', './keysIn', './internal/toFunction'], function(baseForRight, keysIn, toFunction) {
/**
* This method is like `_.forIn` except that it iterates over properties of
@@ -9,7 +9,6 @@ define(['../internal/baseForRight', '../internal/createForIn'], function(baseFor
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Object} Returns `object`.
* @example
*
@@ -23,9 +22,11 @@ define(['../internal/baseForRight', '../internal/createForIn'], function(baseFor
* _.forInRight(new Foo, function(value, key) {
* console.log(key);
* });
- * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'
+ * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
*/
- var forInRight = createForIn(baseForRight);
+ function forInRight(object, iteratee) {
+ return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn);
+ }
return forInRight;
});
diff --git a/object/forOwn.js b/forOwn.js
similarity index 53%
rename from object/forOwn.js
rename to forOwn.js
index 7c722a634..175d7a925 100644
--- a/object/forOwn.js
+++ b/forOwn.js
@@ -1,17 +1,16 @@
-define(['../internal/baseForOwn', '../internal/createForOwn'], function(baseForOwn, createForOwn) {
+define(['./internal/baseForOwn', './internal/toFunction'], function(baseForOwn, toFunction) {
/**
* Iterates over own enumerable properties of an object invoking `iteratee`
- * for each property. The `iteratee` is bound to `thisArg` and invoked with
- * three arguments: (value, key, object). Iteratee functions may exit iteration
- * early by explicitly returning `false`.
+ * for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by
+ * explicitly returning `false`.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Object} Returns `object`.
* @example
*
@@ -25,9 +24,11 @@ define(['../internal/baseForOwn', '../internal/createForOwn'], function(baseForO
* _.forOwn(new Foo, function(value, key) {
* console.log(key);
* });
- * // => logs 'a' and 'b' (iteration order is not guaranteed)
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
*/
- var forOwn = createForOwn(baseForOwn);
+ function forOwn(object, iteratee) {
+ return object && baseForOwn(object, toFunction(iteratee));
+ }
return forOwn;
});
diff --git a/object/forOwnRight.js b/forOwnRight.js
similarity index 67%
rename from object/forOwnRight.js
rename to forOwnRight.js
index c38b792d3..54408eb5b 100644
--- a/object/forOwnRight.js
+++ b/forOwnRight.js
@@ -1,4 +1,4 @@
-define(['../internal/baseForOwnRight', '../internal/createForOwn'], function(baseForOwnRight, createForOwn) {
+define(['./internal/baseForOwnRight', './internal/toFunction'], function(baseForOwnRight, toFunction) {
/**
* This method is like `_.forOwn` except that it iterates over properties of
@@ -9,7 +9,6 @@ define(['../internal/baseForOwnRight', '../internal/createForOwn'], function(bas
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Object} Returns `object`.
* @example
*
@@ -23,9 +22,11 @@ define(['../internal/baseForOwnRight', '../internal/createForOwn'], function(bas
* _.forOwnRight(new Foo, function(value, key) {
* console.log(key);
* });
- * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'
+ * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
*/
- var forOwnRight = createForOwn(baseForOwnRight);
+ function forOwnRight(object, iteratee) {
+ return object && baseForOwnRight(object, toFunction(iteratee));
+ }
return forOwnRight;
});
diff --git a/fromPairs.js b/fromPairs.js
new file mode 100644
index 000000000..4672204cd
--- /dev/null
+++ b/fromPairs.js
@@ -0,0 +1,30 @@
+define(['./internal/baseSet'], function(baseSet) {
+
+ /**
+ * The inverse of `_.toPairs`; this method returns an object composed
+ * from key-value `pairs`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} pairs The key-value pairs.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.fromPairs([['fred', 30], ['barney', 40]]);
+ * // => { 'fred': 30, 'barney': 40 }
+ */
+ function fromPairs(pairs) {
+ var index = -1,
+ length = pairs ? pairs.length : 0,
+ result = {};
+
+ while (++index < length) {
+ var pair = pairs[index];
+ baseSet(result, pair[0], pair[1]);
+ }
+ return result;
+ }
+
+ return fromPairs;
+});
diff --git a/function.js b/function.js
index d00110fcd..9ade01b63 100644
--- a/function.js
+++ b/function.js
@@ -1,30 +1,27 @@
-define(['./function/after', './function/ary', './function/backflow', './function/before', './function/bind', './function/bindAll', './function/bindKey', './function/compose', './function/curry', './function/curryRight', './function/debounce', './function/defer', './function/delay', './function/flow', './function/flowRight', './function/memoize', './function/modArgs', './function/negate', './function/once', './function/partial', './function/partialRight', './function/rearg', './function/restParam', './function/spread', './function/throttle', './function/wrap'], function(after, ary, backflow, before, bind, bindAll, bindKey, compose, curry, curryRight, debounce, defer, delay, flow, flowRight, memoize, modArgs, negate, once, partial, partialRight, rearg, restParam, spread, throttle, wrap) {
+define(['./after', './ary', './before', './bind', './bindKey', './curry', './curryRight', './debounce', './defer', './delay', './flip', './memoize', './negate', './once', './overArgs', './partial', './partialRight', './rearg', './rest', './spread', './throttle', './unary', './wrap'], function(after, ary, before, bind, bindKey, curry, curryRight, debounce, defer, delay, flip, memoize, negate, once, overArgs, partial, partialRight, rearg, rest, spread, throttle, unary, wrap) {
return {
'after': after,
'ary': ary,
- 'backflow': backflow,
'before': before,
'bind': bind,
- 'bindAll': bindAll,
'bindKey': bindKey,
- 'compose': compose,
'curry': curry,
'curryRight': curryRight,
'debounce': debounce,
'defer': defer,
'delay': delay,
- 'flow': flow,
- 'flowRight': flowRight,
+ 'flip': flip,
'memoize': memoize,
- 'modArgs': modArgs,
'negate': negate,
'once': once,
+ 'overArgs': overArgs,
'partial': partial,
'partialRight': partialRight,
'rearg': rearg,
- 'restParam': restParam,
+ 'rest': rest,
'spread': spread,
'throttle': throttle,
+ 'unary': unary,
'wrap': wrap
};
});
diff --git a/function/backflow.js b/function/backflow.js
deleted file mode 100644
index dd75d7b3f..000000000
--- a/function/backflow.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./flowRight"], function(flowRight) {
- return flowRight;
-});
diff --git a/function/bindAll.js b/function/bindAll.js
deleted file mode 100644
index 0900cafce..000000000
--- a/function/bindAll.js
+++ /dev/null
@@ -1,48 +0,0 @@
-define(['../internal/baseFlatten', '../internal/createWrapper', '../object/functions', './restParam'], function(baseFlatten, createWrapper, functions, restParam) {
-
- /** Used to compose bitmasks for wrapper metadata. */
- var BIND_FLAG = 1;
-
- /**
- * Binds methods of an object to the object itself, overwriting the existing
- * method. Method names may be specified as individual arguments or as arrays
- * of method names. If no method names are provided all enumerable function
- * properties, own and inherited, of `object` are bound.
- *
- * **Note:** This method does not set the "length" property of bound functions.
- *
- * @static
- * @memberOf _
- * @category Function
- * @param {Object} object The object to bind and assign the bound methods to.
- * @param {...(string|string[])} [methodNames] The object method names to bind,
- * specified as individual method names or arrays of method names.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var view = {
- * 'label': 'docs',
- * 'onClick': function() {
- * console.log('clicked ' + this.label);
- * }
- * };
- *
- * _.bindAll(view);
- * jQuery('#docs').on('click', view.onClick);
- * // => logs 'clicked docs' when the element is clicked
- */
- var bindAll = restParam(function(object, methodNames) {
- methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object);
-
- var index = -1,
- length = methodNames.length;
-
- while (++index < length) {
- var key = methodNames[index];
- object[key] = createWrapper(object[key], BIND_FLAG, object);
- }
- return object;
- });
-
- return bindAll;
-});
diff --git a/function/compose.js b/function/compose.js
deleted file mode 100644
index dd75d7b3f..000000000
--- a/function/compose.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./flowRight"], function(flowRight) {
- return flowRight;
-});
diff --git a/function/curry.js b/function/curry.js
deleted file mode 100644
index 194d80b2d..000000000
--- a/function/curry.js
+++ /dev/null
@@ -1,52 +0,0 @@
-define(['../internal/createCurry'], function(createCurry) {
-
- /** Used to compose bitmasks for wrapper metadata. */
- var CURRY_FLAG = 8;
-
- /**
- * Creates a function that accepts one or more arguments of `func` that when
- * called either invokes `func` returning its result, if all `func` arguments
- * have been provided, or returns a function that accepts one or more of the
- * remaining `func` arguments, and so on. The arity of `func` may be specified
- * if `func.length` is not sufficient.
- *
- * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
- * may be used as a placeholder for provided arguments.
- *
- * **Note:** This method does not set the "length" property of curried functions.
- *
- * @static
- * @memberOf _
- * @category Function
- * @param {Function} func The function to curry.
- * @param {number} [arity=func.length] The arity of `func`.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {Function} Returns the new curried function.
- * @example
- *
- * var abc = function(a, b, c) {
- * return [a, b, c];
- * };
- *
- * var curried = _.curry(abc);
- *
- * curried(1)(2)(3);
- * // => [1, 2, 3]
- *
- * curried(1, 2)(3);
- * // => [1, 2, 3]
- *
- * curried(1, 2, 3);
- * // => [1, 2, 3]
- *
- * // using placeholders
- * curried(1)(_, 3)(2);
- * // => [1, 2, 3]
- */
- var curry = createCurry(CURRY_FLAG);
-
- // Assign default placeholders.
- curry.placeholder = {};
-
- return curry;
-});
diff --git a/function/modArgs.js b/function/modArgs.js
deleted file mode 100644
index 556203784..000000000
--- a/function/modArgs.js
+++ /dev/null
@@ -1,56 +0,0 @@
-define(['../internal/arrayEvery', '../internal/baseFlatten', '../internal/baseIsFunction', './restParam'], function(arrayEvery, baseFlatten, baseIsFunction, 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);
- });
- });
-
- return modArgs;
-});
diff --git a/functions.js b/functions.js
new file mode 100644
index 000000000..0b7d89597
--- /dev/null
+++ b/functions.js
@@ -0,0 +1,29 @@
+define(['./internal/baseFunctions', './keys'], function(baseFunctions, keys) {
+
+ /**
+ * Creates an array of function property names from own enumerable properties
+ * of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @returns {Array} Returns the new array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = _.constant('a');
+ * this.b = _.constant('b');
+ * }
+ *
+ * Foo.prototype.c = _.constant('c');
+ *
+ * _.functions(new Foo);
+ * // => ['a', 'b']
+ */
+ function functions(object) {
+ return object == null ? [] : baseFunctions(object, keys(object));
+ }
+
+ return functions;
+});
diff --git a/functionsIn.js b/functionsIn.js
new file mode 100644
index 000000000..45a19097a
--- /dev/null
+++ b/functionsIn.js
@@ -0,0 +1,29 @@
+define(['./internal/baseFunctions', './keysIn'], function(baseFunctions, keysIn) {
+
+ /**
+ * Creates an array of function property names from own and inherited
+ * enumerable properties of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @returns {Array} Returns the new array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = _.constant('a');
+ * this.b = _.constant('b');
+ * }
+ *
+ * Foo.prototype.c = _.constant('c');
+ *
+ * _.functionsIn(new Foo);
+ * // => ['a', 'b', 'c']
+ */
+ function functionsIn(object) {
+ return object == null ? [] : baseFunctions(object, keysIn(object));
+ }
+
+ return functionsIn;
+});
diff --git a/object/get.js b/get.js
similarity index 77%
rename from object/get.js
rename to get.js
index 78a4b2b9a..7fbf7a18c 100644
--- a/object/get.js
+++ b/get.js
@@ -1,10 +1,10 @@
-define(['../internal/baseGet', '../internal/toPath'], function(baseGet, toPath) {
+define(['./internal/baseGet'], function(baseGet) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/**
- * Gets the property value at `path` of `object`. If the resolved value is
+ * Gets the value at `path` of `object`. If the resolved value is
* `undefined` the `defaultValue` is used in its place.
*
* @static
@@ -28,7 +28,7 @@ define(['../internal/baseGet', '../internal/toPath'], function(baseGet, toPath)
* // => 'default'
*/
function get(object, path, defaultValue) {
- var result = object == null ? undefined : baseGet(object, toPath(path), (path + ''));
+ var result = object == null ? undefined : baseGet(object, path);
return result === undefined ? defaultValue : result;
}
diff --git a/groupBy.js b/groupBy.js
new file mode 100644
index 000000000..32570952e
--- /dev/null
+++ b/groupBy.js
@@ -0,0 +1,39 @@
+define(['./internal/createAggregator'], function(createAggregator) {
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` through `iteratee`. The corresponding value
+ * of each key is an array of the elements responsible for generating the key.
+ * The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * _.groupBy([6.1, 4.2, 6.3], Math.floor);
+ * // => { '4': [4.2], '6': [6.1, 6.3] }
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.groupBy(['one', 'two', 'three'], 'length');
+ * // => { '3': ['one', 'two'], '5': ['three'] }
+ */
+ var groupBy = createAggregator(function(result, value, key) {
+ if (hasOwnProperty.call(result, key)) {
+ result[key].push(value);
+ } else {
+ result[key] = [value];
+ }
+ });
+
+ return groupBy;
+});
diff --git a/lang/gt.js b/gt.js
similarity index 100%
rename from lang/gt.js
rename to gt.js
diff --git a/lang/gte.js b/gte.js
similarity index 100%
rename from lang/gte.js
rename to gte.js
diff --git a/has.js b/has.js
new file mode 100644
index 000000000..b1d178157
--- /dev/null
+++ b/has.js
@@ -0,0 +1,34 @@
+define(['./internal/baseHas', './internal/hasPath'], function(baseHas, hasPath) {
+
+ /**
+ * Checks if `path` is a direct property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = { 'a': { 'b': { 'c': 3 } } };
+ * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
+ *
+ * _.has(object, 'a');
+ * // => true
+ *
+ * _.has(object, 'a.b.c');
+ * // => true
+ *
+ * _.has(object, ['a', 'b', 'c']);
+ * // => true
+ *
+ * _.has(other, 'a');
+ * // => false
+ */
+ function has(object, path) {
+ return hasPath(object, path, baseHas);
+ }
+
+ return has;
+});
diff --git a/hasIn.js b/hasIn.js
new file mode 100644
index 000000000..c389fcc9c
--- /dev/null
+++ b/hasIn.js
@@ -0,0 +1,33 @@
+define(['./internal/baseHasIn', './internal/hasPath'], function(baseHasIn, hasPath) {
+
+ /**
+ * Checks if `path` is a direct or inherited property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
+ *
+ * _.hasIn(object, 'a');
+ * // => true
+ *
+ * _.hasIn(object, 'a.b.c');
+ * // => true
+ *
+ * _.hasIn(object, ['a', 'b', 'c']);
+ * // => true
+ *
+ * _.hasIn(object, 'b');
+ * // => false
+ */
+ function hasIn(object, path) {
+ return hasPath(object, path, baseHasIn);
+ }
+
+ return hasIn;
+});
diff --git a/array/first.js b/head.js
similarity index 81%
rename from array/first.js
rename to head.js
index 46a09ec03..49e7808e4 100644
--- a/array/first.js
+++ b/head.js
@@ -8,21 +8,21 @@ define([], function() {
*
* @static
* @memberOf _
- * @alias head
+ * @alias first
* @category Array
* @param {Array} array The array to query.
* @returns {*} Returns the first element of `array`.
* @example
*
- * _.first([1, 2, 3]);
+ * _.head([1, 2, 3]);
* // => 1
*
- * _.first([]);
+ * _.head([]);
* // => undefined
*/
- function first(array) {
+ function head(array) {
return array ? array[0] : undefined;
}
- return first;
+ return head;
});
diff --git a/utility/identity.js b/identity.js
similarity index 94%
rename from utility/identity.js
rename to identity.js
index b4950530b..1a774cc4c 100644
--- a/utility/identity.js
+++ b/identity.js
@@ -5,7 +5,7 @@ define([], function() {
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {*} value Any value.
* @returns {*} Returns `value`.
* @example
diff --git a/number/inRange.js b/inRange.js
similarity index 60%
rename from number/inRange.js
rename to inRange.js
index d642463e7..ac9b80b16 100644
--- a/number/inRange.js
+++ b/inRange.js
@@ -1,23 +1,21 @@
-define([], function() {
+define(['./internal/baseInRange', './toNumber'], function(baseInRange, toNumber) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeMax = Math.max,
- nativeMin = Math.min;
-
/**
* Checks if `n` is between `start` and up to but not including, `end`. If
* `end` is not specified it's set to `start` with `start` then set to `0`.
+ * If `start` is greater than `end` the params are swapped to support
+ * negative ranges.
*
* @static
* @memberOf _
* @category Number
- * @param {number} n The number to check.
+ * @param {number} number The number to check.
* @param {number} [start=0] The start of the range.
* @param {number} end The end of the range.
- * @returns {boolean} Returns `true` if `n` is in the range, else `false`.
+ * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
* @example
*
* _.inRange(3, 2, 4);
@@ -37,16 +35,20 @@ define([], function() {
*
* _.inRange(5.2, 4);
* // => false
+ *
+ * _.inRange(-3, -2, -6);
+ * // => true
*/
- function inRange(value, start, end) {
- start = +start || 0;
+ function inRange(number, start, end) {
+ start = toNumber(start) || 0;
if (end === undefined) {
end = start;
start = 0;
} else {
- end = +end || 0;
+ end = toNumber(end) || 0;
}
- return value >= nativeMin(start, end) && value < nativeMax(start, end);
+ number = toNumber(number);
+ return baseInRange(number, start, end);
}
return inRange;
diff --git a/includes.js b/includes.js
new file mode 100644
index 000000000..f307dec15
--- /dev/null
+++ b/includes.js
@@ -0,0 +1,48 @@
+define(['./internal/baseIndexOf', './isArrayLike', './isString', './toInteger', './values'], function(baseIndexOf, isArrayLike, isString, toInteger, values) {
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMax = Math.max;
+
+ /**
+ * Checks if `value` is in `collection`. If `collection` is a string it's checked
+ * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * is used for equality comparisons. If `fromIndex` is negative, it's used as
+ * the offset from the end of `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to search.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
+ * @returns {boolean} Returns `true` if `value` is found, else `false`.
+ * @example
+ *
+ * _.includes([1, 2, 3], 1);
+ * // => true
+ *
+ * _.includes([1, 2, 3], 1, 2);
+ * // => false
+ *
+ * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
+ * // => true
+ *
+ * _.includes('pebbles', 'eb');
+ * // => true
+ */
+ function includes(collection, value, fromIndex, guard) {
+ collection = isArrayLike(collection) ? collection : values(collection);
+ fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
+
+ var length = collection.length;
+ if (fromIndex < 0) {
+ fromIndex = nativeMax(length + fromIndex, 0);
+ }
+ return isString(collection)
+ ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
+ : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
+ }
+
+ return includes;
+});
diff --git a/array/indexOf.js b/indexOf.js
similarity index 53%
rename from array/indexOf.js
rename to indexOf.js
index 64563c414..2d47efd8a 100644
--- a/array/indexOf.js
+++ b/indexOf.js
@@ -1,6 +1,6 @@
-define(['../internal/baseIndexOf', '../internal/binaryIndex'], function(baseIndexOf, binaryIndex) {
+define(['./internal/baseIndexOf', './toInteger'], function(baseIndexOf, toInteger) {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
@@ -15,8 +15,7 @@ define(['../internal/baseIndexOf', '../internal/binaryIndex'], function(baseInde
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=0] The index to search from or `true`
- * to perform a binary search on a sorted array.
+ * @param {number} [fromIndex=0] The index to search from.
* @returns {number} Returns the index of the matched value, else `-1`.
* @example
*
@@ -26,27 +25,17 @@ define(['../internal/baseIndexOf', '../internal/binaryIndex'], function(baseInde
* // using `fromIndex`
* _.indexOf([1, 2, 1, 2], 2, 2);
* // => 3
- *
- * // performing a binary search
- * _.indexOf([1, 1, 2, 2], 2, true);
- * // => 2
*/
function indexOf(array, value, fromIndex) {
var length = array ? array.length : 0;
if (!length) {
return -1;
}
- if (typeof fromIndex == 'number') {
- fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
- } else if (fromIndex) {
- var index = binaryIndex(array, value);
- if (index < length &&
- (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
- return index;
- }
- return -1;
+ fromIndex = toInteger(fromIndex);
+ if (fromIndex < 0) {
+ fromIndex = nativeMax(length + fromIndex, 0);
}
- return baseIndexOf(array, value, fromIndex || 0);
+ return baseIndexOf(array, value, fromIndex);
}
return indexOf;
diff --git a/array/initial.js b/initial.js
similarity index 100%
rename from array/initial.js
rename to initial.js
diff --git a/internal/Hash.js b/internal/Hash.js
new file mode 100644
index 000000000..f64429307
--- /dev/null
+++ b/internal/Hash.js
@@ -0,0 +1,18 @@
+define(['./nativeCreate'], function(nativeCreate) {
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /**
+ * Creates an hash object.
+ *
+ * @private
+ * @returns {Object} Returns the new hash object.
+ */
+ function Hash() {}
+
+ // Avoid inheriting from `Object.prototype` when possible.
+ Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
+
+ return Hash;
+});
diff --git a/internal/LazyWrapper.js b/internal/LazyWrapper.js
index 3e985376d..acf1fbdbd 100644
--- a/internal/LazyWrapper.js
+++ b/internal/LazyWrapper.js
@@ -1,7 +1,7 @@
define(['./baseCreate', './baseLodash'], function(baseCreate, baseLodash) {
- /** Used as references for `-Infinity` and `Infinity`. */
- var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
+ /** Used as references for the maximum length and index of an array. */
+ var MAX_ARRAY_LENGTH = 4294967295;
/**
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
@@ -15,7 +15,7 @@ define(['./baseCreate', './baseLodash'], function(baseCreate, baseLodash) {
this.__dir__ = 1;
this.__filtered__ = false;
this.__iteratees__ = [];
- this.__takeCount__ = POSITIVE_INFINITY;
+ this.__takeCount__ = MAX_ARRAY_LENGTH;
this.__views__ = [];
}
diff --git a/internal/LodashWrapper.js b/internal/LodashWrapper.js
index d03a968a9..d72ec141c 100644
--- a/internal/LodashWrapper.js
+++ b/internal/LodashWrapper.js
@@ -1,17 +1,21 @@
define(['./baseCreate', './baseLodash'], function(baseCreate, baseLodash) {
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
/**
* The base constructor for creating `lodash` wrapper objects.
*
* @private
* @param {*} value The value to wrap.
* @param {boolean} [chainAll] Enable chaining for all wrapper methods.
- * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.
*/
- function LodashWrapper(value, chainAll, actions) {
+ function LodashWrapper(value, chainAll) {
this.__wrapped__ = value;
- this.__actions__ = actions || [];
+ this.__actions__ = [];
this.__chain__ = !!chainAll;
+ this.__index__ = 0;
+ this.__values__ = undefined;
}
LodashWrapper.prototype = baseCreate(baseLodash.prototype);
diff --git a/internal/Map.js b/internal/Map.js
new file mode 100644
index 000000000..b97b8769f
--- /dev/null
+++ b/internal/Map.js
@@ -0,0 +1,7 @@
+define(['./getNative', './root'], function(getNative, root) {
+
+ /* Built-in method references that are verified to be native. */
+ var Map = getNative(root, 'Map');
+
+ return Map;
+});
diff --git a/internal/MapCache.js b/internal/MapCache.js
index c9d287c8c..94780365a 100644
--- a/internal/MapCache.js
+++ b/internal/MapCache.js
@@ -1,18 +1,24 @@
-define(['./mapDelete', './mapGet', './mapHas', './mapSet'], function(mapDelete, mapGet, mapHas, mapSet) {
+define(['./mapClear', './mapDelete', './mapGet', './mapHas', './mapSet'], function(mapClear, mapDelete, mapGet, mapHas, mapSet) {
/**
- * Creates a cache object to store key/value pairs.
+ * Creates a map cache object to store key-value pairs.
*
* @private
- * @static
- * @name Cache
- * @memberOf _.memoize
+ * @param {Array} [values] The values to cache.
*/
- function MapCache() {
- this.__data__ = {};
+ function MapCache(values) {
+ var index = -1,
+ length = values ? values.length : 0;
+
+ this.clear();
+ while (++index < length) {
+ var entry = values[index];
+ this.set(entry[0], entry[1]);
+ }
}
- // Add functions to the `Map` cache.
+ // Add functions to the `MapCache`.
+ MapCache.prototype.clear = mapClear;
MapCache.prototype['delete'] = mapDelete;
MapCache.prototype.get = mapGet;
MapCache.prototype.has = mapHas;
diff --git a/internal/Reflect.js b/internal/Reflect.js
new file mode 100644
index 000000000..8984e2e00
--- /dev/null
+++ b/internal/Reflect.js
@@ -0,0 +1,7 @@
+define(['./root'], function(root) {
+
+ /** Built-in value references. */
+ var Reflect = root.Reflect;
+
+ return Reflect;
+});
diff --git a/internal/Set.js b/internal/Set.js
new file mode 100644
index 000000000..72c6c2298
--- /dev/null
+++ b/internal/Set.js
@@ -0,0 +1,7 @@
+define(['./getNative', './root'], function(getNative, root) {
+
+ /* Built-in method references that are verified to be native. */
+ var Set = getNative(root, 'Set');
+
+ return Set;
+});
diff --git a/internal/SetCache.js b/internal/SetCache.js
index d1058be6a..cf3e4b3ae 100644
--- a/internal/SetCache.js
+++ b/internal/SetCache.js
@@ -1,28 +1,23 @@
-define(['./cachePush', './getNative', './root'], function(cachePush, getNative, root) {
-
- /** Native method references. */
- var Set = getNative(root, 'Set');
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeCreate = getNative(Object, 'create');
+define(['./MapCache', './cachePush'], function(MapCache, cachePush) {
/**
*
- * Creates a cache object to store unique values.
+ * Creates a set cache object to store unique values.
*
* @private
* @param {Array} [values] The values to cache.
*/
function SetCache(values) {
- var length = values ? values.length : 0;
+ var index = -1,
+ length = values ? values.length : 0;
- this.data = { 'hash': nativeCreate(null), 'set': new Set };
- while (length--) {
- this.push(values[length]);
+ this.__data__ = new MapCache;
+ while (++index < length) {
+ this.push(values[index]);
}
}
- // Add functions to the `Set` cache.
+ // Add functions to the `SetCache`.
SetCache.prototype.push = cachePush;
return SetCache;
diff --git a/internal/Stack.js b/internal/Stack.js
new file mode 100644
index 000000000..c223dfea6
--- /dev/null
+++ b/internal/Stack.js
@@ -0,0 +1,28 @@
+define(['./stackClear', './stackDelete', './stackGet', './stackHas', './stackSet'], function(stackClear, stackDelete, stackGet, stackHas, stackSet) {
+
+ /**
+ * Creates a stack cache object to store key-value pairs.
+ *
+ * @private
+ * @param {Array} [values] The values to cache.
+ */
+ function Stack(values) {
+ var index = -1,
+ length = values ? values.length : 0;
+
+ this.clear();
+ while (++index < length) {
+ var entry = values[index];
+ this.set(entry[0], entry[1]);
+ }
+ }
+
+ // Add functions to the `Stack` cache.
+ Stack.prototype.clear = stackClear;
+ Stack.prototype['delete'] = stackDelete;
+ Stack.prototype.get = stackGet;
+ Stack.prototype.has = stackHas;
+ Stack.prototype.set = stackSet;
+
+ return Stack;
+});
diff --git a/internal/Uint8Array.js b/internal/Uint8Array.js
new file mode 100644
index 000000000..b462cd427
--- /dev/null
+++ b/internal/Uint8Array.js
@@ -0,0 +1,7 @@
+define(['./root'], function(root) {
+
+ /** Built-in value references. */
+ var Uint8Array = root.Uint8Array;
+
+ return Uint8Array;
+});
diff --git a/internal/WeakMap.js b/internal/WeakMap.js
new file mode 100644
index 000000000..f9725d3ec
--- /dev/null
+++ b/internal/WeakMap.js
@@ -0,0 +1,7 @@
+define(['./getNative', './root'], function(getNative, root) {
+
+ /* Built-in method references that are verified to be native. */
+ var WeakMap = getNative(root, 'WeakMap');
+
+ return WeakMap;
+});
diff --git a/internal/_Symbol.js b/internal/_Symbol.js
new file mode 100644
index 000000000..4811a706b
--- /dev/null
+++ b/internal/_Symbol.js
@@ -0,0 +1,7 @@
+define(['./root'], function(root) {
+
+ /** Built-in value references. */
+ var _Symbol = root.Symbol;
+
+ return _Symbol;
+});
diff --git a/internal/addMapEntry.js b/internal/addMapEntry.js
new file mode 100644
index 000000000..5cf2424fc
--- /dev/null
+++ b/internal/addMapEntry.js
@@ -0,0 +1,17 @@
+define([], function() {
+
+ /**
+ * Adds the key-value `pair` to `map`.
+ *
+ * @private
+ * @param {Object} map The map to modify.
+ * @param {Array} pair The key-value pair to add.
+ * @returns {Object} Returns `map`.
+ */
+ function addMapEntry(map, pair) {
+ map.set(pair[0], pair[1]);
+ return map;
+ }
+
+ return addMapEntry;
+});
diff --git a/internal/addSetEntry.js b/internal/addSetEntry.js
new file mode 100644
index 000000000..cd9ca4bc4
--- /dev/null
+++ b/internal/addSetEntry.js
@@ -0,0 +1,17 @@
+define([], function() {
+
+ /**
+ * Adds `value` to `set`.
+ *
+ * @private
+ * @param {Object} set The set to modify.
+ * @param {*} value The value to add.
+ * @returns {Object} Returns `set`.
+ */
+ function addSetEntry(set, value) {
+ set.add(value);
+ return set;
+ }
+
+ return addSetEntry;
+});
diff --git a/internal/apply.js b/internal/apply.js
new file mode 100644
index 000000000..54cdb10c7
--- /dev/null
+++ b/internal/apply.js
@@ -0,0 +1,25 @@
+define([], function() {
+
+ /**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */
+ function apply(func, thisArg, args) {
+ var length = args ? args.length : 0;
+ switch (length) {
+ case 0: return func.call(thisArg);
+ case 1: return func.call(thisArg, args[0]);
+ case 2: return func.call(thisArg, args[0], args[1]);
+ case 3: return func.call(thisArg, args[0], args[1], args[2]);
+ }
+ return func.apply(thisArg, args);
+ }
+
+ return apply;
+});
diff --git a/internal/arrayConcat.js b/internal/arrayConcat.js
index a2cd19f71..b6ffb5ff4 100644
--- a/internal/arrayConcat.js
+++ b/internal/arrayConcat.js
@@ -1,11 +1,11 @@
define([], function() {
/**
- * Creates a new array joining `array` with `other`.
+ * Creates a new array concatenating `array` with `other`.
*
* @private
- * @param {Array} array The array to join.
- * @param {Array} other The other array to join.
+ * @param {Array} array The first array to concatenate.
+ * @param {Array} other The second array to concatenate.
* @returns {Array} Returns the new concatenated array.
*/
function arrayConcat(array, other) {
diff --git a/internal/arrayEach.js b/internal/arrayEach.js
index b5653b5de..ee8271887 100644
--- a/internal/arrayEach.js
+++ b/internal/arrayEach.js
@@ -1,8 +1,8 @@
define([], function() {
/**
- * A specialized version of `_.forEach` for arrays without support for callback
- * shorthands and `this` binding.
+ * A specialized version of `_.forEach` for arrays without support for
+ * iteratee shorthands.
*
* @private
* @param {Array} array The array to iterate over.
diff --git a/internal/arrayEachRight.js b/internal/arrayEachRight.js
index 81818a671..1a64f86fc 100644
--- a/internal/arrayEachRight.js
+++ b/internal/arrayEachRight.js
@@ -2,7 +2,7 @@ define([], function() {
/**
* A specialized version of `_.forEachRight` for arrays without support for
- * callback shorthands and `this` binding.
+ * iteratee shorthands.
*
* @private
* @param {Array} array The array to iterate over.
diff --git a/internal/arrayEvery.js b/internal/arrayEvery.js
index 3a3375273..a0268bd90 100644
--- a/internal/arrayEvery.js
+++ b/internal/arrayEvery.js
@@ -1,14 +1,13 @@
define([], function() {
/**
- * A specialized version of `_.every` for arrays without support for callback
- * shorthands and `this` binding.
+ * A specialized version of `_.every` for arrays without support for
+ * iteratee shorthands.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
*/
function arrayEvery(array, predicate) {
var index = -1,
diff --git a/internal/arrayExtremum.js b/internal/arrayExtremum.js
deleted file mode 100644
index 1062a8494..000000000
--- a/internal/arrayExtremum.js
+++ /dev/null
@@ -1,33 +0,0 @@
-define([], function() {
-
- /**
- * A specialized version of `baseExtremum` for arrays which invokes `iteratee`
- * with one argument: (value).
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {Function} comparator The function used to compare values.
- * @param {*} exValue The initial extremum value.
- * @returns {*} Returns the extremum value.
- */
- function arrayExtremum(array, iteratee, comparator, exValue) {
- var index = -1,
- length = array.length,
- computed = exValue,
- result = computed;
-
- while (++index < length) {
- var value = array[index],
- current = +iteratee(value);
-
- if (comparator(current, computed)) {
- computed = current;
- result = value;
- }
- }
- return result;
- }
-
- return arrayExtremum;
-});
diff --git a/internal/arrayFilter.js b/internal/arrayFilter.js
index 82484f020..a43715489 100644
--- a/internal/arrayFilter.js
+++ b/internal/arrayFilter.js
@@ -1,8 +1,8 @@
define([], function() {
/**
- * A specialized version of `_.filter` for arrays without support for callback
- * shorthands and `this` binding.
+ * A specialized version of `_.filter` for arrays without support for
+ * iteratee shorthands.
*
* @private
* @param {Array} array The array to iterate over.
diff --git a/internal/arrayIncludes.js b/internal/arrayIncludes.js
new file mode 100644
index 000000000..517ee1751
--- /dev/null
+++ b/internal/arrayIncludes.js
@@ -0,0 +1,17 @@
+define(['./baseIndexOf'], function(baseIndexOf) {
+
+ /**
+ * A specialized version of `_.includes` for arrays without support for
+ * specifying an index to search from.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} target The value to search for.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */
+ function arrayIncludes(array, value) {
+ return !!array.length && baseIndexOf(array, value, 0) > -1;
+ }
+
+ return arrayIncludes;
+});
diff --git a/internal/arrayIncludesWith.js b/internal/arrayIncludesWith.js
new file mode 100644
index 000000000..9ed823eb4
--- /dev/null
+++ b/internal/arrayIncludesWith.js
@@ -0,0 +1,26 @@
+define([], function() {
+
+ /**
+ * A specialized version of `_.includesWith` for arrays without support for
+ * specifying an index to search from.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} target The value to search for.
+ * @param {Function} comparator The comparator invoked per element.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */
+ function arrayIncludesWith(array, value, comparator) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (comparator(value, array[index])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return arrayIncludesWith;
+});
diff --git a/internal/arrayMap.js b/internal/arrayMap.js
index d9f287fa0..08fab1775 100644
--- a/internal/arrayMap.js
+++ b/internal/arrayMap.js
@@ -1,8 +1,8 @@
define([], function() {
/**
- * A specialized version of `_.map` for arrays without support for callback
- * shorthands and `this` binding.
+ * A specialized version of `_.map` for arrays without support for iteratee
+ * shorthands.
*
* @private
* @param {Array} array The array to iterate over.
diff --git a/internal/arrayReduce.js b/internal/arrayReduce.js
index 52b03c1f6..9d31e83c8 100644
--- a/internal/arrayReduce.js
+++ b/internal/arrayReduce.js
@@ -1,15 +1,14 @@
define([], function() {
/**
- * A specialized version of `_.reduce` for arrays without support for callback
- * shorthands and `this` binding.
+ * A specialized version of `_.reduce` for arrays without support for
+ * iteratee shorthands.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {boolean} [initFromArray] Specify using the first element of `array`
- * as the initial value.
+ * @param {boolean} [initFromArray] Specify using the first element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduce(array, iteratee, accumulator, initFromArray) {
diff --git a/internal/arrayReduceRight.js b/internal/arrayReduceRight.js
index fe9edbf64..01d93b792 100644
--- a/internal/arrayReduceRight.js
+++ b/internal/arrayReduceRight.js
@@ -2,14 +2,13 @@ define([], function() {
/**
* A specialized version of `_.reduceRight` for arrays without support for
- * callback shorthands and `this` binding.
+ * iteratee shorthands.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {boolean} [initFromArray] Specify using the last element of `array`
- * as the initial value.
+ * @param {boolean} [initFromArray] Specify using the last element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
diff --git a/internal/arraySome.js b/internal/arraySome.js
index a5f00f0cc..2b15a25a1 100644
--- a/internal/arraySome.js
+++ b/internal/arraySome.js
@@ -1,14 +1,13 @@
define([], function() {
/**
- * A specialized version of `_.some` for arrays without support for callback
- * shorthands and `this` binding.
+ * A specialized version of `_.some` for arrays without support for iteratee
+ * shorthands.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
*/
function arraySome(array, predicate) {
var index = -1,
diff --git a/internal/arraySum.js b/internal/arraySum.js
deleted file mode 100644
index f48a3c7e6..000000000
--- a/internal/arraySum.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define([], function() {
-
- /**
- * 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, iteratee) {
- var length = array.length,
- result = 0;
-
- while (length--) {
- result += +iteratee(array[length]) || 0;
- }
- return result;
- }
-
- return arraySum;
-});
diff --git a/internal/assignDefaults.js b/internal/assignDefaults.js
deleted file mode 100644
index 24a0503e2..000000000
--- a/internal/assignDefaults.js
+++ /dev/null
@@ -1,19 +0,0 @@
-define([], function() {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Used by `_.defaults` to customize its `_.assign` 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 assignDefaults(objectValue, sourceValue) {
- return objectValue === undefined ? sourceValue : objectValue;
- }
-
- return assignDefaults;
-});
diff --git a/internal/assignInDefaults.js b/internal/assignInDefaults.js
new file mode 100644
index 000000000..dc3c34e66
--- /dev/null
+++ b/internal/assignInDefaults.js
@@ -0,0 +1,31 @@
+define(['../eq'], function(eq) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /**
+ * Used by `_.defaults` to customize its `_.assignIn` use.
+ *
+ * @private
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to assign.
+ * @param {Object} object The parent object of `objValue`.
+ * @returns {*} Returns the value to assign.
+ */
+ function assignInDefaults(objValue, srcValue, key, object) {
+ if (objValue === undefined ||
+ (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+ return srcValue;
+ }
+ return objValue;
+ }
+
+ return assignInDefaults;
+});
diff --git a/internal/assignMergeValue.js b/internal/assignMergeValue.js
new file mode 100644
index 000000000..43de9f857
--- /dev/null
+++ b/internal/assignMergeValue.js
@@ -0,0 +1,22 @@
+define(['../eq'], function(eq) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This function is like `assignValue` except that it doesn't assign `undefined` values.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+ function assignMergeValue(object, key, value) {
+ if ((value !== undefined && !eq(object[key], value)) ||
+ (typeof key == 'number' && value === undefined && !(key in object))) {
+ object[key] = value;
+ }
+ }
+
+ return assignMergeValue;
+});
diff --git a/internal/assignOwnDefaults.js b/internal/assignOwnDefaults.js
deleted file mode 100644
index 2a6fe5681..000000000
--- a/internal/assignOwnDefaults.js
+++ /dev/null
@@ -1,32 +0,0 @@
-define([], function() {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty = objectProto.hasOwnProperty;
-
- /**
- * Used by `_.template` to customize its `_.assign` use.
- *
- * **Note:** This function is like `assignDefaults` except that it ignores
- * inherited property values when checking if a property is `undefined`.
- *
- * @private
- * @param {*} objectValue The destination object property value.
- * @param {*} sourceValue The source object property value.
- * @param {string} key The key associated with the object and source values.
- * @param {Object} object The destination object.
- * @returns {*} Returns the value to assign to the destination object.
- */
- function assignOwnDefaults(objectValue, sourceValue, key, object) {
- return (objectValue === undefined || !hasOwnProperty.call(object, key))
- ? sourceValue
- : objectValue;
- }
-
- return assignOwnDefaults;
-});
diff --git a/internal/assignValue.js b/internal/assignValue.js
new file mode 100644
index 000000000..710222dcb
--- /dev/null
+++ b/internal/assignValue.js
@@ -0,0 +1,32 @@
+define(['../eq'], function(eq) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /**
+ * Assigns `value` to `key` of `object` if the existing value is not equivalent
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+ function assignValue(object, key, value) {
+ var objValue = object[key];
+ if ((!eq(objValue, value) ||
+ (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
+ (value === undefined && !(key in object))) {
+ object[key] = value;
+ }
+ }
+
+ return assignValue;
+});
diff --git a/internal/assignWith.js b/internal/assignWith.js
deleted file mode 100644
index 69ce0cc7c..000000000
--- a/internal/assignWith.js
+++ /dev/null
@@ -1,36 +0,0 @@
-define(['../object/keys'], function(keys) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * A specialized version of `_.assign` for customizing assigned values without
- * support for argument juggling, multiple sources, and `this` binding `customizer`
- * functions.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {Function} customizer The function to customize assigned values.
- * @returns {Object} Returns `object`.
- */
- function assignWith(object, source, customizer) {
- var index = -1,
- props = keys(source),
- length = props.length;
-
- while (++index < length) {
- var key = props[index],
- value = object[key],
- result = customizer(value, source[key], key, object, source);
-
- if ((result === result ? (result !== value) : (value === value)) ||
- (value === undefined && !(key in object))) {
- object[key] = result;
- }
- }
- return object;
- }
-
- return assignWith;
-});
diff --git a/internal/assocDelete.js b/internal/assocDelete.js
new file mode 100644
index 000000000..52676bd91
--- /dev/null
+++ b/internal/assocDelete.js
@@ -0,0 +1,32 @@
+define(['./assocIndexOf'], function(assocIndexOf) {
+
+ /** Used for built-in method references. */
+ var arrayProto = Array.prototype;
+
+ /** Built-in value references. */
+ var splice = arrayProto.splice;
+
+ /**
+ * Removes `key` and its value from the associative array.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function assocDelete(array, key) {
+ var index = assocIndexOf(array, key);
+ if (index < 0) {
+ return false;
+ }
+ var lastIndex = array.length - 1;
+ if (index == lastIndex) {
+ array.pop();
+ } else {
+ splice.call(array, index, 1);
+ }
+ return true;
+ }
+
+ return assocDelete;
+});
diff --git a/internal/assocGet.js b/internal/assocGet.js
new file mode 100644
index 000000000..037e0e4d8
--- /dev/null
+++ b/internal/assocGet.js
@@ -0,0 +1,20 @@
+define(['./assocIndexOf'], function(assocIndexOf) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Gets the associative array value for `key`.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function assocGet(array, key) {
+ var index = assocIndexOf(array, key);
+ return index < 0 ? undefined : array[index][1];
+ }
+
+ return assocGet;
+});
diff --git a/internal/assocHas.js b/internal/assocHas.js
new file mode 100644
index 000000000..84613e6fc
--- /dev/null
+++ b/internal/assocHas.js
@@ -0,0 +1,16 @@
+define(['./assocIndexOf'], function(assocIndexOf) {
+
+ /**
+ * Checks if an associative array value for `key` exists.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function assocHas(array, key) {
+ return assocIndexOf(array, key) > -1;
+ }
+
+ return assocHas;
+});
diff --git a/internal/assocIndexOf.js b/internal/assocIndexOf.js
new file mode 100644
index 000000000..fa6a4cd93
--- /dev/null
+++ b/internal/assocIndexOf.js
@@ -0,0 +1,23 @@
+define(['../eq'], function(eq) {
+
+ /**
+ * Gets the index at which the first occurrence of `key` is found in `array`
+ * of key-value pairs.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} key The key to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function assocIndexOf(array, key) {
+ var length = array.length;
+ while (length--) {
+ if (eq(array[length][0], key)) {
+ return length;
+ }
+ }
+ return -1;
+ }
+
+ return assocIndexOf;
+});
diff --git a/internal/assocSet.js b/internal/assocSet.js
new file mode 100644
index 000000000..dbb95c0e7
--- /dev/null
+++ b/internal/assocSet.js
@@ -0,0 +1,21 @@
+define(['./assocIndexOf'], function(assocIndexOf) {
+
+ /**
+ * Sets the associative array `key` to `value`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ */
+ function assocSet(array, key, value) {
+ var index = assocIndexOf(array, key);
+ if (index < 0) {
+ array.push([key, value]);
+ } else {
+ array[index][1] = value;
+ }
+ }
+
+ return assocSet;
+});
diff --git a/internal/baseAssign.js b/internal/baseAssign.js
index ed4b33286..52375f445 100644
--- a/internal/baseAssign.js
+++ b/internal/baseAssign.js
@@ -1,8 +1,8 @@
-define(['./baseCopy', '../object/keys'], function(baseCopy, keys) {
+define(['./copyObject', '../keys'], function(copyObject, keys) {
/**
- * The base implementation of `_.assign` without support for argument juggling,
- * multiple sources, and `customizer` functions.
+ * The base implementation of `_.assign` without support for multiple sources
+ * or `customizer` functions.
*
* @private
* @param {Object} object The destination object.
@@ -10,9 +10,7 @@ define(['./baseCopy', '../object/keys'], function(baseCopy, keys) {
* @returns {Object} Returns `object`.
*/
function baseAssign(object, source) {
- return source == null
- ? object
- : baseCopy(source, keys(source), object);
+ return object && copyObject(source, keys(source), object);
}
return baseAssign;
diff --git a/internal/baseAt.js b/internal/baseAt.js
index 015b09c0b..065e76028 100644
--- a/internal/baseAt.js
+++ b/internal/baseAt.js
@@ -1,32 +1,24 @@
-define(['./isArrayLike', './isIndex'], function(isArrayLike, isIndex) {
+define(['../get'], function(get) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/**
- * The base implementation of `_.at` without support for string collections
- * and individual key arguments.
+ * The base implementation of `_.at` without support for individual paths.
*
* @private
- * @param {Array|Object} collection The collection to iterate over.
- * @param {number[]|string[]} props The property names or indexes of elements to pick.
+ * @param {Object} object The object to iterate over.
+ * @param {string[]} paths The property paths of elements to pick.
* @returns {Array} Returns the new array of picked elements.
*/
- function baseAt(collection, props) {
+ function baseAt(object, paths) {
var index = -1,
- isNil = collection == null,
- isArr = !isNil && isArrayLike(collection),
- length = isArr ? collection.length : 0,
- propsLength = props.length,
- result = Array(propsLength);
+ isNil = object == null,
+ length = paths.length,
+ result = Array(length);
- while(++index < propsLength) {
- var key = props[index];
- if (isArr) {
- result[index] = isIndex(key, length) ? collection[key] : undefined;
- } else {
- result[index] = isNil ? undefined : collection[key];
- }
+ while (++index < length) {
+ result[index] = isNil ? undefined : get(object, paths[index]);
}
return result;
}
diff --git a/internal/baseCallback.js b/internal/baseCallback.js
deleted file mode 100644
index 64bb13cad..000000000
--- a/internal/baseCallback.js
+++ /dev/null
@@ -1,35 +0,0 @@
-define(['./baseMatches', './baseMatchesProperty', './bindCallback', '../utility/identity', '../utility/property'], function(baseMatches, baseMatchesProperty, bindCallback, identity, property) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * The base implementation of `_.callback` which supports specifying the
- * number of arguments to provide to `func`.
- *
- * @private
- * @param {*} [func=_.identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {number} [argCount] The number of arguments to provide to `func`.
- * @returns {Function} Returns the callback.
- */
- function baseCallback(func, thisArg, argCount) {
- var type = typeof func;
- if (type == 'function') {
- return thisArg === undefined
- ? func
- : bindCallback(func, thisArg, argCount);
- }
- if (func == null) {
- return identity;
- }
- if (type == 'object') {
- return baseMatches(func);
- }
- return thisArg === undefined
- ? property(func)
- : baseMatchesProperty(func, thisArg);
- }
-
- return baseCallback;
-});
diff --git a/internal/baseClamp.js b/internal/baseClamp.js
new file mode 100644
index 000000000..552245a16
--- /dev/null
+++ b/internal/baseClamp.js
@@ -0,0 +1,28 @@
+define([], function() {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
+ *
+ * @private
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
+ */
+ function baseClamp(number, lower, upper) {
+ if (number === number) {
+ if (upper !== undefined) {
+ number = number <= upper ? number : upper;
+ }
+ if (lower !== undefined) {
+ number = number >= lower ? number : lower;
+ }
+ }
+ return number;
+ }
+
+ return baseClamp;
+});
diff --git a/internal/baseClone.js b/internal/baseClone.js
index 71a842325..8616fcff0 100644
--- a/internal/baseClone.js
+++ b/internal/baseClone.js
@@ -1,4 +1,4 @@
-define(['./arrayCopy', './arrayEach', './baseAssign', './baseForOwn', './initCloneArray', './initCloneByTag', './initCloneObject', '../lang/isArray', '../lang/isObject'], function(arrayCopy, arrayEach, baseAssign, baseForOwn, initCloneArray, initCloneByTag, initCloneObject, isArray, isObject) {
+define(['./Stack', './arrayEach', './assignValue', './baseAssign', './baseForOwn', './copyArray', './copySymbols', './getTag', './initCloneArray', './initCloneByTag', './initCloneObject', '../isArray', './isHostObject', '../isObject'], function(Stack, arrayEach, assignValue, baseAssign, baseForOwn, copyArray, copySymbols, getTag, initCloneArray, initCloneByTag, initCloneObject, isArray, isHostObject, isObject) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -10,12 +10,14 @@ define(['./arrayCopy', './arrayEach', './baseAssign', './baseForOwn', './initClo
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
+ genTag = '[object GeneratorFunction]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
+ symbolTag = '[object Symbol]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
@@ -36,41 +38,32 @@ define(['./arrayCopy', './arrayEach', './baseAssign', './baseForOwn', './initClo
cloneableTags[dateTag] = cloneableTags[float32Tag] =
cloneableTags[float64Tag] = cloneableTags[int8Tag] =
cloneableTags[int16Tag] = cloneableTags[int32Tag] =
- cloneableTags[numberTag] = cloneableTags[objectTag] =
- cloneableTags[regexpTag] = cloneableTags[stringTag] =
- cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
- cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+ cloneableTags[mapTag] = cloneableTags[numberTag] =
+ cloneableTags[objectTag] = cloneableTags[regexpTag] =
+ cloneableTags[setTag] = cloneableTags[stringTag] =
+ cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
+ cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
+ cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] =
- cloneableTags[mapTag] = cloneableTags[setTag] =
cloneableTags[weakMapTag] = false;
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
/**
- * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
- * of values.
- */
- var objToString = objectProto.toString;
-
- /**
- * The base implementation of `_.clone` without support for argument juggling
- * and `this` binding `customizer` functions.
+ * The base implementation of `_.clone` and `_.cloneDeep` which tracks
+ * traversed objects.
*
* @private
* @param {*} value The value to clone.
* @param {boolean} [isDeep] Specify a deep clone.
- * @param {Function} [customizer] The function to customize cloning values.
+ * @param {Function} [customizer] The function to customize cloning.
* @param {string} [key] The key of `value`.
- * @param {Object} [object] The object `value` belongs to.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates clones with source counterparts.
+ * @param {Object} [object] The parent object of `value`.
+ * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
* @returns {*} Returns the cloned value.
*/
- function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
+ function baseClone(value, isDeep, customizer, key, object, stack) {
var result;
if (customizer) {
- result = object ? customizer(value, key, object) : customizer(value);
+ result = object ? customizer(value, key, object, stack) : customizer(value);
}
if (result !== undefined) {
return result;
@@ -82,16 +75,19 @@ define(['./arrayCopy', './arrayEach', './baseAssign', './baseForOwn', './initClo
if (isArr) {
result = initCloneArray(value);
if (!isDeep) {
- return arrayCopy(value, result);
+ return copyArray(value, result);
}
} else {
- var tag = objToString.call(value),
- isFunc = tag == funcTag;
+ var tag = getTag(value),
+ isFunc = tag == funcTag || tag == genTag;
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+ if (isHostObject(value)) {
+ return object ? value : {};
+ }
result = initCloneObject(isFunc ? {} : value);
if (!isDeep) {
- return baseAssign(result, value);
+ return copySymbols(value, baseAssign(result, value));
}
} else {
return cloneableTags[tag]
@@ -100,24 +96,18 @@ define(['./arrayCopy', './arrayEach', './baseAssign', './baseForOwn', './initClo
}
}
// Check for circular references and return its corresponding clone.
- stackA || (stackA = []);
- stackB || (stackB = []);
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == value) {
- return stackB[length];
- }
+ stack || (stack = new Stack);
+ var stacked = stack.get(value);
+ if (stacked) {
+ return stacked;
}
- // Add the source value to the stack of traversed objects and associate it with its clone.
- stackA.push(value);
- stackB.push(result);
+ stack.set(value, result);
// Recursively populate clone (susceptible to call stack limits).
(isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
- result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
+ assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
});
- return result;
+ return isArr ? result : copySymbols(value, result);
}
return baseClone;
diff --git a/internal/baseCompareAscending.js b/internal/baseCompareAscending.js
deleted file mode 100644
index 196e170ce..000000000
--- a/internal/baseCompareAscending.js
+++ /dev/null
@@ -1,40 +0,0 @@
-define([], function() {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * The base implementation of `compareAscending` which compares values and
- * sorts them in ascending order without guaranteeing a stable sort.
- *
- * @private
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @returns {number} Returns the sort order indicator for `value`.
- */
- function baseCompareAscending(value, other) {
- if (value !== other) {
- var valIsNull = value === null,
- valIsUndef = value === undefined,
- valIsReflexive = value === value;
-
- var othIsNull = other === null,
- othIsUndef = other === undefined,
- othIsReflexive = other === other;
-
- if ((value > other && !othIsNull) || !valIsReflexive ||
- (valIsNull && !othIsUndef && othIsReflexive) ||
- (valIsUndef && othIsReflexive)) {
- return 1;
- }
- if ((value < other && !valIsNull) || !othIsReflexive ||
- (othIsNull && !valIsUndef && valIsReflexive) ||
- (othIsUndef && valIsReflexive)) {
- return -1;
- }
- }
- return 0;
- }
-
- return baseCompareAscending;
-});
diff --git a/internal/baseConforms.js b/internal/baseConforms.js
new file mode 100644
index 000000000..64405f8b1
--- /dev/null
+++ b/internal/baseConforms.js
@@ -0,0 +1,36 @@
+define(['../keys'], function(keys) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * The base implementation of `_.conforms` which doesn't clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {Function} Returns the new function.
+ */
+ function baseConforms(source) {
+ var props = keys(source),
+ length = props.length;
+
+ return function(object) {
+ if (object == null) {
+ return !length;
+ }
+ var index = length;
+ while (index--) {
+ var key = props[index],
+ predicate = source[key],
+ value = object[key];
+
+ if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
+ return false;
+ }
+ }
+ return true;
+ };
+ }
+
+ return baseConforms;
+});
diff --git a/internal/baseCreate.js b/internal/baseCreate.js
index f88b921ec..bf5cc336a 100644
--- a/internal/baseCreate.js
+++ b/internal/baseCreate.js
@@ -1,4 +1,4 @@
-define(['../lang/isObject'], function(isObject) {
+define(['../isObject'], function(isObject) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
diff --git a/internal/baseDelay.js b/internal/baseDelay.js
index 38cc9b9cf..54ab68132 100644
--- a/internal/baseDelay.js
+++ b/internal/baseDelay.js
@@ -7,8 +7,8 @@ define([], function() {
var FUNC_ERROR_TEXT = 'Expected a function';
/**
- * The base implementation of `_.delay` and `_.defer` which accepts an index
- * of where to slice the arguments to provide to `func`.
+ * The base implementation of `_.delay` and `_.defer` which accepts an array
+ * of `func` arguments.
*
* @private
* @param {Function} func The function to delay.
diff --git a/internal/baseDifference.js b/internal/baseDifference.js
index 3fb7edd6a..8f52c8c69 100644
--- a/internal/baseDifference.js
+++ b/internal/baseDifference.js
@@ -1,49 +1,57 @@
-define(['./baseIndexOf', './cacheIndexOf', './createCache'], function(baseIndexOf, cacheIndexOf, createCache) {
+define(['./SetCache', './arrayIncludes', './arrayIncludesWith', './arrayMap', './baseUnary', './cacheHas'], function(SetCache, arrayIncludes, arrayIncludesWith, arrayMap, baseUnary, cacheHas) {
/** 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.
+ * The base implementation of methods like `_.difference` without support for
+ * excluding multiple arrays or iteratee shorthands.
*
* @private
* @param {Array} array The array to inspect.
* @param {Array} values The values to exclude.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
* @returns {Array} Returns the new array of filtered values.
*/
- function baseDifference(array, values) {
- var length = array ? array.length : 0,
- result = [];
+ function baseDifference(array, values, iteratee, comparator) {
+ var index = -1,
+ includes = arrayIncludes,
+ isCommon = true,
+ length = array.length,
+ result = [],
+ valuesLength = values.length;
if (!length) {
return result;
}
- var index = -1,
- indexOf = baseIndexOf,
- isCommon = true,
- cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
- valuesLength = values.length;
-
- if (cache) {
- indexOf = cacheIndexOf;
+ if (iteratee) {
+ values = arrayMap(values, baseUnary(iteratee));
+ }
+ if (comparator) {
+ includes = arrayIncludesWith;
isCommon = false;
- values = cache;
+ }
+ else if (values.length >= LARGE_ARRAY_SIZE) {
+ includes = cacheHas;
+ isCommon = false;
+ values = new SetCache(values);
}
outer:
while (++index < length) {
- var value = array[index];
+ var value = array[index],
+ computed = iteratee ? iteratee(value) : value;
- if (isCommon && value === value) {
+ if (isCommon && computed === computed) {
var valuesIndex = valuesLength;
while (valuesIndex--) {
- if (values[valuesIndex] === value) {
+ if (values[valuesIndex] === computed) {
continue outer;
}
}
result.push(value);
}
- else if (indexOf(values, value, 0) < 0) {
+ else if (!includes(values, computed, comparator)) {
result.push(value);
}
}
diff --git a/internal/baseEach.js b/internal/baseEach.js
index 555261b18..8ba1cd29c 100644
--- a/internal/baseEach.js
+++ b/internal/baseEach.js
@@ -1,13 +1,12 @@
define(['./baseForOwn', './createBaseEach'], function(baseForOwn, createBaseEach) {
/**
- * The base implementation of `_.forEach` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forEach` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
- * @returns {Array|Object|string} Returns `collection`.
+ * @returns {Array|Object} Returns `collection`.
*/
var baseEach = createBaseEach(baseForOwn);
diff --git a/internal/baseEachRight.js b/internal/baseEachRight.js
index 8114fbe02..e6071d9b7 100644
--- a/internal/baseEachRight.js
+++ b/internal/baseEachRight.js
@@ -1,13 +1,12 @@
define(['./baseForOwnRight', './createBaseEach'], function(baseForOwnRight, createBaseEach) {
/**
- * The base implementation of `_.forEachRight` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forEachRight` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
- * @returns {Array|Object|string} Returns `collection`.
+ * @returns {Array|Object} Returns `collection`.
*/
var baseEachRight = createBaseEach(baseForOwnRight, true);
diff --git a/internal/baseEvery.js b/internal/baseEvery.js
index cece23d1d..83774a59e 100644
--- a/internal/baseEvery.js
+++ b/internal/baseEvery.js
@@ -1,14 +1,12 @@
define(['./baseEach'], function(baseEach) {
/**
- * The base implementation of `_.every` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.every` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
*/
function baseEvery(collection, predicate) {
var result = true;
diff --git a/internal/baseExtremum.js b/internal/baseExtremum.js
index e48c983d9..6f2e9a235 100644
--- a/internal/baseExtremum.js
+++ b/internal/baseExtremum.js
@@ -1,28 +1,34 @@
-define(['./baseEach'], function(baseEach) {
+define([], function() {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
- * Gets the extremum value of `collection` invoking `iteratee` for each value
- * in `collection` to generate the criterion by which the value is ranked.
- * The `iteratee` is invoked with three arguments: (value, index|key, collection).
+ * The base implementation of methods like `_.max` and `_.min` which accepts a
+ * `comparator` to determine the extremum value.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {Function} comparator The function used to compare values.
- * @param {*} exValue The initial extremum value.
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The iteratee invoked per iteration.
+ * @param {Function} comparator The comparator used to compare values.
* @returns {*} Returns the extremum value.
*/
- function baseExtremum(collection, iteratee, comparator, exValue) {
- var computed = exValue,
- result = computed;
+ function baseExtremum(array, iteratee, comparator) {
+ var index = -1,
+ length = array.length;
- baseEach(collection, function(value, index, collection) {
- var current = +iteratee(value, index, collection);
- if (comparator(current, computed) || (current === exValue && current === result)) {
- computed = current;
- result = value;
+ while (++index < length) {
+ var value = array[index],
+ current = iteratee(value);
+
+ if (current != null && (computed === undefined
+ ? current === current
+ : comparator(current, computed)
+ )) {
+ var computed = current,
+ result = value;
}
- });
+ }
return result;
}
diff --git a/internal/baseFill.js b/internal/baseFill.js
index bca329124..0fc585c5f 100644
--- a/internal/baseFill.js
+++ b/internal/baseFill.js
@@ -1,4 +1,4 @@
-define([], function() {
+define(['../toInteger', '../toLength'], function(toInteger, toLength) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -16,18 +16,16 @@ define([], function() {
function baseFill(array, value, start, end) {
var length = array.length;
- start = start == null ? 0 : (+start || 0);
+ start = toInteger(start);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
- end = (end === undefined || end > length) ? length : (+end || 0);
+ end = (end === undefined || end > length) ? length : toInteger(end);
if (end < 0) {
end += length;
}
- length = start > end ? 0 : (end >>> 0);
- start >>>= 0;
-
- while (start < length) {
+ end = start > end ? 0 : toLength(end);
+ while (start < end) {
array[start++] = value;
}
return array;
diff --git a/internal/baseFilter.js b/internal/baseFilter.js
index 4da845478..ea2616735 100644
--- a/internal/baseFilter.js
+++ b/internal/baseFilter.js
@@ -1,11 +1,10 @@
define(['./baseEach'], function(baseEach) {
/**
- * The base implementation of `_.filter` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.filter` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
*/
diff --git a/internal/baseFind.js b/internal/baseFind.js
index 0791dd049..8bbf9c3cb 100644
--- a/internal/baseFind.js
+++ b/internal/baseFind.js
@@ -1,16 +1,15 @@
define([], function() {
/**
- * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
- * without support for callback shorthands and `this` binding, which iterates
- * over `collection` using the provided `eachFunc`.
+ * The base implementation of methods like `_.find` and `_.findKey`, without
+ * support for iteratee shorthands, which iterates over `collection` using
+ * the provided `eachFunc`.
*
* @private
- * @param {Array|Object|string} collection The collection to search.
+ * @param {Array|Object} collection The collection to search.
* @param {Function} predicate The function invoked per iteration.
* @param {Function} eachFunc The function to iterate over `collection`.
- * @param {boolean} [retKey] Specify returning the key of the found element
- * instead of the element itself.
+ * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
* @returns {*} Returns the found element or its key, else `undefined`.
*/
function baseFind(collection, predicate, eachFunc, retKey) {
diff --git a/internal/baseFindIndex.js b/internal/baseFindIndex.js
index 5a6dd094b..251704175 100644
--- a/internal/baseFindIndex.js
+++ b/internal/baseFindIndex.js
@@ -2,7 +2,7 @@ define([], function() {
/**
* The base implementation of `_.findIndex` and `_.findLastIndex` without
- * support for callback shorthands and `this` binding.
+ * support for iteratee shorthands.
*
* @private
* @param {Array} array The array to search.
diff --git a/internal/baseFlatten.js b/internal/baseFlatten.js
index 380e4196d..8cf62d87f 100644
--- a/internal/baseFlatten.js
+++ b/internal/baseFlatten.js
@@ -1,8 +1,7 @@
-define(['./arrayPush', '../lang/isArguments', '../lang/isArray', './isArrayLike', './isObjectLike'], function(arrayPush, isArguments, isArray, isArrayLike, isObjectLike) {
+define(['./arrayPush', '../isArguments', '../isArray', '../isArrayLikeObject'], function(arrayPush, isArguments, isArray, isArrayLikeObject) {
/**
- * The base implementation of `_.flatten` with added support for restricting
- * flattening and specifying the start index.
+ * The base implementation of `_.flatten` with support for restricting flattening.
*
* @private
* @param {Array} array The array to flatten.
@@ -19,7 +18,7 @@ define(['./arrayPush', '../lang/isArguments', '../lang/isArray', './isArrayLike'
while (++index < length) {
var value = array[index];
- if (isObjectLike(value) && isArrayLike(value) &&
+ if (isArrayLikeObject(value) &&
(isStrict || isArray(value) || isArguments(value))) {
if (isDeep) {
// Recursively flatten arrays (susceptible to call stack limits).
diff --git a/internal/baseForIn.js b/internal/baseForIn.js
index 56590257e..cfa5112d9 100644
--- a/internal/baseForIn.js
+++ b/internal/baseForIn.js
@@ -1,8 +1,7 @@
-define(['./baseFor', '../object/keysIn'], function(baseFor, keysIn) {
+define(['./baseFor', '../keysIn'], function(baseFor, keysIn) {
/**
- * The base implementation of `_.forIn` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forIn` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to iterate over.
@@ -10,7 +9,7 @@ define(['./baseFor', '../object/keysIn'], function(baseFor, keysIn) {
* @returns {Object} Returns `object`.
*/
function baseForIn(object, iteratee) {
- return baseFor(object, iteratee, keysIn);
+ return object == null ? object : baseFor(object, iteratee, keysIn);
}
return baseForIn;
diff --git a/internal/baseForOwn.js b/internal/baseForOwn.js
index 5352f2749..1bb3f4460 100644
--- a/internal/baseForOwn.js
+++ b/internal/baseForOwn.js
@@ -1,8 +1,7 @@
-define(['./baseFor', '../object/keys'], function(baseFor, keys) {
+define(['./baseFor', '../keys'], function(baseFor, keys) {
/**
- * The base implementation of `_.forOwn` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to iterate over.
@@ -10,7 +9,7 @@ define(['./baseFor', '../object/keys'], function(baseFor, keys) {
* @returns {Object} Returns `object`.
*/
function baseForOwn(object, iteratee) {
- return baseFor(object, iteratee, keys);
+ return object && baseFor(object, iteratee, keys);
}
return baseForOwn;
diff --git a/internal/baseForOwnRight.js b/internal/baseForOwnRight.js
index 247c20058..71e1a74db 100644
--- a/internal/baseForOwnRight.js
+++ b/internal/baseForOwnRight.js
@@ -1,8 +1,7 @@
-define(['./baseForRight', '../object/keys'], function(baseForRight, keys) {
+define(['./baseForRight', '../keys'], function(baseForRight, keys) {
/**
- * The base implementation of `_.forOwnRight` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to iterate over.
@@ -10,7 +9,7 @@ define(['./baseForRight', '../object/keys'], function(baseForRight, keys) {
* @returns {Object} Returns `object`.
*/
function baseForOwnRight(object, iteratee) {
- return baseForRight(object, iteratee, keys);
+ return object && baseForRight(object, iteratee, keys);
}
return baseForOwnRight;
diff --git a/internal/baseFunctions.js b/internal/baseFunctions.js
index a52757c14..d19880232 100644
--- a/internal/baseFunctions.js
+++ b/internal/baseFunctions.js
@@ -1,4 +1,4 @@
-define(['../lang/isFunction'], function(isFunction) {
+define(['./arrayFilter', '../isFunction'], function(arrayFilter, isFunction) {
/**
* The base implementation of `_.functions` which creates an array of
@@ -10,18 +10,9 @@ define(['../lang/isFunction'], function(isFunction) {
* @returns {Array} Returns the new array of filtered property names.
*/
function baseFunctions(object, props) {
- var index = -1,
- length = props.length,
- resIndex = -1,
- result = [];
-
- while (++index < length) {
- var key = props[index];
- if (isFunction(object[key])) {
- result[++resIndex] = key;
- }
- }
- return result;
+ return arrayFilter(props, function(key) {
+ return isFunction(object[key]);
+ });
}
return baseFunctions;
diff --git a/internal/baseGet.js b/internal/baseGet.js
index 1b037f89e..9a4528222 100644
--- a/internal/baseGet.js
+++ b/internal/baseGet.js
@@ -1,25 +1,19 @@
-define(['./toObject'], function(toObject) {
+define(['./baseToPath', './isKey'], function(baseToPath, isKey) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/**
- * The base implementation of `get` without support for string paths
- * and default values.
+ * The base implementation of `_.get` without support for default values.
*
* @private
* @param {Object} object The object to query.
- * @param {Array} path The path of the property to get.
- * @param {string} [pathKey] The key representation of path.
+ * @param {Array|string} path The path of the property to get.
* @returns {*} Returns the resolved value.
*/
- function baseGet(object, path, pathKey) {
- if (object == null) {
- return;
- }
- if (pathKey !== undefined && pathKey in toObject(object)) {
- path = [pathKey];
- }
+ function baseGet(object, path) {
+ path = isKey(path, object) ? [path + ''] : baseToPath(path);
+
var index = 0,
length = path.length;
diff --git a/internal/baseHas.js b/internal/baseHas.js
new file mode 100644
index 000000000..80fb0a5fb
--- /dev/null
+++ b/internal/baseHas.js
@@ -0,0 +1,29 @@
+define([], function() {
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /** Built-in value references. */
+ var getPrototypeOf = Object.getPrototypeOf;
+
+ /**
+ * The base implementation of `_.has` without support for deep paths.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+ function baseHas(object, key) {
+ // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
+ // that are composed entirely of index properties, return `false` for
+ // `hasOwnProperty` checks of them.
+ return hasOwnProperty.call(object, key) ||
+ (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
+ }
+
+ return baseHas;
+});
diff --git a/internal/baseHasIn.js b/internal/baseHasIn.js
new file mode 100644
index 000000000..9b8af5aaf
--- /dev/null
+++ b/internal/baseHasIn.js
@@ -0,0 +1,16 @@
+define([], function() {
+
+ /**
+ * The base implementation of `_.hasIn` without support for deep paths.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+ function baseHasIn(object, key) {
+ return key in Object(object);
+ }
+
+ return baseHasIn;
+});
diff --git a/internal/baseInRange.js b/internal/baseInRange.js
new file mode 100644
index 000000000..88b6a1abf
--- /dev/null
+++ b/internal/baseInRange.js
@@ -0,0 +1,21 @@
+define([], function() {
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMax = Math.max,
+ nativeMin = Math.min;
+
+ /**
+ * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
+ *
+ * @private
+ * @param {number} number The number to check.
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
+ */
+ function baseInRange(number, start, end) {
+ return number >= nativeMin(start, end) && number < nativeMax(start, end);
+ }
+
+ return baseInRange;
+});
diff --git a/internal/baseIndexOf.js b/internal/baseIndexOf.js
index 917c4f47f..e28fbb3b6 100644
--- a/internal/baseIndexOf.js
+++ b/internal/baseIndexOf.js
@@ -1,7 +1,7 @@
define(['./indexOfNaN'], function(indexOfNaN) {
/**
- * The base implementation of `_.indexOf` without support for binary searches.
+ * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
*
* @private
* @param {Array} array The array to search.
diff --git a/internal/baseIntersection.js b/internal/baseIntersection.js
new file mode 100644
index 000000000..429f00ff8
--- /dev/null
+++ b/internal/baseIntersection.js
@@ -0,0 +1,61 @@
+define(['./SetCache', './arrayIncludes', './arrayIncludesWith', './arrayMap', './baseUnary', './cacheHas'], function(SetCache, arrayIncludes, arrayIncludesWith, arrayMap, baseUnary, cacheHas) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * The base implementation of methods like `_.intersection`, without support
+ * for iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ */
+ function baseIntersection(arrays, iteratee, comparator) {
+ var includes = comparator ? arrayIncludesWith : arrayIncludes,
+ othLength = arrays.length,
+ othIndex = othLength,
+ caches = Array(othLength),
+ result = [];
+
+ while (othIndex--) {
+ var array = arrays[othIndex];
+ if (othIndex && iteratee) {
+ array = arrayMap(array, baseUnary(iteratee));
+ }
+ caches[othIndex] = !comparator && (iteratee || array.length >= 120)
+ ? new SetCache(othIndex && array)
+ : undefined;
+ }
+ array = arrays[0];
+
+ var index = -1,
+ length = array.length,
+ seen = caches[0];
+
+ outer:
+ while (++index < length) {
+ var value = array[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) {
+ var othIndex = othLength;
+ while (--othIndex) {
+ var cache = caches[othIndex];
+ if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) {
+ continue outer;
+ }
+ }
+ if (seen) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ }
+ return result;
+ }
+
+ return baseIntersection;
+});
diff --git a/internal/baseInvoke.js b/internal/baseInvoke.js
new file mode 100644
index 000000000..f71133700
--- /dev/null
+++ b/internal/baseInvoke.js
@@ -0,0 +1,28 @@
+define(['./apply', './baseToPath', './isKey', '../last', './parent'], function(apply, baseToPath, isKey, last, parent) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * The base implementation of `_.invoke` without support for individual
+ * method arguments.
+ *
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {Array} args The arguments to invoke the method with.
+ * @returns {*} Returns the result of the invoked method.
+ */
+ function baseInvoke(object, path, args) {
+ if (!isKey(path, object)) {
+ path = baseToPath(path);
+ object = parent(object, path);
+ path = last(path);
+ }
+ var func = object == null ? object : object[path];
+ return func == null ? undefined : apply(func, object, args);
+ }
+
+ return baseInvoke;
+});
diff --git a/internal/baseIsEqual.js b/internal/baseIsEqual.js
index a57b1a05c..205df6dfd 100644
--- a/internal/baseIsEqual.js
+++ b/internal/baseIsEqual.js
@@ -1,26 +1,28 @@
-define(['./baseIsEqualDeep', '../lang/isObject', './isObjectLike'], function(baseIsEqualDeep, isObject, isObjectLike) {
+define(['./baseIsEqualDeep', '../isObject', '../isObjectLike'], function(baseIsEqualDeep, isObject, isObjectLike) {
/**
- * The base implementation of `_.isEqual` without support for `this` binding
- * `customizer` functions.
+ * The base implementation of `_.isEqual` which supports partial comparisons
+ * and tracks traversed objects.
*
* @private
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
- * @param {Function} [customizer] The function to customize comparing values.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
- * @param {Array} [stackA] Tracks traversed `value` objects.
- * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {boolean} [bitmask] The bitmask of comparison flags.
+ * The bitmask may be composed of the following flags:
+ * 1 - Unordered comparison
+ * 2 - Partial comparison
+ * @param {Object} [stack] Tracks traversed `value` and `other` objects.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
*/
- function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
+ function baseIsEqual(value, other, customizer, bitmask, stack) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
- return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
+ return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
}
return baseIsEqual;
diff --git a/internal/baseIsEqualDeep.js b/internal/baseIsEqualDeep.js
index 82f967c3c..0bb93a631 100644
--- a/internal/baseIsEqualDeep.js
+++ b/internal/baseIsEqualDeep.js
@@ -1,22 +1,19 @@
-define(['./equalArrays', './equalByTag', './equalObjects', '../lang/isArray', '../lang/isTypedArray'], function(equalArrays, equalByTag, equalObjects, isArray, isTypedArray) {
+define(['./Stack', './equalArrays', './equalByTag', './equalObjects', './getTag', '../isArray', './isHostObject', '../isTypedArray'], function(Stack, equalArrays, equalByTag, equalObjects, getTag, isArray, isHostObject, isTypedArray) {
+
+ /** Used to compose bitmasks for comparison styles. */
+ var PARTIAL_COMPARE_FLAG = 2;
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
objectTag = '[object Object]';
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
- /**
- * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
- * of values.
- */
- var objToString = objectProto.toString;
-
/**
* A specialized version of `baseIsEqual` for arrays and objects which performs
* deep comparisons and tracks traversed objects enabling objects with circular
@@ -26,20 +23,19 @@ define(['./equalArrays', './equalByTag', './equalObjects', '../lang/isArray', '.
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} [customizer] The function to customize comparing objects.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
- * @param {Array} [stackA=[]] Tracks traversed `value` objects.
- * @param {Array} [stackB=[]] Tracks traversed `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+ function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
- objTag = objToString.call(object);
+ objTag = getTag(object);
if (objTag == argsTag) {
objTag = objectTag;
} else if (objTag != objectTag) {
@@ -47,52 +43,34 @@ define(['./equalArrays', './equalByTag', './equalObjects', '../lang/isArray', '.
}
}
if (!othIsArr) {
- othTag = objToString.call(other);
+ othTag = getTag(other);
if (othTag == argsTag) {
othTag = objectTag;
} else if (othTag != objectTag) {
othIsArr = isTypedArray(other);
}
}
- var objIsObj = objTag == objectTag,
- othIsObj = othTag == objectTag,
+ var objIsObj = objTag == objectTag && !isHostObject(object),
+ othIsObj = othTag == objectTag && !isHostObject(other),
isSameTag = objTag == othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
- return equalByTag(object, other, objTag);
+ return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
}
- if (!isLoose) {
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
+ if (!isPartial) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
- return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
+ return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
}
}
if (!isSameTag) {
return false;
}
- // Assume cyclic values are equal.
- // For more information on detecting circular references see https://es5.github.io/#JO.
- stackA || (stackA = []);
- stackB || (stackB = []);
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == object) {
- return stackB[length] == other;
- }
- }
- // Add `object` and `other` to the stack of traversed objects.
- stackA.push(object);
- stackB.push(other);
-
- var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
-
- stackA.pop();
- stackB.pop();
-
- return result;
+ stack || (stack = new Stack);
+ return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
}
return baseIsEqualDeep;
diff --git a/internal/baseIsFunction.js b/internal/baseIsFunction.js
deleted file mode 100644
index 458999d1a..000000000
--- a/internal/baseIsFunction.js
+++ /dev/null
@@ -1,18 +0,0 @@
-define([], function() {
-
- /**
- * The base implementation of `_.isFunction` without support for environments
- * with incorrect `typeof` results.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- */
- function baseIsFunction(value) {
- // Avoid a Chakra JIT bug in compatibility modes of IE 11.
- // See https://github.com/jashkenas/underscore/issues/1621 for more details.
- return typeof value == 'function' || false;
- }
-
- return baseIsFunction;
-});
diff --git a/internal/baseIsMatch.js b/internal/baseIsMatch.js
index d98c92cef..94329c4fb 100644
--- a/internal/baseIsMatch.js
+++ b/internal/baseIsMatch.js
@@ -1,19 +1,23 @@
-define(['./baseIsEqual', './toObject'], function(baseIsEqual, toObject) {
+define(['./Stack', './baseIsEqual'], function(Stack, baseIsEqual) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
+ /** Used to compose bitmasks for comparison styles. */
+ var UNORDERED_COMPARE_FLAG = 1,
+ PARTIAL_COMPARE_FLAG = 2;
+
/**
- * The base implementation of `_.isMatch` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.isMatch` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to inspect.
- * @param {Array} matchData The propery names, values, and compare flags to match.
- * @param {Function} [customizer] The function to customize comparing objects.
+ * @param {Object} source The object of property values to match.
+ * @param {Array} matchData The property names, values, and compare flags to match.
+ * @param {Function} [customizer] The function to customize comparisons.
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
*/
- function baseIsMatch(object, matchData, customizer) {
+ function baseIsMatch(object, source, matchData, customizer) {
var index = matchData.length,
length = index,
noCustomizer = !customizer;
@@ -21,7 +25,7 @@ define(['./baseIsEqual', './toObject'], function(baseIsEqual, toObject) {
if (object == null) {
return !length;
}
- object = toObject(object);
+ object = Object(object);
while (index--) {
var data = matchData[index];
if ((noCustomizer && data[2])
@@ -42,8 +46,10 @@ define(['./baseIsEqual', './toObject'], function(baseIsEqual, toObject) {
return false;
}
} else {
- var result = customizer ? customizer(objValue, srcValue, key) : undefined;
- if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
+ var stack = new Stack,
+ result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
+
+ if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) : result)) {
return false;
}
}
diff --git a/internal/baseIteratee.js b/internal/baseIteratee.js
new file mode 100644
index 000000000..3467c52a6
--- /dev/null
+++ b/internal/baseIteratee.js
@@ -0,0 +1,27 @@
+define(['./baseMatches', './baseMatchesProperty', '../identity', '../isArray', '../property'], function(baseMatches, baseMatchesProperty, identity, isArray, property) {
+
+ /**
+ * The base implementation of `_.iteratee`.
+ *
+ * @private
+ * @param {*} [value=_.identity] The value to convert to an iteratee.
+ * @returns {Function} Returns the iteratee.
+ */
+ function baseIteratee(value) {
+ var type = typeof value;
+ if (type == 'function') {
+ return value;
+ }
+ if (value == null) {
+ return identity;
+ }
+ if (type == 'object') {
+ return isArray(value)
+ ? baseMatchesProperty(value[0], value[1])
+ : baseMatches(value);
+ }
+ return property(value);
+ }
+
+ return baseIteratee;
+});
diff --git a/internal/baseKeys.js b/internal/baseKeys.js
new file mode 100644
index 000000000..6152f1e1b
--- /dev/null
+++ b/internal/baseKeys.js
@@ -0,0 +1,20 @@
+define([], function() {
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeKeys = Object.keys;
+
+ /**
+ * The base implementation of `_.keys` which doesn't skip the constructor
+ * property of prototypes or treat sparse arrays as dense.
+ *
+ * @private
+ * @type Function
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeys(object) {
+ return nativeKeys(Object(object));
+ }
+
+ return baseKeys;
+});
diff --git a/internal/baseKeysIn.js b/internal/baseKeysIn.js
new file mode 100644
index 000000000..fd1b9d805
--- /dev/null
+++ b/internal/baseKeysIn.js
@@ -0,0 +1,39 @@
+define(['./Reflect', './iteratorToArray'], function(Reflect, iteratorToArray) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Built-in value references. */
+ var enumerate = Reflect ? Reflect.enumerate : undefined,
+ propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+ /**
+ * The base implementation of `_.keysIn` which doesn't skip the constructor
+ * property of prototypes or treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeysIn(object) {
+ object = object == null ? object : Object(object);
+
+ var result = [];
+ for (var key in object) {
+ result.push(key);
+ }
+ return result;
+ }
+
+ // Fallback for IE < 9 with es6-shim.
+ if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
+ baseKeysIn = function(object) {
+ return iteratorToArray(enumerate(object));
+ };
+ }
+
+ return baseKeysIn;
+});
diff --git a/internal/baseMap.js b/internal/baseMap.js
index 98f547bfa..8f16f80f9 100644
--- a/internal/baseMap.js
+++ b/internal/baseMap.js
@@ -1,11 +1,10 @@
-define(['./baseEach', './isArrayLike'], function(baseEach, isArrayLike) {
+define(['./baseEach', '../isArrayLike'], function(baseEach, isArrayLike) {
/**
- * The base implementation of `_.map` without support for callback shorthands
- * and `this` binding.
+ * The base implementation of `_.map` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
diff --git a/internal/baseMatches.js b/internal/baseMatches.js
index a4700e1b1..b7ff8e405 100644
--- a/internal/baseMatches.js
+++ b/internal/baseMatches.js
@@ -1,10 +1,10 @@
-define(['./baseIsMatch', './getMatchData', './toObject'], function(baseIsMatch, getMatchData, toObject) {
+define(['./baseIsMatch', './getMatchData'], function(baseIsMatch, getMatchData) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/**
- * The base implementation of `_.matches` which does not clone `source`.
+ * The base implementation of `_.matches` which doesn't clone `source`.
*
* @private
* @param {Object} source The object of property values to match.
@@ -20,11 +20,12 @@ define(['./baseIsMatch', './getMatchData', './toObject'], function(baseIsMatch,
if (object == null) {
return false;
}
- return object[key] === value && (value !== undefined || (key in toObject(object)));
+ return object[key] === value &&
+ (value !== undefined || (key in Object(object)));
};
}
return function(object) {
- return baseIsMatch(object, matchData);
+ return object === source || baseIsMatch(object, source, matchData);
};
}
diff --git a/internal/baseMatchesProperty.js b/internal/baseMatchesProperty.js
index b0738de39..d7e84156f 100644
--- a/internal/baseMatchesProperty.js
+++ b/internal/baseMatchesProperty.js
@@ -1,39 +1,26 @@
-define(['./baseGet', './baseIsEqual', './baseSlice', '../lang/isArray', './isKey', './isStrictComparable', '../array/last', './toObject', './toPath'], function(baseGet, baseIsEqual, baseSlice, isArray, isKey, isStrictComparable, last, toObject, toPath) {
+define(['./baseIsEqual', '../get', '../hasIn'], function(baseIsEqual, get, hasIn) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
+ /** Used to compose bitmasks for comparison styles. */
+ var UNORDERED_COMPARE_FLAG = 1,
+ PARTIAL_COMPARE_FLAG = 2;
+
/**
- * The base implementation of `_.matchesProperty` which does not clone `srcValue`.
+ * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
*
* @private
* @param {string} path The path of the property to get.
- * @param {*} srcValue The value to compare.
+ * @param {*} srcValue The value to match.
* @returns {Function} Returns the new function.
*/
function baseMatchesProperty(path, srcValue) {
- var isArr = isArray(path),
- isCommon = isKey(path) && isStrictComparable(srcValue),
- pathKey = (path + '');
-
- path = toPath(path);
return function(object) {
- if (object == null) {
- return false;
- }
- var key = pathKey;
- object = toObject(object);
- if ((isArr || !isCommon) && !(key in object)) {
- object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
- if (object == null) {
- return false;
- }
- key = last(path);
- object = toObject(object);
- }
- return object[key] === srcValue
- ? (srcValue !== undefined || (key in object))
- : baseIsEqual(srcValue, object[key], undefined, true);
+ var objValue = get(object, path);
+ return (objValue === undefined && objValue === srcValue)
+ ? hasIn(object, path)
+ : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
};
}
diff --git a/internal/baseMerge.js b/internal/baseMerge.js
index 1e25af801..918cbe8ab 100644
--- a/internal/baseMerge.js
+++ b/internal/baseMerge.js
@@ -1,52 +1,39 @@
-define(['./arrayEach', './baseMergeDeep', '../lang/isArray', './isArrayLike', '../lang/isObject', './isObjectLike', '../lang/isTypedArray', '../object/keys'], function(arrayEach, baseMergeDeep, isArray, isArrayLike, isObject, isObjectLike, isTypedArray, keys) {
+define(['./Stack', './arrayEach', './assignMergeValue', './baseMergeDeep', '../isArray', '../isObject', '../isTypedArray', '../keysIn'], function(Stack, arrayEach, assignMergeValue, baseMergeDeep, isArray, isObject, isTypedArray, keysIn) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/**
- * The base implementation of `_.merge` without support for argument juggling,
- * multiple sources, and `this` binding `customizer` functions.
+ * The base implementation of `_.merge` without support for multiple sources.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @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`.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
- function baseMerge(object, source, customizer, stackA, stackB) {
- if (!isObject(object)) {
- return object;
+ function baseMerge(object, source, customizer, stack) {
+ if (object === source) {
+ return;
}
- var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
- props = isSrcArr ? undefined : keys(source);
-
+ var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source);
arrayEach(props || source, function(srcValue, key) {
if (props) {
key = srcValue;
srcValue = source[key];
}
- if (isObjectLike(srcValue)) {
- stackA || (stackA = []);
- stackB || (stackB = []);
- baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
+ if (isObject(srcValue)) {
+ stack || (stack = new Stack);
+ baseMergeDeep(object, source, key, baseMerge, customizer, stack);
}
else {
- var value = object[key],
- result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
- isCommon = result === undefined;
-
- if (isCommon) {
- result = srcValue;
- }
- if ((result !== undefined || (isSrcArr && !(key in object))) &&
- (isCommon || (result === result ? (result !== value) : (value === value)))) {
- object[key] = result;
+ var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
+ if (newValue === undefined) {
+ newValue = srcValue;
}
+ assignMergeValue(object, key, newValue);
}
});
- return object;
}
return baseMerge;
diff --git a/internal/baseMergeDeep.js b/internal/baseMergeDeep.js
index a807f2549..4d73962da 100644
--- a/internal/baseMergeDeep.js
+++ b/internal/baseMergeDeep.js
@@ -1,4 +1,4 @@
-define(['./arrayCopy', '../lang/isArguments', '../lang/isArray', './isArrayLike', '../lang/isPlainObject', '../lang/isTypedArray', '../lang/toPlainObject'], function(arrayCopy, isArguments, isArray, isArrayLike, isPlainObject, isTypedArray, toPlainObject) {
+define(['./assignMergeValue', './baseClone', './copyArray', '../isArguments', '../isArray', '../isArrayLikeObject', '../isFunction', '../isObject', '../isPlainObject', '../isTypedArray', '../toPlainObject'], function(assignMergeValue, baseClone, copyArray, isArguments, isArray, isArrayLikeObject, isFunction, isObject, isPlainObject, isTypedArray, toPlainObject) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -13,52 +13,44 @@ define(['./arrayCopy', '../lang/isArguments', '../lang/isArray', './isArrayLike'
* @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 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`.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
- function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
- var length = stackA.length,
- srcValue = source[key];
+ function baseMergeDeep(object, source, key, mergeFunc, customizer, stack) {
+ var objValue = object[key],
+ srcValue = source[key],
+ stacked = stack.get(srcValue) || stack.get(objValue);
- while (length--) {
- if (stackA[length] == srcValue) {
- object[key] = stackB[length];
- return;
- }
+ if (stacked) {
+ assignMergeValue(object, key, stacked);
+ return;
}
- var value = object[key],
- result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
- isCommon = result === undefined;
+ var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined,
+ isCommon = newValue === undefined;
if (isCommon) {
- result = srcValue;
- if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
- result = isArray(value)
- ? value
- : (isArrayLike(value) ? arrayCopy(value) : []);
+ newValue = srcValue;
+ if (isArray(srcValue) || isTypedArray(srcValue)) {
+ newValue = isArray(objValue)
+ ? objValue
+ : ((isArrayLikeObject(objValue)) ? copyArray(objValue) : baseClone(srcValue));
}
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
- result = isArguments(value)
- ? toPlainObject(value)
- : (isPlainObject(value) ? value : {});
+ newValue = isArguments(objValue)
+ ? toPlainObject(objValue)
+ : (isObject(objValue) ? objValue : baseClone(srcValue));
}
else {
- isCommon = false;
+ isCommon = isFunction(srcValue);
}
}
- // Add the source value to the stack of traversed objects and associate
- // it with its merged value.
- stackA.push(srcValue);
- stackB.push(result);
+ stack.set(srcValue, newValue);
if (isCommon) {
// Recursively merge objects and arrays (susceptible to call stack limits).
- object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
- } else if (result === result ? (result !== value) : (value === value)) {
- object[key] = result;
+ mergeFunc(newValue, srcValue, customizer, stack);
}
+ assignMergeValue(object, key, newValue);
}
return baseMergeDeep;
diff --git a/internal/baseOrderBy.js b/internal/baseOrderBy.js
new file mode 100644
index 000000000..37f5f097a
--- /dev/null
+++ b/internal/baseOrderBy.js
@@ -0,0 +1,33 @@
+define(['./arrayMap', './baseIteratee', './baseMap', './baseSortBy', './compareMultiple'], function(arrayMap, baseIteratee, baseMap, baseSortBy, compareMultiple) {
+
+ /**
+ * The base implementation of `_.orderBy` without param guards.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
+ * @param {string[]} orders The sort orders of `iteratees`.
+ * @returns {Array} Returns the new sorted array.
+ */
+ function baseOrderBy(collection, iteratees, orders) {
+ var index = -1,
+ toIteratee = baseIteratee;
+
+ iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
+ return toIteratee(iteratee);
+ });
+
+ var result = baseMap(collection, function(value, key, collection) {
+ var criteria = arrayMap(iteratees, function(iteratee) {
+ return iteratee(value);
+ });
+ return { 'criteria': criteria, 'index': ++index, 'value': value };
+ });
+
+ return baseSortBy(result, function(object, other) {
+ return compareMultiple(object, other, orders);
+ });
+ }
+
+ return baseOrderBy;
+});
diff --git a/internal/basePick.js b/internal/basePick.js
new file mode 100644
index 000000000..1a5ccb691
--- /dev/null
+++ b/internal/basePick.js
@@ -0,0 +1,23 @@
+define(['./arrayReduce'], function(arrayReduce) {
+
+ /**
+ * The base implementation of `_.pick` without support for individual
+ * property names.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {string[]} props The property names to pick.
+ * @returns {Object} Returns the new object.
+ */
+ function basePick(object, props) {
+ object = Object(object);
+ return arrayReduce(props, function(result, key) {
+ if (key in object) {
+ result[key] = object[key];
+ }
+ return result;
+ }, {});
+ }
+
+ return basePick;
+});
diff --git a/internal/basePickBy.js b/internal/basePickBy.js
new file mode 100644
index 000000000..ccd1a8124
--- /dev/null
+++ b/internal/basePickBy.js
@@ -0,0 +1,22 @@
+define(['./baseForIn'], function(baseForIn) {
+
+ /**
+ * The base implementation of `_.pickBy` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {Function} predicate The function invoked per property.
+ * @returns {Object} Returns the new object.
+ */
+ function basePickBy(object, predicate) {
+ var result = {};
+ baseForIn(object, function(value, key) {
+ if (predicate(value)) {
+ result[key] = value;
+ }
+ });
+ return result;
+ }
+
+ return basePickBy;
+});
diff --git a/internal/basePropertyDeep.js b/internal/basePropertyDeep.js
index e3d3b383b..d386e1a2d 100644
--- a/internal/basePropertyDeep.js
+++ b/internal/basePropertyDeep.js
@@ -1,4 +1,4 @@
-define(['./baseGet', './toPath'], function(baseGet, toPath) {
+define(['./baseGet'], function(baseGet) {
/**
* A specialized version of `baseProperty` which supports deep paths.
@@ -8,10 +8,8 @@ define(['./baseGet', './toPath'], function(baseGet, toPath) {
* @returns {Function} Returns the new function.
*/
function basePropertyDeep(path) {
- var pathKey = (path + '');
- path = toPath(path);
return function(object) {
- return baseGet(object, path, pathKey);
+ return baseGet(object, path);
};
}
diff --git a/internal/basePullAll.js b/internal/basePullAll.js
new file mode 100644
index 000000000..9a5b29636
--- /dev/null
+++ b/internal/basePullAll.js
@@ -0,0 +1,16 @@
+define(['./basePullAllBy'], function(basePullAllBy) {
+
+ /**
+ * The base implementation of `_.pullAll`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @returns {Array} Returns `array`.
+ */
+ function basePullAll(array, values) {
+ return basePullAllBy(array, values);
+ }
+
+ return basePullAll;
+});
diff --git a/internal/basePullAllBy.js b/internal/basePullAllBy.js
new file mode 100644
index 000000000..c0967b091
--- /dev/null
+++ b/internal/basePullAllBy.js
@@ -0,0 +1,43 @@
+define(['./arrayMap', './baseIndexOf'], function(arrayMap, baseIndexOf) {
+
+ /** Used for built-in method references. */
+ var arrayProto = Array.prototype;
+
+ /** Built-in value references. */
+ var splice = arrayProto.splice;
+
+ /**
+ * The base implementation of `_.pullAllBy` without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns `array`.
+ */
+ function basePullAllBy(array, values, iteratee) {
+ var index = -1,
+ length = values.length,
+ seen = array;
+
+ if (iteratee) {
+ seen = arrayMap(array, function(value) { return iteratee(value); });
+ }
+ while (++index < length) {
+ var fromIndex = 0,
+ value = values[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
+ if (seen !== array) {
+ splice.call(seen, fromIndex, 1);
+ }
+ splice.call(array, fromIndex, 1);
+ }
+ }
+ return array;
+ }
+
+ return basePullAllBy;
+});
diff --git a/internal/basePullAt.js b/internal/basePullAt.js
index b9f10441e..b143e22ec 100644
--- a/internal/basePullAt.js
+++ b/internal/basePullAt.js
@@ -1,14 +1,14 @@
-define(['./isIndex'], function(isIndex) {
+define(['./baseToPath', './isIndex', './isKey', '../last', './parent'], function(baseToPath, isIndex, isKey, last, parent) {
- /** Used for native method references. */
+ /** Used for built-in method references. */
var arrayProto = Array.prototype;
- /** Native method references. */
+ /** Built-in value references. */
var splice = arrayProto.splice;
/**
* The base implementation of `_.pullAt` without support for individual
- * index arguments and capturing the removed elements.
+ * indexes or capturing the removed elements.
*
* @private
* @param {Array} array The array to modify.
@@ -16,12 +16,27 @@ define(['./isIndex'], function(isIndex) {
* @returns {Array} Returns `array`.
*/
function basePullAt(array, indexes) {
- var length = array ? indexes.length : 0;
+ var length = array ? indexes.length : 0,
+ lastIndex = length - 1;
+
while (length--) {
var index = indexes[length];
- if (index != previous && isIndex(index)) {
+ if (lastIndex == length || index != previous) {
var previous = index;
- splice.call(array, index, 1);
+ if (isIndex(index)) {
+ splice.call(array, index, 1);
+ }
+ else if (!isKey(index, array)) {
+ var path = baseToPath(index),
+ object = parent(array, path);
+
+ if (object != null) {
+ delete object[last(path)];
+ }
+ }
+ else {
+ delete array[index];
+ }
}
}
return array;
diff --git a/internal/baseRandom.js b/internal/baseRandom.js
index f1495ae3f..7f3e388d7 100644
--- a/internal/baseRandom.js
+++ b/internal/baseRandom.js
@@ -1,20 +1,20 @@
define([], function() {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeFloor = Math.floor,
nativeRandom = Math.random;
/**
- * The base implementation of `_.random` without support for argument juggling
- * and returning floating-point numbers.
+ * The base implementation of `_.random` without support for returning
+ * floating-point numbers.
*
* @private
- * @param {number} min The minimum possible value.
- * @param {number} max The maximum possible value.
+ * @param {number} lower The lower bound.
+ * @param {number} upper The upper bound.
* @returns {number} Returns the random number.
*/
- function baseRandom(min, max) {
- return min + nativeFloor(nativeRandom() * (max - min + 1));
+ function baseRandom(lower, upper) {
+ return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
}
return baseRandom;
diff --git a/internal/baseRange.js b/internal/baseRange.js
new file mode 100644
index 000000000..2c3366275
--- /dev/null
+++ b/internal/baseRange.js
@@ -0,0 +1,31 @@
+define([], function() {
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeCeil = Math.ceil,
+ nativeMax = Math.max;
+
+ /**
+ * The base implementation of `_.range` and `_.rangeRight` which doesn't
+ * coerce arguments to numbers.
+ *
+ * @private
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} step The value to increment or decrement by.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the new array of numbers.
+ */
+ function baseRange(start, end, step, fromRight) {
+ var index = -1,
+ length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
+ result = Array(length);
+
+ while (length--) {
+ result[fromRight ? length : ++index] = start;
+ start += step;
+ }
+ return result;
+ }
+
+ return baseRange;
+});
diff --git a/internal/baseReduce.js b/internal/baseReduce.js
index e832d6382..54391879f 100644
--- a/internal/baseReduce.js
+++ b/internal/baseReduce.js
@@ -1,16 +1,15 @@
define([], function() {
/**
- * The base implementation of `_.reduce` and `_.reduceRight` without support
- * for callback shorthands and `this` binding, which iterates over `collection`
- * using the provided `eachFunc`.
+ * The base implementation of `_.reduce` and `_.reduceRight`, without support
+ * for iteratee shorthands, which iterates over `collection` using the provided
+ * `eachFunc`.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} accumulator The initial value.
- * @param {boolean} initFromCollection Specify using the first or last element
- * of `collection` as the initial value.
+ * @param {boolean} initFromCollection Specify using the first or last element of `collection` as the initial value.
* @param {Function} eachFunc The function to iterate over `collection`.
* @returns {*} Returns the accumulated value.
*/
diff --git a/internal/baseSet.js b/internal/baseSet.js
new file mode 100644
index 000000000..247fa9904
--- /dev/null
+++ b/internal/baseSet.js
@@ -0,0 +1,43 @@
+define(['./assignValue', './baseToPath', './isIndex', './isKey', '../isObject'], function(assignValue, baseToPath, isIndex, isKey, isObject) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * The base implementation of `_.set`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize path creation.
+ * @returns {Object} Returns `object`.
+ */
+ function baseSet(object, path, value, customizer) {
+ path = isKey(path, object) ? [path + ''] : baseToPath(path);
+
+ var index = -1,
+ length = path.length,
+ lastIndex = length - 1,
+ nested = object;
+
+ while (nested != null && ++index < length) {
+ var key = path[index];
+ if (isObject(nested)) {
+ var newValue = value;
+ if (index != lastIndex) {
+ var objValue = nested[key];
+ newValue = customizer ? customizer(objValue, key, nested) : undefined;
+ if (newValue === undefined) {
+ newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue;
+ }
+ }
+ assignValue(nested, key, newValue);
+ }
+ nested = nested[key];
+ }
+ return object;
+ }
+
+ return baseSet;
+});
diff --git a/internal/baseSetData.js b/internal/baseSetData.js
index da88b53a5..18bd4f90d 100644
--- a/internal/baseSetData.js
+++ b/internal/baseSetData.js
@@ -1,4 +1,4 @@
-define(['../utility/identity', './metaMap'], function(identity, metaMap) {
+define(['../identity', './metaMap'], function(identity, metaMap) {
/**
* The base implementation of `setData` without support for hot loop detection.
diff --git a/internal/baseSlice.js b/internal/baseSlice.js
index 499082f3d..e0b24143a 100644
--- a/internal/baseSlice.js
+++ b/internal/baseSlice.js
@@ -1,8 +1,5 @@
define([], function() {
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
/**
* The base implementation of `_.slice` without an iteratee call guard.
*
@@ -16,11 +13,10 @@ define([], function() {
var index = -1,
length = array.length;
- start = start == null ? 0 : (+start || 0);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
- end = (end === undefined || end > length) ? length : (+end || 0);
+ end = end > length ? length : end;
if (end < 0) {
end += length;
}
diff --git a/internal/baseSome.js b/internal/baseSome.js
index f73c3278e..b9a3b34a4 100644
--- a/internal/baseSome.js
+++ b/internal/baseSome.js
@@ -1,14 +1,12 @@
define(['./baseEach'], function(baseEach) {
/**
- * The base implementation of `_.some` without support for callback shorthands
- * and `this` binding.
+ * The base implementation of `_.some` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
*/
function baseSome(collection, predicate) {
var result;
diff --git a/internal/baseSortByOrder.js b/internal/baseSortByOrder.js
deleted file mode 100644
index a1b95333d..000000000
--- a/internal/baseSortByOrder.js
+++ /dev/null
@@ -1,28 +0,0 @@
-define(['./arrayMap', './baseCallback', './baseMap', './baseSortBy', './compareMultiple'], function(arrayMap, baseCallback, baseMap, baseSortBy, compareMultiple) {
-
- /**
- * The base implementation of `_.sortByOrder` without param guards.
- *
- * @private
- * @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`.
- * @returns {Array} Returns the new sorted array.
- */
- function baseSortByOrder(collection, iteratees, orders) {
- var index = -1;
-
- iteratees = arrayMap(iteratees, function(iteratee) { return baseCallback(iteratee); });
-
- var result = baseMap(collection, function(value) {
- var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); });
- return { 'criteria': criteria, 'index': ++index, 'value': value };
- });
-
- return baseSortBy(result, function(object, other) {
- return compareMultiple(object, other, orders);
- });
- }
-
- return baseSortByOrder;
-});
diff --git a/internal/binaryIndex.js b/internal/baseSortedIndex.js
similarity index 73%
rename from internal/binaryIndex.js
rename to internal/baseSortedIndex.js
index 72fb07b04..f711235de 100644
--- a/internal/binaryIndex.js
+++ b/internal/baseSortedIndex.js
@@ -1,11 +1,12 @@
-define(['./binaryIndexBy', '../utility/identity'], function(binaryIndexBy, identity) {
+define(['./baseSortedIndexBy', '../identity'], function(baseSortedIndexBy, identity) {
/** Used as references for the maximum length and index of an array. */
var MAX_ARRAY_LENGTH = 4294967295,
HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
/**
- * Performs a binary search of `array` to determine the index at which `value`
+ * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
+ * performs a binary search of `array` to determine the index at which `value`
* should be inserted into `array` in order to maintain its sort order.
*
* @private
@@ -15,7 +16,7 @@ define(['./binaryIndexBy', '../utility/identity'], function(binaryIndexBy, ident
* @returns {number} Returns the index at which `value` should be inserted
* into `array`.
*/
- function binaryIndex(array, value, retHighest) {
+ function baseSortedIndex(array, value, retHighest) {
var low = 0,
high = array ? array.length : low;
@@ -32,8 +33,8 @@ define(['./binaryIndexBy', '../utility/identity'], function(binaryIndexBy, ident
}
return high;
}
- return binaryIndexBy(array, value, identity, retHighest);
+ return baseSortedIndexBy(array, value, identity, retHighest);
}
- return binaryIndex;
+ return baseSortedIndex;
});
diff --git a/internal/binaryIndexBy.js b/internal/baseSortedIndexBy.js
similarity index 75%
rename from internal/binaryIndexBy.js
rename to internal/baseSortedIndexBy.js
index e86ed6f63..babda4ff4 100644
--- a/internal/binaryIndexBy.js
+++ b/internal/baseSortedIndexBy.js
@@ -3,28 +3,27 @@ define([], function() {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeFloor = Math.floor,
- nativeMin = Math.min;
-
/** Used as references for the maximum length and index of an array. */
var MAX_ARRAY_LENGTH = 4294967295,
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeFloor = Math.floor,
+ nativeMin = Math.min;
+
/**
- * This function is like `binaryIndex` except that it invokes `iteratee` for
- * `value` and each element of `array` to compute their sort ranking. The
- * iteratee is invoked with one argument; (value).
+ * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
+ * which invokes `iteratee` for `value` and each element of `array` to compute
+ * their sort ranking. The iteratee is invoked with one argument; (value).
*
* @private
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} iteratee The iteratee invoked per element.
* @param {boolean} [retHighest] Specify returning the highest qualified index.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
*/
- function binaryIndexBy(array, value, iteratee, retHighest) {
+ function baseSortedIndexBy(array, value, iteratee, retHighest) {
value = iteratee(value);
var low = 0,
@@ -59,5 +58,5 @@ define([], function() {
return nativeMin(high, MAX_ARRAY_INDEX);
}
- return binaryIndexBy;
+ return baseSortedIndexBy;
});
diff --git a/internal/baseSortedUniq.js b/internal/baseSortedUniq.js
new file mode 100644
index 000000000..c135c65d3
--- /dev/null
+++ b/internal/baseSortedUniq.js
@@ -0,0 +1,15 @@
+define(['./baseSortedUniqBy'], function(baseSortedUniqBy) {
+
+ /**
+ * The base implementation of `_.sortedUniq`.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ */
+ function baseSortedUniq(array) {
+ return baseSortedUniqBy(array);
+ }
+
+ return baseSortedUniq;
+});
diff --git a/internal/baseSortedUniqBy.js b/internal/baseSortedUniqBy.js
new file mode 100644
index 000000000..e55c44726
--- /dev/null
+++ b/internal/baseSortedUniqBy.js
@@ -0,0 +1,34 @@
+define(['../eq'], function(eq) {
+
+ /**
+ * The base implementation of `_.sortedUniqBy` without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ */
+ function baseSortedUniqBy(array, iteratee) {
+ var index = 0,
+ length = array.length,
+ value = array[0],
+ computed = iteratee ? iteratee(value) : value,
+ seen = computed,
+ resIndex = 0,
+ result = [value];
+
+ while (++index < length) {
+ value = array[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ if (!eq(computed, seen)) {
+ seen = computed;
+ result[++resIndex] = value;
+ }
+ }
+ return result;
+ }
+
+ return baseSortedUniqBy;
+});
diff --git a/internal/baseSum.js b/internal/baseSum.js
index e269c4cd9..3448ed335 100644
--- a/internal/baseSum.js
+++ b/internal/baseSum.js
@@ -1,19 +1,27 @@
-define(['./baseEach'], function(baseEach) {
+define([], function() {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
- * The base implementation of `_.sum` without support for callback shorthands
- * and `this` binding.
+ * The base implementation of `_.sum` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {number} Returns the sum.
*/
- function baseSum(collection, iteratee) {
- var result = 0;
- baseEach(collection, function(value, index, collection) {
- result += +iteratee(value, index, collection) || 0;
- });
+ function baseSum(array, iteratee) {
+ var result,
+ index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var current = iteratee(array[index]);
+ if (current !== undefined) {
+ result = result === undefined ? current : (result + current);
+ }
+ }
return result;
}
diff --git a/internal/baseTimes.js b/internal/baseTimes.js
new file mode 100644
index 000000000..7c2d1f9ea
--- /dev/null
+++ b/internal/baseTimes.js
@@ -0,0 +1,23 @@
+define([], function() {
+
+ /**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */
+ function baseTimes(n, iteratee) {
+ var index = -1,
+ result = Array(n);
+
+ while (++index < n) {
+ result[index] = iteratee(index);
+ }
+ return result;
+ }
+
+ return baseTimes;
+});
diff --git a/internal/baseToPairs.js b/internal/baseToPairs.js
new file mode 100644
index 000000000..530ac7dd5
--- /dev/null
+++ b/internal/baseToPairs.js
@@ -0,0 +1,19 @@
+define(['./arrayMap'], function(arrayMap) {
+
+ /**
+ * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
+ * of key-value pairs for `object` corresponding to the property names of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the new array of key-value pairs.
+ */
+ function baseToPairs(object, props) {
+ return arrayMap(props, function(key) {
+ return [key, object[key]];
+ });
+ }
+
+ return baseToPairs;
+});
diff --git a/internal/baseToPath.js b/internal/baseToPath.js
new file mode 100644
index 000000000..026cc65c3
--- /dev/null
+++ b/internal/baseToPath.js
@@ -0,0 +1,16 @@
+define(['../isArray', './stringToPath'], function(isArray, stringToPath) {
+
+ /**
+ * The base implementation of `_.toPath` which only converts `value` to a
+ * path if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Array} Returns the property path array.
+ */
+ function baseToPath(value) {
+ return isArray(value) ? value : stringToPath(value);
+ }
+
+ return baseToPath;
+});
diff --git a/internal/baseToString.js b/internal/baseToString.js
deleted file mode 100644
index a93ab7391..000000000
--- a/internal/baseToString.js
+++ /dev/null
@@ -1,16 +0,0 @@
-define([], function() {
-
- /**
- * Converts `value` to a string if it's not one. An empty string is returned
- * for `null` or `undefined` values.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {string} Returns the string.
- */
- function baseToString(value) {
- return value == null ? '' : (value + '');
- }
-
- return baseToString;
-});
diff --git a/internal/baseUnary.js b/internal/baseUnary.js
new file mode 100644
index 000000000..e08e9d24e
--- /dev/null
+++ b/internal/baseUnary.js
@@ -0,0 +1,17 @@
+define([], function() {
+
+ /**
+ * The base implementation of `_.unary` without support for storing wrapper metadata.
+ *
+ * @private
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new function.
+ */
+ function baseUnary(func) {
+ return function(value) {
+ return func(value);
+ };
+ }
+
+ return baseUnary;
+});
diff --git a/internal/baseUniq.js b/internal/baseUniq.js
index a325d4928..c99b54385 100644
--- a/internal/baseUniq.js
+++ b/internal/baseUniq.js
@@ -1,39 +1,47 @@
-define(['./baseIndexOf', './cacheIndexOf', './createCache'], function(baseIndexOf, cacheIndexOf, createCache) {
+define(['./SetCache', './arrayIncludes', './arrayIncludesWith', './cacheHas', './createSet', './setToArray'], function(SetCache, arrayIncludes, arrayIncludesWith, cacheHas, createSet, setToArray) {
/** 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.
+ * The base implementation of `_.uniqBy` without support for iteratee shorthands.
*
* @private
* @param {Array} array The array to inspect.
- * @param {Function} [iteratee] The function invoked per iteration.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
* @returns {Array} Returns the new duplicate free array.
*/
- function baseUniq(array, iteratee) {
+ function baseUniq(array, iteratee, comparator) {
var index = -1,
- indexOf = baseIndexOf,
+ includes = arrayIncludes,
length = array.length,
isCommon = true,
- isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
- seen = isLarge ? createCache() : null,
- result = [];
+ result = [],
+ seen = result;
- if (seen) {
- indexOf = cacheIndexOf;
+ if (comparator) {
isCommon = false;
- } else {
- isLarge = false;
+ includes = arrayIncludesWith;
+ }
+ else if (length >= LARGE_ARRAY_SIZE) {
+ var set = iteratee ? null : createSet(array);
+ if (set) {
+ return setToArray(set);
+ }
+ isCommon = false;
+ includes = cacheHas;
+ seen = new SetCache;
+ }
+ else {
seen = iteratee ? [] : result;
}
outer:
while (++index < length) {
var value = array[index],
- computed = iteratee ? iteratee(value, index, array) : value;
+ computed = iteratee ? iteratee(value) : value;
- if (isCommon && value === value) {
+ if (isCommon && computed === computed) {
var seenIndex = seen.length;
while (seenIndex--) {
if (seen[seenIndex] === computed) {
@@ -45,8 +53,8 @@ define(['./baseIndexOf', './cacheIndexOf', './createCache'], function(baseIndexO
}
result.push(value);
}
- else if (indexOf(seen, computed, 0) < 0) {
- if (iteratee || isLarge) {
+ else if (!includes(seen, computed, comparator)) {
+ if (seen !== result) {
seen.push(computed);
}
result.push(value);
diff --git a/internal/baseUnset.js b/internal/baseUnset.js
new file mode 100644
index 000000000..ca15e145e
--- /dev/null
+++ b/internal/baseUnset.js
@@ -0,0 +1,19 @@
+define(['./baseToPath', '../has', './isKey', '../last', './parent'], function(baseToPath, has, isKey, last, parent) {
+
+ /**
+ * The base implementation of `_.unset`.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+ */
+ function baseUnset(object, path) {
+ path = isKey(path, object) ? [path + ''] : baseToPath(path);
+ object = parent(object, path);
+ var key = last(path);
+ return (object != null && has(object, key)) ? delete object[key] : true;
+ }
+
+ return baseUnset;
+});
diff --git a/internal/baseValues.js b/internal/baseValues.js
index bc8dff1fb..85cd2a25a 100644
--- a/internal/baseValues.js
+++ b/internal/baseValues.js
@@ -1,4 +1,4 @@
-define([], function() {
+define(['./arrayMap'], function(arrayMap) {
/**
* The base implementation of `_.values` and `_.valuesIn` which creates an
@@ -11,14 +11,9 @@ define([], function() {
* @returns {Object} Returns the array of property values.
*/
function baseValues(object, props) {
- var index = -1,
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = object[props[index]];
- }
- return result;
+ return arrayMap(props, function(key) {
+ return object[key];
+ });
}
return baseValues;
diff --git a/internal/baseWhile.js b/internal/baseWhile.js
index 6d62ce2f2..d2800a97e 100644
--- a/internal/baseWhile.js
+++ b/internal/baseWhile.js
@@ -1,8 +1,8 @@
define(['./baseSlice'], function(baseSlice) {
/**
- * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`,
- * and `_.takeWhile` without support for callback shorthands and `this` binding.
+ * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
+ * without support for iteratee shorthands.
*
* @private
* @param {Array} array The array to query.
@@ -15,7 +15,9 @@ define(['./baseSlice'], function(baseSlice) {
var length = array.length,
index = fromRight ? length : -1;
- while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}
+ while ((fromRight ? index-- : ++index < length) &&
+ predicate(array[index], index, array)) {}
+
return isDrop
? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
: baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
diff --git a/internal/baseWrapperValue.js b/internal/baseWrapperValue.js
index 255d956f4..af11a73d7 100644
--- a/internal/baseWrapperValue.js
+++ b/internal/baseWrapperValue.js
@@ -1,4 +1,4 @@
-define(['./LazyWrapper', './arrayPush'], function(LazyWrapper, arrayPush) {
+define(['./LazyWrapper', './arrayPush', './arrayReduce'], function(LazyWrapper, arrayPush, arrayReduce) {
/**
* The base implementation of `wrapperValue` which returns the result of
@@ -7,7 +7,7 @@ define(['./LazyWrapper', './arrayPush'], function(LazyWrapper, arrayPush) {
*
* @private
* @param {*} value The unwrapped value.
- * @param {Array} actions Actions to peform to resolve the unwrapped value.
+ * @param {Array} actions Actions to perform to resolve the unwrapped value.
* @returns {*} Returns the resolved value.
*/
function baseWrapperValue(value, actions) {
@@ -15,14 +15,9 @@ define(['./LazyWrapper', './arrayPush'], function(LazyWrapper, arrayPush) {
if (result instanceof LazyWrapper) {
result = result.value();
}
- var index = -1,
- length = actions.length;
-
- while (++index < length) {
- var action = actions[index];
- result = action.func.apply(action.thisArg, arrayPush([result], action.args));
- }
- return result;
+ return arrayReduce(actions, function(result, action) {
+ return action.func.apply(action.thisArg, arrayPush([result], action.args));
+ }, result);
}
return baseWrapperValue;
diff --git a/internal/baseXor.js b/internal/baseXor.js
new file mode 100644
index 000000000..ef948ad17
--- /dev/null
+++ b/internal/baseXor.js
@@ -0,0 +1,29 @@
+define(['./arrayPush', './baseDifference', './baseUniq'], function(arrayPush, baseDifference, baseUniq) {
+
+ /**
+ * The base implementation of methods like `_.xor`, without support for
+ * iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of values.
+ */
+ function baseXor(arrays, iteratee, comparator) {
+ var index = -1,
+ length = arrays.length;
+
+ while (++index < length) {
+ var result = result
+ ? arrayPush(
+ baseDifference(result, arrays[index], iteratee, comparator),
+ baseDifference(arrays[index], result, iteratee, comparator)
+ )
+ : arrays[index];
+ }
+ return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
+ }
+
+ return baseXor;
+});
diff --git a/internal/bindCallback.js b/internal/bindCallback.js
deleted file mode 100644
index 70210a3ae..000000000
--- a/internal/bindCallback.js
+++ /dev/null
@@ -1,43 +0,0 @@
-define(['../utility/identity'], function(identity) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * A specialized version of `baseCallback` which only supports `this` binding
- * and specifying the number of arguments to provide to `func`.
- *
- * @private
- * @param {Function} func The function to bind.
- * @param {*} thisArg The `this` binding of `func`.
- * @param {number} [argCount] The number of arguments to provide to `func`.
- * @returns {Function} Returns the callback.
- */
- function bindCallback(func, thisArg, argCount) {
- if (typeof func != 'function') {
- return identity;
- }
- if (thisArg === undefined) {
- return func;
- }
- switch (argCount) {
- case 1: return function(value) {
- return func.call(thisArg, value);
- };
- case 3: return function(value, index, collection) {
- return func.call(thisArg, value, index, collection);
- };
- case 4: return function(accumulator, value, index, collection) {
- return func.call(thisArg, accumulator, value, index, collection);
- };
- case 5: return function(value, other, key, object, source) {
- return func.call(thisArg, value, other, key, object, source);
- };
- }
- return function() {
- return func.apply(thisArg, arguments);
- };
- }
-
- return bindCallback;
-});
diff --git a/internal/bufferClone.js b/internal/bufferClone.js
deleted file mode 100644
index cfd586dc8..000000000
--- a/internal/bufferClone.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define(['./root'], function(root) {
-
- /** Native method references. */
- var ArrayBuffer = root.ArrayBuffer,
- Uint8Array = root.Uint8Array;
-
- /**
- * Creates a clone of the given array buffer.
- *
- * @private
- * @param {ArrayBuffer} buffer The array buffer to clone.
- * @returns {ArrayBuffer} Returns the cloned array buffer.
- */
- function bufferClone(buffer) {
- var result = new ArrayBuffer(buffer.byteLength),
- view = new Uint8Array(result);
-
- view.set(new Uint8Array(buffer));
- return result;
- }
-
- return bufferClone;
-});
diff --git a/internal/cacheHas.js b/internal/cacheHas.js
new file mode 100644
index 000000000..6b0685499
--- /dev/null
+++ b/internal/cacheHas.js
@@ -0,0 +1,26 @@
+define(['./isKeyable'], function(isKeyable) {
+
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+ /**
+ * Checks if `value` is in `cache`.
+ *
+ * @private
+ * @param {Object} cache The set cache to search.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns `true` if `value` is found, else `false`.
+ */
+ function cacheHas(cache, value) {
+ var map = cache.__data__;
+ if (isKeyable(value)) {
+ var data = map.__data__,
+ hash = typeof value == 'string' ? data.string : data.hash;
+
+ return hash[value] === HASH_UNDEFINED;
+ }
+ return map.has(value);
+ }
+
+ return cacheHas;
+});
diff --git a/internal/cacheIndexOf.js b/internal/cacheIndexOf.js
deleted file mode 100644
index c9c8d6366..000000000
--- a/internal/cacheIndexOf.js
+++ /dev/null
@@ -1,20 +0,0 @@
-define(['../lang/isObject'], function(isObject) {
-
- /**
- * Checks if `value` is in `cache` mimicking the return signature of
- * `_.indexOf` by returning `0` if the value is found, else `-1`.
- *
- * @private
- * @param {Object} cache The cache to search.
- * @param {*} value The value to search for.
- * @returns {number} Returns `0` if `value` is found, else `-1`.
- */
- function cacheIndexOf(cache, value) {
- var data = cache.data,
- result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];
-
- return result ? 0 : -1;
- }
-
- return cacheIndexOf;
-});
diff --git a/internal/cachePush.js b/internal/cachePush.js
index 5ac360d1d..c1fbdd4d7 100644
--- a/internal/cachePush.js
+++ b/internal/cachePush.js
@@ -1,7 +1,10 @@
-define(['../lang/isObject'], function(isObject) {
+define(['./isKeyable'], function(isKeyable) {
+
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
/**
- * Adds `value` to the cache.
+ * Adds `value` to the set cache.
*
* @private
* @name push
@@ -9,11 +12,15 @@ define(['../lang/isObject'], function(isObject) {
* @param {*} value The value to cache.
*/
function cachePush(value) {
- var data = this.data;
- if (typeof value == 'string' || isObject(value)) {
- data.set.add(value);
- } else {
- data.hash[value] = true;
+ var map = this.__data__;
+ if (isKeyable(value)) {
+ var data = map.__data__,
+ hash = typeof value == 'string' ? data.string : data.hash;
+
+ hash[value] = HASH_UNDEFINED;
+ }
+ else {
+ map.set(value, HASH_UNDEFINED);
}
}
diff --git a/internal/charsEndIndex.js b/internal/charsEndIndex.js
new file mode 100644
index 000000000..52dbf7ff6
--- /dev/null
+++ b/internal/charsEndIndex.js
@@ -0,0 +1,20 @@
+define(['./baseIndexOf'], function(baseIndexOf) {
+
+ /**
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
+ * that is not found in the character symbols.
+ *
+ * @private
+ * @param {Array} strSymbols The string symbols to inspect.
+ * @param {Array} chrSymbols The character symbols to find.
+ * @returns {number} Returns the index of the last unmatched string symbol.
+ */
+ function charsEndIndex(strSymbols, chrSymbols) {
+ var index = strSymbols.length;
+
+ while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
+ return index;
+ }
+
+ return charsEndIndex;
+});
diff --git a/internal/charsLeftIndex.js b/internal/charsLeftIndex.js
deleted file mode 100644
index 4ca8b631c..000000000
--- a/internal/charsLeftIndex.js
+++ /dev/null
@@ -1,21 +0,0 @@
-define([], function() {
-
- /**
- * Used by `_.trim` and `_.trimLeft` to get the index of the first character
- * of `string` that is not found in `chars`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @param {string} chars The characters to find.
- * @returns {number} Returns the index of the first character not found in `chars`.
- */
- function charsLeftIndex(string, chars) {
- var index = -1,
- length = string.length;
-
- while (++index < length && chars.indexOf(string.charAt(index)) > -1) {}
- return index;
- }
-
- return charsLeftIndex;
-});
diff --git a/internal/charsRightIndex.js b/internal/charsRightIndex.js
deleted file mode 100644
index 9672450e1..000000000
--- a/internal/charsRightIndex.js
+++ /dev/null
@@ -1,20 +0,0 @@
-define([], function() {
-
- /**
- * Used by `_.trim` and `_.trimRight` to get the index of the last character
- * of `string` that is not found in `chars`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @param {string} chars The characters to find.
- * @returns {number} Returns the index of the last character not found in `chars`.
- */
- function charsRightIndex(string, chars) {
- var index = string.length;
-
- while (index-- && chars.indexOf(string.charAt(index)) > -1) {}
- return index;
- }
-
- return charsRightIndex;
-});
diff --git a/internal/charsStartIndex.js b/internal/charsStartIndex.js
new file mode 100644
index 000000000..e8aafb2ed
--- /dev/null
+++ b/internal/charsStartIndex.js
@@ -0,0 +1,21 @@
+define(['./baseIndexOf'], function(baseIndexOf) {
+
+ /**
+ * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
+ * that is not found in the character symbols.
+ *
+ * @private
+ * @param {Array} strSymbols The string symbols to inspect.
+ * @param {Array} chrSymbols The character symbols to find.
+ * @returns {number} Returns the index of the first unmatched string symbol.
+ */
+ function charsStartIndex(strSymbols, chrSymbols) {
+ var index = -1,
+ length = strSymbols.length;
+
+ while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
+ return index;
+ }
+
+ return charsStartIndex;
+});
diff --git a/internal/checkGlobal.js b/internal/checkGlobal.js
new file mode 100644
index 000000000..172c8ab26
--- /dev/null
+++ b/internal/checkGlobal.js
@@ -0,0 +1,15 @@
+define([], function() {
+
+ /**
+ * Checks if `value` is a global object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+ */
+ function checkGlobal(value) {
+ return (value && value.Object === Object) ? value : null;
+ }
+
+ return checkGlobal;
+});
diff --git a/internal/cloneBuffer.js b/internal/cloneBuffer.js
new file mode 100644
index 000000000..3775717d3
--- /dev/null
+++ b/internal/cloneBuffer.js
@@ -0,0 +1,20 @@
+define(['./Uint8Array'], function(Uint8Array) {
+
+ /**
+ * Creates a clone of `buffer`.
+ *
+ * @private
+ * @param {ArrayBuffer} buffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */
+ function cloneBuffer(buffer) {
+ var Ctor = buffer.constructor,
+ result = new Ctor(buffer.byteLength),
+ view = new Uint8Array(result);
+
+ view.set(new Uint8Array(buffer));
+ return result;
+ }
+
+ return cloneBuffer;
+});
diff --git a/internal/cloneMap.js b/internal/cloneMap.js
new file mode 100644
index 000000000..84e02b9d5
--- /dev/null
+++ b/internal/cloneMap.js
@@ -0,0 +1,16 @@
+define(['./addMapEntry', './arrayReduce', './mapToArray'], function(addMapEntry, arrayReduce, mapToArray) {
+
+ /**
+ * Creates a clone of `map`.
+ *
+ * @private
+ * @param {Object} map The map to clone.
+ * @returns {Object} Returns the cloned map.
+ */
+ function cloneMap(map) {
+ var Ctor = map.constructor;
+ return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
+ }
+
+ return cloneMap;
+});
diff --git a/internal/cloneRegExp.js b/internal/cloneRegExp.js
new file mode 100644
index 000000000..695b1d4a4
--- /dev/null
+++ b/internal/cloneRegExp.js
@@ -0,0 +1,22 @@
+define([], function() {
+
+ /** Used to match `RegExp` flags from their coerced string values. */
+ var reFlags = /\w*$/;
+
+ /**
+ * Creates a clone of `regexp`.
+ *
+ * @private
+ * @param {Object} regexp The regexp to clone.
+ * @returns {Object} Returns the cloned regexp.
+ */
+ function cloneRegExp(regexp) {
+ var Ctor = regexp.constructor,
+ result = new Ctor(regexp.source, reFlags.exec(regexp));
+
+ result.lastIndex = regexp.lastIndex;
+ return result;
+ }
+
+ return cloneRegExp;
+});
diff --git a/internal/cloneSet.js b/internal/cloneSet.js
new file mode 100644
index 000000000..e6bf19494
--- /dev/null
+++ b/internal/cloneSet.js
@@ -0,0 +1,16 @@
+define(['./addSetEntry', './arrayReduce', './setToArray'], function(addSetEntry, arrayReduce, setToArray) {
+
+ /**
+ * Creates a clone of `set`.
+ *
+ * @private
+ * @param {Object} set The set to clone.
+ * @returns {Object} Returns the cloned set.
+ */
+ function cloneSet(set) {
+ var Ctor = set.constructor;
+ return arrayReduce(setToArray(set), addSetEntry, new Ctor);
+ }
+
+ return cloneSet;
+});
diff --git a/internal/cloneSymbol.js b/internal/cloneSymbol.js
new file mode 100644
index 000000000..56c9c932c
--- /dev/null
+++ b/internal/cloneSymbol.js
@@ -0,0 +1,22 @@
+define(['./_Symbol'], function(_Symbol) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to convert symbols to primitives and strings. */
+ var symbolProto = _Symbol ? _Symbol.prototype : undefined,
+ symbolValueOf = _Symbol ? symbolProto.valueOf : undefined;
+
+ /**
+ * Creates a clone of the `symbol` object.
+ *
+ * @private
+ * @param {Object} symbol The symbol object to clone.
+ * @returns {Object} Returns the cloned symbol object.
+ */
+ function cloneSymbol(symbol) {
+ return _Symbol ? Object(symbolValueOf.call(symbol)) : {};
+ }
+
+ return cloneSymbol;
+});
diff --git a/internal/cloneTypedArray.js b/internal/cloneTypedArray.js
new file mode 100644
index 000000000..07a721336
--- /dev/null
+++ b/internal/cloneTypedArray.js
@@ -0,0 +1,19 @@
+define(['./cloneBuffer'], function(cloneBuffer) {
+
+ /**
+ * Creates a clone of `typedArray`.
+ *
+ * @private
+ * @param {Object} typedArray The typed array to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned typed array.
+ */
+ function cloneTypedArray(typedArray, isDeep) {
+ var buffer = typedArray.buffer,
+ Ctor = typedArray.constructor;
+
+ return new Ctor(isDeep ? cloneBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
+ }
+
+ return cloneTypedArray;
+});
diff --git a/internal/compareAscending.js b/internal/compareAscending.js
index a0cafa9ce..e122875ab 100644
--- a/internal/compareAscending.js
+++ b/internal/compareAscending.js
@@ -1,16 +1,38 @@
-define(['./baseCompareAscending'], function(baseCompareAscending) {
+define([], function() {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
- * Used by `_.sortBy` to compare transformed elements of a collection and stable
- * sort them in ascending order.
+ * Compares values to sort them in ascending order.
*
* @private
- * @param {Object} object The object to compare.
- * @param {Object} other The other object to compare.
- * @returns {number} Returns the sort order indicator for `object`.
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {number} Returns the sort order indicator for `value`.
*/
- function compareAscending(object, other) {
- return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index);
+ function compareAscending(value, other) {
+ if (value !== other) {
+ var valIsNull = value === null,
+ valIsUndef = value === undefined,
+ valIsReflexive = value === value;
+
+ var othIsNull = other === null,
+ othIsUndef = other === undefined,
+ othIsReflexive = other === other;
+
+ if ((value > other && !othIsNull) || !valIsReflexive ||
+ (valIsNull && !othIsUndef && othIsReflexive) ||
+ (valIsUndef && othIsReflexive)) {
+ return 1;
+ }
+ if ((value < other && !valIsNull) || !othIsReflexive ||
+ (othIsNull && !valIsUndef && valIsReflexive) ||
+ (othIsUndef && valIsReflexive)) {
+ return -1;
+ }
+ }
+ return 0;
}
return compareAscending;
diff --git a/internal/compareMultiple.js b/internal/compareMultiple.js
index aa19db96a..7b5da5feb 100644
--- a/internal/compareMultiple.js
+++ b/internal/compareMultiple.js
@@ -1,17 +1,17 @@
-define(['./baseCompareAscending'], function(baseCompareAscending) {
+define(['./compareAscending'], function(compareAscending) {
/**
- * Used by `_.sortByOrder` to compare multiple properties of a value to another
+ * Used by `_.orderBy` to compare multiple properties of a value to another
* and stable sort them.
*
- * 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".
+ * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
+ * specify an order of "desc" for descending or "asc" for ascending sort order
+ * of corresponding values.
*
* @private
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
- * @param {boolean[]} orders The order to sort by for each property.
+ * @param {boolean[]|string[]} orders The order to sort by for each property.
* @returns {number} Returns the sort order indicator for `object`.
*/
function compareMultiple(object, other, orders) {
@@ -22,13 +22,13 @@ define(['./baseCompareAscending'], function(baseCompareAscending) {
ordersLength = orders.length;
while (++index < length) {
- var result = baseCompareAscending(objCriteria[index], othCriteria[index]);
+ var result = compareAscending(objCriteria[index], othCriteria[index]);
if (result) {
if (index >= ordersLength) {
return result;
}
var order = orders[index];
- return result * ((order === 'asc' || order === true) ? 1 : -1);
+ return result * (order == 'desc' ? -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 47ac1101d..235cb8b16 100644
--- a/internal/composeArgs.js
+++ b/internal/composeArgs.js
@@ -1,6 +1,6 @@
define([], function() {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
diff --git a/internal/composeArgsRight.js b/internal/composeArgsRight.js
index 28dc476c6..be4623131 100644
--- a/internal/composeArgsRight.js
+++ b/internal/composeArgsRight.js
@@ -1,6 +1,6 @@
define([], function() {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
diff --git a/internal/arrayCopy.js b/internal/copyArray.js
similarity index 88%
rename from internal/arrayCopy.js
rename to internal/copyArray.js
index aec4a1e31..f3a514789 100644
--- a/internal/arrayCopy.js
+++ b/internal/copyArray.js
@@ -8,7 +8,7 @@ define([], function() {
* @param {Array} [array=[]] The array to copy values to.
* @returns {Array} Returns `array`.
*/
- function arrayCopy(source, array) {
+ function copyArray(source, array) {
var index = -1,
length = source.length;
@@ -19,5 +19,5 @@ define([], function() {
return array;
}
- return arrayCopy;
+ return copyArray;
});
diff --git a/internal/baseCopy.js b/internal/copyObject.js
similarity index 52%
rename from internal/baseCopy.js
rename to internal/copyObject.js
index 9411c9a58..fbca36528 100644
--- a/internal/baseCopy.js
+++ b/internal/copyObject.js
@@ -1,4 +1,4 @@
-define([], function() {
+define(['./copyObjectWith'], function(copyObjectWith) {
/**
* Copies properties of `source` to `object`.
@@ -9,18 +9,9 @@ define([], function() {
* @param {Object} [object={}] The object to copy properties to.
* @returns {Object} Returns `object`.
*/
- function baseCopy(source, props, object) {
- object || (object = {});
-
- var index = -1,
- length = props.length;
-
- while (++index < length) {
- var key = props[index];
- object[key] = source[key];
- }
- return object;
+ function copyObject(source, props, object) {
+ return copyObjectWith(source, props, object);
}
- return baseCopy;
+ return copyObject;
});
diff --git a/internal/copyObjectWith.js b/internal/copyObjectWith.js
new file mode 100644
index 000000000..2272e3dbb
--- /dev/null
+++ b/internal/copyObjectWith.js
@@ -0,0 +1,30 @@
+define(['./assignValue'], function(assignValue) {
+
+ /**
+ * This function is like `copyObject` except that it accepts a function to
+ * customize copied values.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @param {Function} [customizer] The function to customize copied values.
+ * @returns {Object} Returns `object`.
+ */
+ function copyObjectWith(source, props, object, customizer) {
+ object || (object = {});
+
+ var index = -1,
+ length = props.length;
+
+ while (++index < length) {
+ var key = props[index],
+ newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
+
+ assignValue(object, key, newValue);
+ }
+ return object;
+ }
+
+ return copyObjectWith;
+});
diff --git a/internal/copySymbols.js b/internal/copySymbols.js
new file mode 100644
index 000000000..e6b15c780
--- /dev/null
+++ b/internal/copySymbols.js
@@ -0,0 +1,16 @@
+define(['./copyObject', './getSymbols'], function(copyObject, getSymbols) {
+
+ /**
+ * Copies own symbol properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */
+ function copySymbols(source, object) {
+ return copyObject(source, getSymbols(source), object);
+ }
+
+ return copySymbols;
+});
diff --git a/internal/createAggregator.js b/internal/createAggregator.js
index ede68ac9c..55a15cb0c 100644
--- a/internal/createAggregator.js
+++ b/internal/createAggregator.js
@@ -1,7 +1,7 @@
-define(['./baseCallback', './baseEach', '../lang/isArray'], function(baseCallback, baseEach, isArray) {
+define(['./baseEach', './baseIteratee', '../isArray'], function(baseEach, baseIteratee, isArray) {
/**
- * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.
+ * Creates a function like `_.groupBy`.
*
* @private
* @param {Function} setter The function to set keys and values of the accumulator object.
@@ -9,9 +9,9 @@ define(['./baseCallback', './baseEach', '../lang/isArray'], function(baseCallbac
* @returns {Function} Returns the new aggregator function.
*/
function createAggregator(setter, initializer) {
- return function(collection, iteratee, thisArg) {
+ return function(collection, iteratee) {
var result = initializer ? initializer() : {};
- iteratee = baseCallback(iteratee, thisArg, 3);
+ iteratee = baseIteratee(iteratee);
if (isArray(collection)) {
var index = -1,
@@ -19,11 +19,11 @@ define(['./baseCallback', './baseEach', '../lang/isArray'], function(baseCallbac
while (++index < length) {
var value = collection[index];
- setter(result, value, iteratee(value, index, collection), collection);
+ setter(result, value, iteratee(value), collection);
}
} else {
baseEach(collection, function(value, key, collection) {
- setter(result, value, iteratee(value, key, collection), collection);
+ setter(result, value, iteratee(value), collection);
});
}
return result;
diff --git a/internal/createAssigner.js b/internal/createAssigner.js
index 921cb16f0..917a59598 100644
--- a/internal/createAssigner.js
+++ b/internal/createAssigner.js
@@ -1,34 +1,28 @@
-define(['./bindCallback', './isIterateeCall', '../function/restParam'], function(bindCallback, isIterateeCall, restParam) {
+define(['./isIterateeCall', '../rest'], function(isIterateeCall, rest) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/**
- * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
+ * Creates a function like `_.assign`.
*
* @private
* @param {Function} assigner The function to assign values.
* @returns {Function} Returns the new assigner function.
*/
function createAssigner(assigner) {
- return restParam(function(object, sources) {
+ return rest(function(object, sources) {
var index = -1,
- length = object == null ? 0 : sources.length,
- customizer = length > 2 ? sources[length - 2] : undefined,
- guard = length > 2 ? sources[2] : undefined,
- thisArg = length > 1 ? sources[length - 1] : undefined;
+ length = sources.length,
+ customizer = length > 1 ? sources[length - 1] : undefined,
+ guard = length > 2 ? sources[2] : undefined;
- if (typeof customizer == 'function') {
- customizer = bindCallback(customizer, thisArg, 5);
- length -= 2;
- } else {
- customizer = typeof thisArg == 'function' ? thisArg : undefined;
- length -= (customizer ? 1 : 0);
- }
+ customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
customizer = length < 3 ? undefined : customizer;
length = 1;
}
+ object = Object(object);
while (++index < length) {
var source = sources[index];
if (source) {
diff --git a/internal/createBaseEach.js b/internal/createBaseEach.js
index 4a93c585c..a5a8bab0c 100644
--- a/internal/createBaseEach.js
+++ b/internal/createBaseEach.js
@@ -1,4 +1,4 @@
-define(['./getLength', './isLength', './toObject'], function(getLength, isLength, toObject) {
+define(['../isArrayLike'], function(isArrayLike) {
/**
* Creates a `baseEach` or `baseEachRight` function.
@@ -10,12 +10,15 @@ define(['./getLength', './isLength', './toObject'], function(getLength, isLength
*/
function createBaseEach(eachFunc, fromRight) {
return function(collection, iteratee) {
- var length = collection ? getLength(collection) : 0;
- if (!isLength(length)) {
+ if (collection == null) {
+ return collection;
+ }
+ if (!isArrayLike(collection)) {
return eachFunc(collection, iteratee);
}
- var index = fromRight ? length : -1,
- iterable = toObject(collection);
+ var length = collection.length,
+ index = fromRight ? length : -1,
+ iterable = Object(collection);
while ((fromRight ? index-- : ++index < length)) {
if (iteratee(iterable[index], index, iterable) === false) {
diff --git a/internal/createBaseFor.js b/internal/createBaseFor.js
index 99f5f7076..fa545e504 100644
--- a/internal/createBaseFor.js
+++ b/internal/createBaseFor.js
@@ -1,7 +1,7 @@
-define(['./toObject'], function(toObject) {
+define([], function() {
/**
- * Creates a base function for `_.forIn` or `_.forInRight`.
+ * Creates a base function for methods like `_.forIn`.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
@@ -9,13 +9,13 @@ define(['./toObject'], function(toObject) {
*/
function createBaseFor(fromRight) {
return function(object, iteratee, keysFunc) {
- var iterable = toObject(object),
+ var index = -1,
+ iterable = Object(object),
props = keysFunc(object),
- length = props.length,
- index = fromRight ? length : -1;
+ length = props.length;
- while ((fromRight ? index-- : ++index < length)) {
- var key = props[index];
+ while (length--) {
+ var key = props[fromRight ? length : ++index];
if (iteratee(iterable[key], key, iterable) === false) {
break;
}
diff --git a/internal/createBaseWrapper.js b/internal/createBaseWrapper.js
new file mode 100644
index 000000000..9f385248e
--- /dev/null
+++ b/internal/createBaseWrapper.js
@@ -0,0 +1,28 @@
+define(['./createCtorWrapper', './root'], function(createCtorWrapper, root) {
+
+ /** Used to compose bitmasks for wrapper metadata. */
+ var BIND_FLAG = 1;
+
+ /**
+ * Creates a function that wraps `func` to invoke it with the optional `this`
+ * binding of `thisArg`.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createBaseWrapper(func, bitmask, thisArg) {
+ var isBind = bitmask & BIND_FLAG,
+ Ctor = createCtorWrapper(func);
+
+ function wrapper() {
+ var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+ return fn.apply(isBind ? thisArg : this, arguments);
+ }
+ return wrapper;
+ }
+
+ return createBaseWrapper;
+});
diff --git a/internal/createBindWrapper.js b/internal/createBindWrapper.js
deleted file mode 100644
index 104894c76..000000000
--- a/internal/createBindWrapper.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define(['./createCtorWrapper', './root'], function(createCtorWrapper, root) {
-
- /**
- * Creates a function that wraps `func` and invokes it with the `this`
- * binding of `thisArg`.
- *
- * @private
- * @param {Function} func The function to bind.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @returns {Function} Returns the new bound function.
- */
- function createBindWrapper(func, thisArg) {
- var Ctor = createCtorWrapper(func);
-
- function wrapper() {
- var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
- return fn.apply(thisArg, arguments);
- }
- return wrapper;
- }
-
- return createBindWrapper;
-});
diff --git a/internal/createCache.js b/internal/createCache.js
deleted file mode 100644
index ef7440565..000000000
--- a/internal/createCache.js
+++ /dev/null
@@ -1,21 +0,0 @@
-define(['./SetCache', './getNative', './root'], function(SetCache, getNative, root) {
-
- /** Native method references. */
- var Set = getNative(root, 'Set');
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeCreate = getNative(Object, 'create');
-
- /**
- * Creates a `Set` cache object to optimize linear searches of large arrays.
- *
- * @private
- * @param {Array} [values] The values to cache.
- * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.
- */
- function createCache(values) {
- return (nativeCreate && Set) ? new SetCache(values) : null;
- }
-
- return createCache;
-});
diff --git a/internal/createCaseFirst.js b/internal/createCaseFirst.js
new file mode 100644
index 000000000..77ce4e616
--- /dev/null
+++ b/internal/createCaseFirst.js
@@ -0,0 +1,37 @@
+define(['./stringToArray', '../toString'], function(stringToArray, toString) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to compose unicode character classes. */
+ var rsAstralRange = '\\ud800-\\udfff',
+ rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsVarRange = '\\ufe0e\\ufe0f';
+
+ /** Used to compose unicode capture groups. */
+ var rsZWJ = '\\u200d';
+
+ /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+ var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+
+ /**
+ * Creates a function like `_.lowerFirst`.
+ *
+ * @private
+ * @param {string} methodName The name of the `String` case method to use.
+ * @returns {Function} Returns the new function.
+ */
+ function createCaseFirst(methodName) {
+ return function(string) {
+ string = toString(string);
+
+ var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined,
+ chr = strSymbols ? strSymbols[0] : string.charAt(0),
+ trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
+
+ return chr[methodName]() + trailing;
+ };
+ }
+
+ return createCaseFirst;
+});
diff --git a/internal/createCompounder.js b/internal/createCompounder.js
index e542095b5..b5c060b38 100644
--- a/internal/createCompounder.js
+++ b/internal/createCompounder.js
@@ -1,8 +1,7 @@
-define(['../string/deburr', '../string/words'], function(deburr, words) {
+define(['./arrayReduce', '../deburr', '../words'], function(arrayReduce, deburr, words) {
/**
- * Creates a function that produces compound words out of the words in a
- * given string.
+ * Creates a function like `_.camelCase`.
*
* @private
* @param {Function} callback The function to combine each word.
@@ -10,15 +9,7 @@ define(['../string/deburr', '../string/words'], function(deburr, words) {
*/
function createCompounder(callback) {
return function(string) {
- var index = -1,
- array = words(deburr(string)),
- length = array.length,
- result = '';
-
- while (++index < length) {
- result = callback(result, array[index], index);
- }
- return result;
+ return arrayReduce(words(deburr(string)), callback, '');
};
}
diff --git a/internal/createCtorWrapper.js b/internal/createCtorWrapper.js
index f4355549a..1e2dd98c6 100644
--- a/internal/createCtorWrapper.js
+++ b/internal/createCtorWrapper.js
@@ -1,4 +1,4 @@
-define(['./baseCreate', '../lang/isObject'], function(baseCreate, isObject) {
+define(['./baseCreate', '../isObject'], function(baseCreate, isObject) {
/**
* Creates a function that produces an instance of `Ctor` regardless of
diff --git a/internal/createCurry.js b/internal/createCurry.js
deleted file mode 100644
index 9f30502f9..000000000
--- a/internal/createCurry.js
+++ /dev/null
@@ -1,26 +0,0 @@
-define(['./createWrapper', './isIterateeCall'], function(createWrapper, isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a `_.curry` or `_.curryRight` function.
- *
- * @private
- * @param {boolean} flag The curry bit flag.
- * @returns {Function} Returns the new curry function.
- */
- function createCurry(flag) {
- function curryFunc(func, arity, guard) {
- if (guard && isIterateeCall(func, arity, guard)) {
- arity = undefined;
- }
- var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);
- result.placeholder = curryFunc.placeholder;
- return result;
- }
- return curryFunc;
- }
-
- return createCurry;
-});
diff --git a/internal/createCurryWrapper.js b/internal/createCurryWrapper.js
new file mode 100644
index 000000000..c3422a046
--- /dev/null
+++ b/internal/createCurryWrapper.js
@@ -0,0 +1,41 @@
+define(['./apply', './createCtorWrapper', './createHybridWrapper', './createRecurryWrapper', './replaceHolders', './root'], function(apply, createCtorWrapper, createHybridWrapper, createRecurryWrapper, replaceHolders, root) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Creates a function that wraps `func` to enable currying.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
+ * @param {number} arity The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createCurryWrapper(func, bitmask, arity) {
+ var Ctor = createCtorWrapper(func);
+
+ function wrapper() {
+ var length = arguments.length,
+ index = length,
+ args = Array(length),
+ fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
+ placeholder = wrapper.placeholder;
+
+ while (index--) {
+ args[index] = arguments[index];
+ }
+ var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
+ ? []
+ : replaceHolders(args, placeholder);
+
+ length -= holders.length;
+ return length < arity
+ ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
+ : apply(fn, this, args);
+ }
+ return wrapper;
+ }
+
+ return createCurryWrapper;
+});
diff --git a/internal/createDefaults.js b/internal/createDefaults.js
deleted file mode 100644
index edab6d166..000000000
--- a/internal/createDefaults.js
+++ /dev/null
@@ -1,26 +0,0 @@
-define(['../function/restParam'], function(restParam) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * 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);
- });
- }
-
- return createDefaults;
-});
diff --git a/internal/createExtremum.js b/internal/createExtremum.js
deleted file mode 100644
index 1d88a8058..000000000
--- a/internal/createExtremum.js
+++ /dev/null
@@ -1,32 +0,0 @@
-define(['./arrayExtremum', './baseCallback', './baseExtremum', '../lang/isArray', './isIterateeCall', './toIterable'], function(arrayExtremum, baseCallback, baseExtremum, isArray, isIterateeCall, toIterable) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a `_.max` or `_.min` function.
- *
- * @private
- * @param {Function} comparator The function used to compare values.
- * @param {*} exValue The initial extremum value.
- * @returns {Function} Returns the new extremum function.
- */
- function createExtremum(comparator, exValue) {
- return function(collection, iteratee, thisArg) {
- if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = undefined;
- }
- iteratee = baseCallback(iteratee, thisArg, 3);
- if (iteratee.length == 1) {
- collection = isArray(collection) ? collection : toIterable(collection);
- var result = arrayExtremum(collection, iteratee, comparator, exValue);
- if (!(collection.length && result === exValue)) {
- return result;
- }
- }
- return baseExtremum(collection, iteratee, comparator, exValue);
- };
- }
-
- return createExtremum;
-});
diff --git a/internal/createFind.js b/internal/createFind.js
deleted file mode 100644
index 86bcba49e..000000000
--- a/internal/createFind.js
+++ /dev/null
@@ -1,26 +0,0 @@
-define(['./baseCallback', './baseFind', './baseFindIndex', '../lang/isArray'], function(baseCallback, baseFind, baseFindIndex, isArray) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a `_.find` or `_.findLast` function.
- *
- * @private
- * @param {Function} eachFunc The function to iterate over a collection.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new find function.
- */
- function createFind(eachFunc, fromRight) {
- return function(collection, predicate, thisArg) {
- predicate = baseCallback(predicate, thisArg, 3);
- if (isArray(collection)) {
- var index = baseFindIndex(collection, predicate, fromRight);
- return index > -1 ? collection[index] : undefined;
- }
- return baseFind(collection, predicate, eachFunc);
- };
- }
-
- return createFind;
-});
diff --git a/internal/createFindIndex.js b/internal/createFindIndex.js
deleted file mode 100644
index d088bbfd2..000000000
--- a/internal/createFindIndex.js
+++ /dev/null
@@ -1,21 +0,0 @@
-define(['./baseCallback', './baseFindIndex'], function(baseCallback, baseFindIndex) {
-
- /**
- * Creates a `_.findIndex` or `_.findLastIndex` function.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new find function.
- */
- function createFindIndex(fromRight) {
- return function(array, predicate, thisArg) {
- if (!(array && array.length)) {
- return -1;
- }
- predicate = baseCallback(predicate, thisArg, 3);
- return baseFindIndex(array, predicate, fromRight);
- };
- }
-
- return createFindIndex;
-});
diff --git a/internal/createFindKey.js b/internal/createFindKey.js
deleted file mode 100644
index 27736a935..000000000
--- a/internal/createFindKey.js
+++ /dev/null
@@ -1,18 +0,0 @@
-define(['./baseCallback', './baseFind'], function(baseCallback, baseFind) {
-
- /**
- * Creates a `_.findKey` or `_.findLastKey` function.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new find function.
- */
- function createFindKey(objectFunc) {
- return function(object, predicate, thisArg) {
- predicate = baseCallback(predicate, thisArg, 3);
- return baseFind(object, predicate, objectFunc, true);
- };
- }
-
- return createFindKey;
-});
diff --git a/internal/createFlow.js b/internal/createFlow.js
index 5859d3506..931bd24dc 100644
--- a/internal/createFlow.js
+++ b/internal/createFlow.js
@@ -1,4 +1,4 @@
-define(['./LodashWrapper', './getData', './getFuncName', '../lang/isArray', './isLaziable'], function(LodashWrapper, getData, getFuncName, isArray, isLaziable) {
+define(['./LodashWrapper', './baseFlatten', './getData', './getFuncName', '../isArray', './isLaziable', '../rest'], function(LodashWrapper, baseFlatten, getData, getFuncName, isArray, isLaziable, rest) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -23,23 +23,26 @@ define(['./LodashWrapper', './getData', './getFuncName', '../lang/isArray', './i
* @returns {Function} Returns the new flow function.
*/
function createFlow(fromRight) {
- return function() {
- var wrapper,
- length = arguments.length,
- index = fromRight ? length : -1,
- leftIndex = 0,
- funcs = Array(length);
+ return rest(function(funcs) {
+ funcs = baseFlatten(funcs);
- while ((fromRight ? index-- : ++index < length)) {
- var func = funcs[leftIndex++] = arguments[index];
+ var length = funcs.length,
+ index = length,
+ prereq = LodashWrapper.prototype.thru;
+
+ if (fromRight) {
+ funcs.reverse();
+ }
+ while (index--) {
+ var func = funcs[index];
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {
- wrapper = new LodashWrapper([], true);
+ if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
+ var wrapper = new LodashWrapper([], true);
}
}
- index = wrapper ? -1 : length;
+ index = wrapper ? index : length;
while (++index < length) {
func = funcs[index];
@@ -67,7 +70,7 @@ define(['./LodashWrapper', './getData', './getFuncName', '../lang/isArray', './i
}
return result;
};
- };
+ });
}
return createFlow;
diff --git a/internal/createForEach.js b/internal/createForEach.js
deleted file mode 100644
index fe72e18ba..000000000
--- a/internal/createForEach.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define(['./bindCallback', '../lang/isArray'], function(bindCallback, isArray) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a function for `_.forEach` or `_.forEachRight`.
- *
- * @private
- * @param {Function} arrayFunc The function to iterate over an array.
- * @param {Function} eachFunc The function to iterate over a collection.
- * @returns {Function} Returns the new each function.
- */
- function createForEach(arrayFunc, eachFunc) {
- return function(collection, iteratee, thisArg) {
- return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
- ? arrayFunc(collection, iteratee)
- : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
- };
- }
-
- return createForEach;
-});
diff --git a/internal/createForIn.js b/internal/createForIn.js
deleted file mode 100644
index b39bb5e7f..000000000
--- a/internal/createForIn.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define(['./bindCallback', '../object/keysIn'], function(bindCallback, keysIn) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a function for `_.forIn` or `_.forInRight`.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new each function.
- */
- function createForIn(objectFunc) {
- return function(object, iteratee, thisArg) {
- if (typeof iteratee != 'function' || thisArg !== undefined) {
- iteratee = bindCallback(iteratee, thisArg, 3);
- }
- return objectFunc(object, iteratee, keysIn);
- };
- }
-
- return createForIn;
-});
diff --git a/internal/createForOwn.js b/internal/createForOwn.js
deleted file mode 100644
index 97bd3e853..000000000
--- a/internal/createForOwn.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define(['./bindCallback'], function(bindCallback) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a function for `_.forOwn` or `_.forOwnRight`.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new each function.
- */
- function createForOwn(objectFunc) {
- return function(object, iteratee, thisArg) {
- if (typeof iteratee != 'function' || thisArg !== undefined) {
- iteratee = bindCallback(iteratee, thisArg, 3);
- }
- return objectFunc(object, iteratee);
- };
- }
-
- return createForOwn;
-});
diff --git a/internal/createHybridWrapper.js b/internal/createHybridWrapper.js
index 1c7dabc73..92ae56c6f 100644
--- a/internal/createHybridWrapper.js
+++ b/internal/createHybridWrapper.js
@@ -1,4 +1,4 @@
-define(['./arrayCopy', './composeArgs', './composeArgsRight', './createCtorWrapper', './isLaziable', './reorder', './replaceHolders', './root', './setData'], function(arrayCopy, composeArgs, composeArgsRight, createCtorWrapper, isLaziable, reorder, replaceHolders, root, setData) {
+define(['./composeArgs', './composeArgsRight', './createCtorWrapper', './createRecurryWrapper', './reorder', './replaceHolders', './root'], function(composeArgs, composeArgsRight, createCtorWrapper, createRecurryWrapper, reorder, replaceHolders, root) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -6,23 +6,18 @@ define(['./arrayCopy', './composeArgs', './composeArgsRight', './createCtorWrapp
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
BIND_KEY_FLAG = 2,
- CURRY_BOUND_FLAG = 4,
CURRY_FLAG = 8,
CURRY_RIGHT_FLAG = 16,
- PARTIAL_FLAG = 32,
- PARTIAL_RIGHT_FLAG = 64,
- ARY_FLAG = 128;
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeMax = Math.max;
+ ARY_FLAG = 128,
+ FLIP_FLAG = 512;
/**
- * Creates a function that wraps `func` and invokes it with optional `this`
- * binding of, partial application, and currying.
+ * Creates a function that wraps `func` to invoke it with optional `this`
+ * binding of `thisArg`, partial application, and currying.
*
* @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
+ * @param {Function|string} func The function or method name to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to prepend to those provided to the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
@@ -38,13 +33,11 @@ define(['./arrayCopy', './composeArgs', './composeArgsRight', './createCtorWrapp
isBind = bitmask & BIND_FLAG,
isBindKey = bitmask & BIND_KEY_FLAG,
isCurry = bitmask & CURRY_FLAG,
- isCurryBound = bitmask & CURRY_BOUND_FLAG,
isCurryRight = bitmask & CURRY_RIGHT_FLAG,
+ isFlip = bitmask & FLIP_FLAG,
Ctor = isBindKey ? undefined : createCtorWrapper(func);
function wrapper() {
- // Avoid `arguments` object use disqualifying optimizations by
- // converting it to an array before providing it to other functions.
var length = arguments.length,
index = length,
args = Array(length);
@@ -64,27 +57,7 @@ define(['./arrayCopy', './composeArgs', './composeArgsRight', './createCtorWrapp
length -= argsHolders.length;
if (length < arity) {
- var newArgPos = argPos ? arrayCopy(argPos) : undefined,
- newArity = nativeMax(arity - length, 0),
- 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);
-
- if (!isCurryBound) {
- bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
- }
- var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
- result = createHybridWrapper.apply(undefined, newData);
-
- if (isLaziable(func)) {
- setData(result, newData);
- }
- result.placeholder = placeholder;
- return result;
+ return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
}
}
var thisBinding = isBind ? thisArg : this,
@@ -92,12 +65,14 @@ define(['./arrayCopy', './composeArgs', './composeArgsRight', './createCtorWrapp
if (argPos) {
args = reorder(args, argPos);
+ } else if (isFlip && args.length > 1) {
+ args.reverse();
}
if (isAry && ary < args.length) {
args.length = ary;
}
if (this && this !== root && this instanceof wrapper) {
- fn = Ctor || createCtorWrapper(func);
+ fn = Ctor || createCtorWrapper(fn);
}
return fn.apply(thisBinding, args);
}
diff --git a/internal/createObjectMapper.js b/internal/createObjectMapper.js
deleted file mode 100644
index 80e15f340..000000000
--- a/internal/createObjectMapper.js
+++ /dev/null
@@ -1,26 +0,0 @@
-define(['./baseCallback', './baseForOwn'], function(baseCallback, baseForOwn) {
-
- /**
- * Creates a function for `_.mapKeys` or `_.mapValues`.
- *
- * @private
- * @param {boolean} [isMapKeys] Specify mapping keys instead of values.
- * @returns {Function} Returns the new map function.
- */
- function createObjectMapper(isMapKeys) {
- return function(object, iteratee, thisArg) {
- var result = {};
- iteratee = baseCallback(iteratee, thisArg, 3);
-
- baseForOwn(object, function(value, key, object) {
- var mapped = iteratee(value, key, object);
- key = isMapKeys ? mapped : key;
- value = isMapKeys ? value : mapped;
- result[key] = value;
- });
- return result;
- };
- }
-
- return createObjectMapper;
-});
diff --git a/internal/createOver.js b/internal/createOver.js
new file mode 100644
index 000000000..659333ea3
--- /dev/null
+++ b/internal/createOver.js
@@ -0,0 +1,23 @@
+define(['./apply', './arrayMap', './baseFlatten', './baseIteratee', '../rest'], function(apply, arrayMap, baseFlatten, baseIteratee, rest) {
+
+ /**
+ * Creates a function like `_.over`.
+ *
+ * @private
+ * @param {Function} arrayFunc The function to iterate over iteratees.
+ * @returns {Function} Returns the new invoker function.
+ */
+ function createOver(arrayFunc) {
+ return rest(function(iteratees) {
+ iteratees = arrayMap(baseFlatten(iteratees), baseIteratee);
+ return rest(function(args) {
+ var thisArg = this;
+ return arrayFunc(iteratees, function(iteratee) {
+ return apply(iteratee, thisArg, args);
+ });
+ });
+ });
+ }
+
+ return createOver;
+});
diff --git a/internal/createPadDir.js b/internal/createPadDir.js
deleted file mode 100644
index 092fbcdef..000000000
--- a/internal/createPadDir.js
+++ /dev/null
@@ -1,18 +0,0 @@
-define(['./baseToString', './createPadding'], function(baseToString, createPadding) {
-
- /**
- * Creates a function for `_.padLeft` or `_.padRight`.
- *
- * @private
- * @param {boolean} [fromRight] Specify padding from the right.
- * @returns {Function} Returns the new pad function.
- */
- function createPadDir(fromRight) {
- return function(string, length, chars) {
- string = baseToString(string);
- return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string);
- };
- }
-
- return createPadDir;
-});
diff --git a/internal/createPadding.js b/internal/createPadding.js
index f0b0298eb..9e4764ba1 100644
--- a/internal/createPadding.js
+++ b/internal/createPadding.js
@@ -1,29 +1,46 @@
-define(['../string/repeat', './root'], function(repeat, root) {
+define(['../repeat', './stringSize', './stringToArray', '../toInteger'], function(repeat, stringSize, stringToArray, toInteger) {
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeCeil = Math.ceil,
- nativeIsFinite = root.isFinite;
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to compose unicode character classes. */
+ var rsAstralRange = '\\ud800-\\udfff',
+ rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsVarRange = '\\ufe0e\\ufe0f';
+
+ /** Used to compose unicode capture groups. */
+ var rsZWJ = '\\u200d';
+
+ /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+ var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeCeil = Math.ceil;
/**
- * Creates the padding required for `string` based on the given `length`.
- * The `chars` string is truncated if the number of characters exceeds `length`.
+ * Creates the padding for `string` based on `length`. The `chars` string
+ * is truncated if the number of characters exceeds `length`.
*
* @private
* @param {string} string The string to create padding for.
* @param {number} [length=0] The padding length.
* @param {string} [chars=' '] The string used as padding.
- * @returns {string} Returns the pad for `string`.
+ * @returns {string} Returns the padding for `string`.
*/
function createPadding(string, length, chars) {
- var strLength = string.length;
- length = +length;
+ length = toInteger(length);
- if (strLength >= length || !nativeIsFinite(length)) {
+ var strLength = stringSize(string);
+ if (!length || strLength >= length) {
return '';
}
var padLength = length - strLength;
- chars = chars == null ? ' ' : (chars + '');
- return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);
+ chars = chars === undefined ? ' ' : (chars + '');
+
+ var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
+ return reHasComplexSymbol.test(chars)
+ ? stringToArray(result).slice(0, padLength).join('')
+ : result.slice(0, padLength);
}
return createPadding;
diff --git a/internal/createPartial.js b/internal/createPartial.js
deleted file mode 100644
index cf1bf8f0a..000000000
--- a/internal/createPartial.js
+++ /dev/null
@@ -1,22 +0,0 @@
-define(['./createWrapper', './replaceHolders', '../function/restParam'], function(createWrapper, replaceHolders, restParam) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a `_.partial` or `_.partialRight` function.
- *
- * @private
- * @param {boolean} flag The partial bit flag.
- * @returns {Function} Returns the new partial function.
- */
- function createPartial(flag) {
- var partialFunc = restParam(function(func, partials) {
- var holders = replaceHolders(partials, partialFunc.placeholder);
- return createWrapper(func, flag, undefined, partials, holders);
- });
- return partialFunc;
- }
-
- return createPartial;
-});
diff --git a/internal/createPartialWrapper.js b/internal/createPartialWrapper.js
index 0d256ceee..b8a5942f9 100644
--- a/internal/createPartialWrapper.js
+++ b/internal/createPartialWrapper.js
@@ -1,32 +1,31 @@
-define(['./createCtorWrapper', './root'], function(createCtorWrapper, root) {
+define(['./apply', './createCtorWrapper', './root'], function(apply, createCtorWrapper, root) {
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1;
/**
- * Creates a function that wraps `func` and invokes it with the optional `this`
+ * Creates a function that wraps `func` to invoke it with the optional `this`
* binding of `thisArg` and the `partials` prepended to those provided to
* the wrapper.
*
* @private
- * @param {Function} func The function to partially apply arguments to.
- * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} partials The arguments to prepend to those provided to the new function.
- * @returns {Function} Returns the new bound function.
+ * @returns {Function} Returns the new wrapped function.
*/
function createPartialWrapper(func, bitmask, thisArg, partials) {
var isBind = bitmask & BIND_FLAG,
Ctor = createCtorWrapper(func);
function wrapper() {
- // Avoid `arguments` object use disqualifying optimizations by
- // converting it to an array before providing it `func`.
var argsIndex = -1,
argsLength = arguments.length,
leftIndex = -1,
leftLength = partials.length,
- args = Array(leftLength + argsLength);
+ args = Array(leftLength + argsLength),
+ fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
while (++leftIndex < leftLength) {
args[leftIndex] = partials[leftIndex];
@@ -34,8 +33,7 @@ define(['./createCtorWrapper', './root'], function(createCtorWrapper, root) {
while (argsLength--) {
args[leftIndex++] = arguments[++argsIndex];
}
- var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
- return fn.apply(isBind ? thisArg : this, args);
+ return apply(fn, isBind ? thisArg : this, args);
}
return wrapper;
}
diff --git a/internal/createRange.js b/internal/createRange.js
new file mode 100644
index 000000000..08f92f244
--- /dev/null
+++ b/internal/createRange.js
@@ -0,0 +1,33 @@
+define(['./baseRange', './isIterateeCall', '../toNumber'], function(baseRange, isIterateeCall, toNumber) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Creates a `_.range` or `_.rangeRight` function.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new range function.
+ */
+ function createRange(fromRight) {
+ return function(start, end, step) {
+ if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
+ end = step = undefined;
+ }
+ // Ensure the sign of `-0` is preserved.
+ start = toNumber(start);
+ start = start === start ? start : 0;
+ if (end === undefined) {
+ end = start;
+ start = 0;
+ } else {
+ end = toNumber(end) || 0;
+ }
+ step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
+ return baseRange(start, end, step, fromRight);
+ };
+ }
+
+ return createRange;
+});
diff --git a/internal/createRecurryWrapper.js b/internal/createRecurryWrapper.js
new file mode 100644
index 000000000..26e51f37f
--- /dev/null
+++ b/internal/createRecurryWrapper.js
@@ -0,0 +1,55 @@
+define(['./copyArray', './isLaziable', './setData'], function(copyArray, isLaziable, setData) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to compose bitmasks for wrapper metadata. */
+ var BIND_FLAG = 1,
+ BIND_KEY_FLAG = 2,
+ CURRY_BOUND_FLAG = 4,
+ CURRY_FLAG = 8,
+ PARTIAL_FLAG = 32,
+ PARTIAL_RIGHT_FLAG = 64;
+
+ /**
+ * Creates a function that wraps `func` to continue currying.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
+ * @param {Function} wrapFunc The function to create the `func` wrapper.
+ * @param {*} placeholder The placeholder to replace.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to prepend to those provided to the new function.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
+ var isCurry = bitmask & CURRY_FLAG,
+ newArgPos = argPos ? copyArray(argPos) : undefined,
+ newsHolders = isCurry ? holders : undefined,
+ newHoldersRight = isCurry ? undefined : holders,
+ newPartials = isCurry ? partials : undefined,
+ newPartialsRight = isCurry ? undefined : partials;
+
+ bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
+ bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
+
+ if (!(bitmask & CURRY_BOUND_FLAG)) {
+ bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
+ }
+ var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity],
+ result = wrapFunc.apply(undefined, newData);
+
+ if (isLaziable(func)) {
+ setData(result, newData);
+ }
+ result.placeholder = placeholder;
+ return result;
+ }
+
+ return createRecurryWrapper;
+});
diff --git a/internal/createReduce.js b/internal/createReduce.js
deleted file mode 100644
index 8576c299d..000000000
--- a/internal/createReduce.js
+++ /dev/null
@@ -1,24 +0,0 @@
-define(['./baseCallback', './baseReduce', '../lang/isArray'], function(baseCallback, baseReduce, isArray) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a function for `_.reduce` or `_.reduceRight`.
- *
- * @private
- * @param {Function} arrayFunc The function to iterate over an array.
- * @param {Function} eachFunc The function to iterate over a collection.
- * @returns {Function} Returns the new each function.
- */
- function createReduce(arrayFunc, eachFunc) {
- return function(collection, iteratee, accumulator, thisArg) {
- var initFromArray = arguments.length < 3;
- return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
- ? arrayFunc(collection, iteratee, accumulator, initFromArray)
- : baseReduce(collection, baseCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);
- };
- }
-
- return createReduce;
-});
diff --git a/internal/createRound.js b/internal/createRound.js
index 2314c4102..a6902dd2a 100644
--- a/internal/createRound.js
+++ b/internal/createRound.js
@@ -1,13 +1,7 @@
-define([], function() {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /** Native method references. */
- var pow = Math.pow;
+define(['../toInteger', '../toNumber', '../toString'], function(toInteger, toNumber, toString) {
/**
- * Creates a `_.ceil`, `_.floor`, or `_.round` function.
+ * Creates a function like `_.round`.
*
* @private
* @param {string} methodName The name of the `Math` method to use when rounding.
@@ -16,10 +10,16 @@ define([], function() {
function createRound(methodName) {
var func = Math[methodName];
return function(number, precision) {
- precision = precision === undefined ? 0 : (+precision || 0);
+ number = toNumber(number);
+ precision = toInteger(precision);
if (precision) {
- precision = pow(10, precision);
- return func(number * precision) / precision;
+ // Shift with exponential notation to avoid floating-point issues.
+ // See [MDN](https://mdn.io/round#Examples) for more details.
+ var pair = (toString(number) + 'e').split('e'),
+ value = func(pair[0] + 'e' + (+pair[1] + precision));
+
+ pair = (toString(value) + 'e').split('e');
+ return +(pair[0] + 'e' + (+pair[1] - precision));
}
return func(number);
};
diff --git a/internal/createSet.js b/internal/createSet.js
new file mode 100644
index 000000000..3c0249535
--- /dev/null
+++ b/internal/createSet.js
@@ -0,0 +1,15 @@
+define(['./Set', '../noop'], function(Set, noop) {
+
+ /**
+ * Creates a set of `values`.
+ *
+ * @private
+ * @param {Array} values The values to add to the set.
+ * @returns {Object} Returns the new set.
+ */
+ var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
+ return new Set(values);
+ };
+
+ return createSet;
+});
diff --git a/internal/createSortedIndex.js b/internal/createSortedIndex.js
deleted file mode 100644
index 7c0f2035d..000000000
--- a/internal/createSortedIndex.js
+++ /dev/null
@@ -1,19 +0,0 @@
-define(['./baseCallback', './binaryIndex', './binaryIndexBy'], function(baseCallback, binaryIndex, binaryIndexBy) {
-
- /**
- * Creates a `_.sortedIndex` or `_.sortedLastIndex` function.
- *
- * @private
- * @param {boolean} [retHighest] Specify returning the highest qualified index.
- * @returns {Function} Returns the new index function.
- */
- function createSortedIndex(retHighest) {
- return function(array, value, iteratee, thisArg) {
- return iteratee == null
- ? binaryIndex(array, value, retHighest)
- : binaryIndexBy(array, value, baseCallback(iteratee, thisArg, 1), retHighest);
- };
- }
-
- return createSortedIndex;
-});
diff --git a/internal/createWrapper.js b/internal/createWrapper.js
index f4a8c2e3a..98045550e 100644
--- a/internal/createWrapper.js
+++ b/internal/createWrapper.js
@@ -1,4 +1,4 @@
-define(['./baseSetData', './createBindWrapper', './createHybridWrapper', './createPartialWrapper', './getData', './mergeData', './setData'], function(baseSetData, createBindWrapper, createHybridWrapper, createPartialWrapper, getData, mergeData, setData) {
+define(['./baseSetData', './createBaseWrapper', './createCurryWrapper', './createHybridWrapper', './createPartialWrapper', './getData', './mergeData', './setData', '../toInteger'], function(baseSetData, createBaseWrapper, createCurryWrapper, createHybridWrapper, createPartialWrapper, getData, mergeData, setData, toInteger) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -6,13 +6,15 @@ define(['./baseSetData', './createBindWrapper', './createHybridWrapper', './crea
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
BIND_KEY_FLAG = 2,
+ CURRY_FLAG = 8,
+ CURRY_RIGHT_FLAG = 16,
PARTIAL_FLAG = 32,
PARTIAL_RIGHT_FLAG = 64;
/** 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. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
@@ -20,8 +22,8 @@ define(['./baseSetData', './createBindWrapper', './createHybridWrapper', './crea
* `this` binding and partially applied arguments.
*
* @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of flags.
+ * @param {Function|string} func The function or method name to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags.
* The bitmask may be composed of the following flags:
* 1 - `_.bind`
* 2 - `_.bindKey`
@@ -50,7 +52,10 @@ define(['./baseSetData', './createBindWrapper', './createHybridWrapper', './crea
bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
partials = holders = undefined;
}
- length -= (holders ? holders.length : 0);
+ ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
+ arity = arity === undefined ? arity : toInteger(arity);
+ length -= holders ? holders.length : 0;
+
if (bitmask & PARTIAL_RIGHT_FLAG) {
var partialsRight = partials,
holdersRight = holders;
@@ -62,17 +67,25 @@ define(['./baseSetData', './createBindWrapper', './createHybridWrapper', './crea
if (data) {
mergeData(newData, data);
- bitmask = newData[1];
- arity = newData[9];
}
- newData[9] = arity == null
+ func = newData[0];
+ bitmask = newData[1];
+ thisArg = newData[2];
+ partials = newData[3];
+ holders = newData[4];
+ arity = newData[9] = newData[9] == null
? (isBindKey ? 0 : func.length)
- : (nativeMax(arity - length, 0) || 0);
+ : nativeMax(newData[9] - length, 0);
- if (bitmask == BIND_FLAG) {
- var result = createBindWrapper(newData[0], newData[2]);
- } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
- result = createPartialWrapper.apply(undefined, newData);
+ if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
+ bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
+ }
+ if (!bitmask || bitmask == BIND_FLAG) {
+ var result = createBaseWrapper(func, bitmask, thisArg);
+ } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
+ result = createCurryWrapper(func, bitmask, arity);
+ } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
+ result = createPartialWrapper(func, bitmask, thisArg, partials);
} else {
result = createHybridWrapper.apply(undefined, newData);
}
diff --git a/internal/equalArrays.js b/internal/equalArrays.js
index bf57df658..47b3c47a0 100644
--- a/internal/equalArrays.js
+++ b/internal/equalArrays.js
@@ -3,6 +3,10 @@ define(['./arraySome'], function(arraySome) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
+ /** Used to compose bitmasks for comparison styles. */
+ var UNORDERED_COMPARE_FLAG = 1,
+ PARTIAL_COMPARE_FLAG = 2;
+
/**
* A specialized version of `baseIsEqualDeep` for arrays with support for
* partial deep comparisons.
@@ -11,44 +15,61 @@ define(['./arraySome'], function(arraySome) {
* @param {Array} array The array to compare.
* @param {Array} other The other array to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} [customizer] The function to customize comparing arrays.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
- * @param {Array} [stackA] Tracks traversed `value` objects.
- * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `array` and `other` objects.
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
*/
- function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
+ function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
var index = -1,
+ isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+ isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
arrLength = array.length,
othLength = other.length;
- if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
+ if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
return false;
}
+ // Assume cyclic values are equal.
+ var stacked = stack.get(array);
+ if (stacked) {
+ return stacked == other;
+ }
+ var result = true;
+ stack.set(array, other);
+
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
- othValue = other[index],
- result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
+ othValue = other[index];
- if (result !== undefined) {
- if (result) {
+ if (customizer) {
+ var compared = isPartial
+ ? customizer(othValue, arrValue, index, other, array, stack)
+ : customizer(arrValue, othValue, index, array, other, stack);
+ }
+ if (compared !== undefined) {
+ if (compared) {
continue;
}
- return false;
+ result = false;
+ break;
}
// Recursively compare arrays (susceptible to call stack limits).
- if (isLoose) {
+ if (isUnordered) {
if (!arraySome(other, function(othValue) {
- return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
+ return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
})) {
- return false;
+ result = false;
+ break;
}
- } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
- return false;
+ } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
+ result = false;
+ break;
}
}
- return true;
+ stack['delete'](array);
+ return result;
}
return equalArrays;
diff --git a/internal/equalByTag.js b/internal/equalByTag.js
index a77428551..0659481d1 100644
--- a/internal/equalByTag.js
+++ b/internal/equalByTag.js
@@ -1,12 +1,28 @@
-define([], function() {
+define(['./Uint8Array', './_Symbol', './mapToArray', './setToArray'], function(Uint8Array, _Symbol, mapToArray, setToArray) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to compose bitmasks for comparison styles. */
+ var UNORDERED_COMPARE_FLAG = 1,
+ PARTIAL_COMPARE_FLAG = 2;
/** `Object#toString` result references. */
var boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
+ mapTag = '[object Map]',
numberTag = '[object Number]',
regexpTag = '[object RegExp]',
- stringTag = '[object String]';
+ setTag = '[object Set]',
+ stringTag = '[object String]',
+ symbolTag = '[object Symbol]';
+
+ var arrayBufferTag = '[object ArrayBuffer]';
+
+ /** Used to convert symbols to primitives and strings. */
+ var symbolProto = _Symbol ? _Symbol.prototype : undefined,
+ symbolValueOf = _Symbol ? symbolProto.valueOf : undefined;
/**
* A specialized version of `baseIsEqualDeep` for comparing objects of
@@ -19,10 +35,20 @@ define([], function() {
* @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.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function equalByTag(object, other, tag) {
+ function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
switch (tag) {
+ case arrayBufferTag:
+ if ((object.byteLength != other.byteLength) ||
+ !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
+ return false;
+ }
+ return true;
+
case boolTag:
case dateTag:
// Coerce dates and booleans to numbers, dates to milliseconds and booleans
@@ -34,15 +60,27 @@ define([], function() {
case numberTag:
// Treat `NaN` vs. `NaN` as equal.
- return (object != +object)
- ? other != +other
- : object == +other;
+ return (object != +object) ? other != +other : object == +other;
case regexpTag:
case stringTag:
// Coerce regexes to strings and treat strings primitives and string
// objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
return object == (other + '');
+
+ case mapTag:
+ var convert = mapToArray;
+
+ case setTag:
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
+ convert || (convert = setToArray);
+
+ // Recursively compare objects (susceptible to call stack limits).
+ return (isPartial || object.size == other.size) &&
+ equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
+
+ case symbolTag:
+ return !!_Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
}
return false;
}
diff --git a/internal/equalObjects.js b/internal/equalObjects.js
index 612404e43..7046b7098 100644
--- a/internal/equalObjects.js
+++ b/internal/equalObjects.js
@@ -1,13 +1,11 @@
-define(['../object/keys'], function(keys) {
+define(['./baseHas', '../keys'], function(baseHas, keys) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty = objectProto.hasOwnProperty;
+ /** Used to compose bitmasks for comparison styles. */
+ var UNORDERED_COMPARE_FLAG = 1,
+ PARTIAL_COMPARE_FLAG = 2;
/**
* A specialized version of `baseIsEqualDeep` for objects with support for
@@ -17,42 +15,60 @@ define(['../object/keys'], function(keys) {
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} [customizer] The function to customize comparing values.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
- * @param {Array} [stackA] Tracks traversed `value` objects.
- * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
- var objProps = keys(object),
+ function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+ isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
+ objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
- if (objLength != othLength && !isLoose) {
+ if (objLength != othLength && !isPartial) {
return false;
}
var index = objLength;
while (index--) {
var key = objProps[index];
- if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
+ if (!(isPartial ? key in other : baseHas(other, key)) ||
+ !(isUnordered || key == othProps[index])) {
return false;
}
}
- var skipCtor = isLoose;
+ // Assume cyclic values are equal.
+ var stacked = stack.get(object);
+ if (stacked) {
+ return stacked == other;
+ }
+ var result = true;
+ stack.set(object, other);
+
+ var skipCtor = isPartial;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
- othValue = other[key],
- result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;
+ othValue = other[key];
+ if (customizer) {
+ var compared = isPartial
+ ? customizer(othValue, objValue, key, other, object, stack)
+ : customizer(objValue, othValue, key, object, other, stack);
+ }
// Recursively compare objects (susceptible to call stack limits).
- if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
- return false;
+ if (!(compared === undefined
+ ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
+ : compared
+ )) {
+ result = false;
+ break;
}
skipCtor || (skipCtor = key == 'constructor');
}
- if (!skipCtor) {
+ if (result && !skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
@@ -61,10 +77,11 @@ define(['../object/keys'], function(keys) {
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
- return false;
+ result = false;
}
}
- return true;
+ stack['delete'](object);
+ return result;
}
return equalObjects;
diff --git a/internal/escapeRegExpChar.js b/internal/escapeRegExpChar.js
deleted file mode 100644
index 228f4d12e..000000000
--- a/internal/escapeRegExpChar.js
+++ /dev/null
@@ -1,41 +0,0 @@
-define([], function() {
-
- /** 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;
- }
-
- return escapeRegExpChar;
-});
diff --git a/internal/getData.js b/internal/getData.js
index a508896bb..7fb6f9043 100644
--- a/internal/getData.js
+++ b/internal/getData.js
@@ -1,4 +1,4 @@
-define(['./metaMap', '../utility/noop'], function(metaMap, noop) {
+define(['./metaMap', '../noop'], function(metaMap, noop) {
/**
* Gets metadata for `func`.
diff --git a/internal/getMatchData.js b/internal/getMatchData.js
index e72a66a80..db8f88b6c 100644
--- a/internal/getMatchData.js
+++ b/internal/getMatchData.js
@@ -1,14 +1,14 @@
-define(['./isStrictComparable', '../object/pairs'], function(isStrictComparable, pairs) {
+define(['./isStrictComparable', '../toPairs'], function(isStrictComparable, toPairs) {
/**
- * Gets the propery names, values, and compare flags of `object`.
+ * Gets the property names, values, and compare flags of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the match data of `object`.
*/
function getMatchData(object) {
- var result = pairs(object),
+ var result = toPairs(object),
length = result.length;
while (length--) {
diff --git a/internal/getNative.js b/internal/getNative.js
index 7d821b31a..8c33541a8 100644
--- a/internal/getNative.js
+++ b/internal/getNative.js
@@ -1,4 +1,4 @@
-define(['../lang/isNative'], function(isNative) {
+define(['../isNative'], function(isNative) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
diff --git a/internal/getSymbols.js b/internal/getSymbols.js
new file mode 100644
index 000000000..bb47d7147
--- /dev/null
+++ b/internal/getSymbols.js
@@ -0,0 +1,18 @@
+define([], function() {
+
+ /** Built-in value references. */
+ var getOwnPropertySymbols = Object.getOwnPropertySymbols;
+
+ /**
+ * Creates an array of the own symbol properties of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+ var getSymbols = getOwnPropertySymbols || function() {
+ return [];
+ };
+
+ return getSymbols;
+});
diff --git a/internal/getTag.js b/internal/getTag.js
new file mode 100644
index 000000000..3536eaf49
--- /dev/null
+++ b/internal/getTag.js
@@ -0,0 +1,55 @@
+define(['./Map', './Set'], function(Map, Set) {
+
+ /** `Object#toString` result references. */
+ var mapTag = '[object Map]',
+ objectTag = '[object Object]',
+ setTag = '[object Set]';
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to resolve the decompiled source of functions. */
+ var funcToString = Function.prototype.toString;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString = objectProto.toString;
+
+ /** Used to detect maps and sets. */
+ var mapCtorString = Map ? funcToString.call(Map) : '',
+ setCtorString = Set ? funcToString.call(Set) : '';
+
+ /**
+ * Gets the `toStringTag` of `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */
+ function getTag(value) {
+ return objectToString.call(value);
+ }
+
+ // Fallback for IE 11 providing `toStringTag` values for maps and sets.
+ if ((Map && getTag(new Map) != mapTag) || (Set && getTag(new Set) != setTag)) {
+ getTag = function(value) {
+ var result = objectToString.call(value),
+ Ctor = result == objectTag ? value.constructor : null,
+ ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
+
+ if (ctorString) {
+ if (ctorString == mapCtorString) {
+ return mapTag;
+ }
+ if (ctorString == setCtorString) {
+ return setTag;
+ }
+ }
+ return result;
+ };
+ }
+
+ return getTag;
+});
diff --git a/internal/getView.js b/internal/getView.js
index 7d0c74267..a36ecb10b 100644
--- a/internal/getView.js
+++ b/internal/getView.js
@@ -1,6 +1,6 @@
define([], function() {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
diff --git a/internal/hasPath.js b/internal/hasPath.js
new file mode 100644
index 000000000..dfc6098e8
--- /dev/null
+++ b/internal/hasPath.js
@@ -0,0 +1,30 @@
+define(['./baseToPath', '../isArguments', '../isArray', './isIndex', './isKey', '../isLength', '../isString', '../last', './parent'], function(baseToPath, isArguments, isArray, isIndex, isKey, isLength, isString, last, parent) {
+
+ /**
+ * Checks if `path` exists on `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @param {Function} hasFunc The function to check properties.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ */
+ function hasPath(object, path, hasFunc) {
+ if (object == null) {
+ return false;
+ }
+ var result = hasFunc(object, path);
+ if (!result && !isKey(path)) {
+ path = baseToPath(path);
+ object = parent(object, path);
+ if (object != null) {
+ path = last(path);
+ result = hasFunc(object, path);
+ }
+ }
+ return result || (isLength(object && object.length) && isIndex(path, object.length) &&
+ (isArray(object) || isString(object) || isArguments(object)));
+ }
+
+ return hasPath;
+});
diff --git a/internal/hashDelete.js b/internal/hashDelete.js
new file mode 100644
index 000000000..b36cfafb8
--- /dev/null
+++ b/internal/hashDelete.js
@@ -0,0 +1,16 @@
+define(['./hashHas'], function(hashHas) {
+
+ /**
+ * Removes `key` and its value from the hash.
+ *
+ * @private
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function hashDelete(hash, key) {
+ return hashHas(hash, key) && delete hash[key];
+ }
+
+ return hashDelete;
+});
diff --git a/internal/hashGet.js b/internal/hashGet.js
new file mode 100644
index 000000000..06058ee91
--- /dev/null
+++ b/internal/hashGet.js
@@ -0,0 +1,32 @@
+define(['./nativeCreate'], function(nativeCreate) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /**
+ * Gets the hash value for `key`.
+ *
+ * @private
+ * @param {Object} hash The hash to query.
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function hashGet(hash, key) {
+ if (nativeCreate) {
+ var result = hash[key];
+ return result === HASH_UNDEFINED ? undefined : result;
+ }
+ return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
+ }
+
+ return hashGet;
+});
diff --git a/internal/hashHas.js b/internal/hashHas.js
new file mode 100644
index 000000000..4495fec1b
--- /dev/null
+++ b/internal/hashHas.js
@@ -0,0 +1,25 @@
+define(['./nativeCreate'], function(nativeCreate) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /**
+ * Checks if a hash value for `key` exists.
+ *
+ * @private
+ * @param {Object} hash The hash to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function hashHas(hash, key) {
+ return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
+ }
+
+ return hashHas;
+});
diff --git a/internal/hashSet.js b/internal/hashSet.js
new file mode 100644
index 000000000..3e847cb47
--- /dev/null
+++ b/internal/hashSet.js
@@ -0,0 +1,22 @@
+define(['./nativeCreate'], function(nativeCreate) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+ /**
+ * Sets the hash `key` to `value`.
+ *
+ * @private
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ */
+ function hashSet(hash, key, value) {
+ hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+ }
+
+ return hashSet;
+});
diff --git a/internal/indexKeys.js b/internal/indexKeys.js
new file mode 100644
index 000000000..0e0271e7d
--- /dev/null
+++ b/internal/indexKeys.js
@@ -0,0 +1,22 @@
+define(['./baseTimes', '../isArguments', '../isArray', '../isLength', '../isString'], function(baseTimes, isArguments, isArray, isLength, isString) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Creates an array of index keys for `object` values of arrays,
+ * `arguments` objects, and strings, otherwise `null` is returned.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array|null} Returns index keys, else `null`.
+ */
+ function indexKeys(object) {
+ var length = object ? object.length : undefined;
+ return (isLength(length) && (isArray(object) || isString(object) || isArguments(object)))
+ ? baseTimes(length, String)
+ : null;
+ }
+
+ return indexKeys;
+});
diff --git a/internal/initCloneArray.js b/internal/initCloneArray.js
index b01bce6f2..055bda797 100644
--- a/internal/initCloneArray.js
+++ b/internal/initCloneArray.js
@@ -1,6 +1,6 @@
define([], function() {
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
@@ -15,9 +15,9 @@ define([], function() {
*/
function initCloneArray(array) {
var length = array.length,
- result = new array.constructor(length);
+ result = array.constructor(length);
- // Add array properties assigned by `RegExp#exec`.
+ // Add properties assigned by `RegExp#exec`.
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
result.index = array.index;
result.input = array.input;
diff --git a/internal/initCloneByTag.js b/internal/initCloneByTag.js
index 67d95409e..7f5b4ad73 100644
--- a/internal/initCloneByTag.js
+++ b/internal/initCloneByTag.js
@@ -1,11 +1,14 @@
-define(['./bufferClone'], function(bufferClone) {
+define(['./cloneBuffer', './cloneMap', './cloneRegExp', './cloneSet', './cloneSymbol', './cloneTypedArray'], function(cloneBuffer, cloneMap, cloneRegExp, cloneSet, cloneSymbol, cloneTypedArray) {
/** `Object#toString` result references. */
var boolTag = '[object Boolean]',
dateTag = '[object Date]',
+ mapTag = '[object Map]',
numberTag = '[object Number]',
regexpTag = '[object RegExp]',
- stringTag = '[object String]';
+ setTag = '[object Set]',
+ stringTag = '[object String]',
+ symbolTag = '[object Symbol]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
@@ -18,9 +21,6 @@ define(['./bufferClone'], function(bufferClone) {
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
- /** Used to match `RegExp` flags from their coerced string values. */
- var reFlags = /\w*$/;
-
/**
* Initializes an object clone based on its `toStringTag`.
*
@@ -37,7 +37,7 @@ define(['./bufferClone'], function(bufferClone) {
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
- return bufferClone(object);
+ return cloneBuffer(object);
case boolTag:
case dateTag:
@@ -46,18 +46,24 @@ define(['./bufferClone'], function(bufferClone) {
case float32Tag: case float64Tag:
case int8Tag: case int16Tag: case int32Tag:
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
- var buffer = object.buffer;
- return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
+ return cloneTypedArray(object, isDeep);
+
+ case mapTag:
+ return cloneMap(object);
case numberTag:
case stringTag:
return new Ctor(object);
case regexpTag:
- var result = new Ctor(object.source, reFlags.exec(object));
- result.lastIndex = object.lastIndex;
+ return cloneRegExp(object);
+
+ case setTag:
+ return cloneSet(object);
+
+ case symbolTag:
+ return cloneSymbol(object);
}
- return result;
}
return initCloneByTag;
diff --git a/internal/initCloneObject.js b/internal/initCloneObject.js
index a0cdd6104..439e99998 100644
--- a/internal/initCloneObject.js
+++ b/internal/initCloneObject.js
@@ -1,4 +1,7 @@
-define([], function() {
+define(['./baseCreate', '../isFunction'], function(baseCreate, isFunction) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* Initializes an object clone.
@@ -9,10 +12,7 @@ define([], function() {
*/
function initCloneObject(object) {
var Ctor = object.constructor;
- if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
- Ctor = Object;
- }
- return new Ctor;
+ return baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
}
return initCloneObject;
diff --git a/internal/invokePath.js b/internal/invokePath.js
deleted file mode 100644
index f89e5a7ce..000000000
--- a/internal/invokePath.js
+++ /dev/null
@@ -1,26 +0,0 @@
-define(['./baseGet', './baseSlice', './isKey', '../array/last', './toPath'], function(baseGet, baseSlice, isKey, last, toPath) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Invokes the method at `path` on `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} path The path of the method to invoke.
- * @param {Array} args The arguments to invoke the method with.
- * @returns {*} Returns the result of the invoked method.
- */
- function invokePath(object, path, args) {
- if (object != null && !isKey(path, object)) {
- path = toPath(path);
- object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
- path = last(path);
- }
- var func = object == null ? object : object[path];
- return func == null ? undefined : func.apply(object, args);
- }
-
- return invokePath;
-});
diff --git a/internal/isArrayLike.js b/internal/isArrayLike.js
deleted file mode 100644
index 6d79bd308..000000000
--- a/internal/isArrayLike.js
+++ /dev/null
@@ -1,15 +0,0 @@
-define(['./getLength', './isLength'], function(getLength, isLength) {
-
- /**
- * Checks if `value` is array-like.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
- */
- function isArrayLike(value) {
- return value != null && isLength(getLength(value));
- }
-
- return isArrayLike;
-});
diff --git a/internal/isHostObject.js b/internal/isHostObject.js
new file mode 100644
index 000000000..dbc6c704e
--- /dev/null
+++ b/internal/isHostObject.js
@@ -0,0 +1,23 @@
+define([], function() {
+
+ /**
+ * Checks if `value` is a host object in IE < 9.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+ */
+ function isHostObject(value) {
+ // Many host objects are `Object` objects that can coerce to strings
+ // despite having improperly defined `toString` methods.
+ var result = false;
+ if (value != null && typeof value.toString != 'function') {
+ try {
+ result = !!(value + '');
+ } catch (e) {}
+ }
+ return result;
+ }
+
+ return isHostObject;
+});
diff --git a/internal/isIndex.js b/internal/isIndex.js
index 1eb122013..7644bb037 100644
--- a/internal/isIndex.js
+++ b/internal/isIndex.js
@@ -1,14 +1,11 @@
define([], function() {
- /** Used to detect unsigned integer values. */
- var reIsUint = /^\d+$/;
-
- /**
- * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
- * of an array-like value.
- */
+ /** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;
+ /** Used to detect unsigned integer values. */
+ var reIsUint = /^(?:0|[1-9]\d*)$/;
+
/**
* Checks if `value` is a valid array-like index.
*
diff --git a/internal/isIterateeCall.js b/internal/isIterateeCall.js
index efbc40f6e..5f04470b2 100644
--- a/internal/isIterateeCall.js
+++ b/internal/isIterateeCall.js
@@ -1,4 +1,4 @@
-define(['./isArrayLike', './isIndex', '../lang/isObject'], function(isArrayLike, isIndex, isObject) {
+define(['../eq', '../isArrayLike', './isIndex', '../isObject'], function(eq, isArrayLike, isIndex, isObject) {
/**
* Checks if the provided arguments are from an iteratee call.
@@ -17,8 +17,7 @@ define(['./isArrayLike', './isIndex', '../lang/isObject'], function(isArrayLike,
if (type == 'number'
? (isArrayLike(object) && isIndex(index, object.length))
: (type == 'string' && index in object)) {
- var other = object[index];
- return value === value ? (value === other) : (other !== other);
+ return eq(object[index], value);
}
return false;
}
diff --git a/internal/isKey.js b/internal/isKey.js
index 5fe2add10..a1ff7407a 100644
--- a/internal/isKey.js
+++ b/internal/isKey.js
@@ -1,7 +1,7 @@
-define(['../lang/isArray', './toObject'], function(isArray, toObject) {
+define(['../isArray'], function(isArray) {
/** Used to match property names within property paths. */
- var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
+ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
reIsPlainProp = /^\w*$/;
/**
@@ -13,15 +13,12 @@ define(['../lang/isArray', './toObject'], function(isArray, toObject) {
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
*/
function isKey(value, object) {
- var type = typeof value;
- if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
+ if (typeof value == 'number') {
return true;
}
- if (isArray(value)) {
- return false;
- }
- var result = !reIsDeepProp.test(value);
- return result || (object != null && value in toObject(object));
+ return !isArray(value) &&
+ (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+ (object != null && value in Object(object)));
}
return isKey;
diff --git a/internal/isKeyable.js b/internal/isKeyable.js
new file mode 100644
index 000000000..f7a29ae90
--- /dev/null
+++ b/internal/isKeyable.js
@@ -0,0 +1,17 @@
+define([], function() {
+
+ /**
+ * Checks if `value` is suitable for use as unique object key.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+ */
+ function isKeyable(value) {
+ var type = typeof value;
+ return type == 'number' || type == 'boolean' ||
+ (type == 'string' && value !== '__proto__') || value == null;
+ }
+
+ return isKeyable;
+});
diff --git a/internal/isLaziable.js b/internal/isLaziable.js
index b0c6b10cf..72ab23b00 100644
--- a/internal/isLaziable.js
+++ b/internal/isLaziable.js
@@ -1,4 +1,4 @@
-define(['./LazyWrapper', './getData', './getFuncName', '../chain/lodash'], function(LazyWrapper, getData, getFuncName, lodash) {
+define(['./LazyWrapper', './getData', './getFuncName', '../wrapperLodash'], function(LazyWrapper, getData, getFuncName, lodash) {
/**
* Checks if `func` has a lazy counterpart.
diff --git a/internal/isLength.js b/internal/isLength.js
deleted file mode 100644
index 7a8762c4f..000000000
--- a/internal/isLength.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define([], function() {
-
- /**
- * 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;
-
- /**
- * Checks if `value` is a valid array-like length.
- *
- * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
- */
- function isLength(value) {
- return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
- }
-
- return isLength;
-});
diff --git a/internal/isObjectLike.js b/internal/isObjectLike.js
deleted file mode 100644
index 42fc5561a..000000000
--- a/internal/isObjectLike.js
+++ /dev/null
@@ -1,15 +0,0 @@
-define([], function() {
-
- /**
- * Checks if `value` is object-like.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
- */
- function isObjectLike(value) {
- return !!value && typeof value == 'object';
- }
-
- return isObjectLike;
-});
diff --git a/internal/isPrototype.js b/internal/isPrototype.js
new file mode 100644
index 000000000..d57affdb9
--- /dev/null
+++ b/internal/isPrototype.js
@@ -0,0 +1,21 @@
+define([], function() {
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /**
+ * Checks if `value` is likely a prototype object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+ */
+ function isPrototype(value) {
+ var Ctor = value && value.constructor,
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+
+ return value === proto;
+ }
+
+ return isPrototype;
+});
diff --git a/internal/isSpace.js b/internal/isSpace.js
deleted file mode 100644
index 458b83467..000000000
--- a/internal/isSpace.js
+++ /dev/null
@@ -1,17 +0,0 @@
-define([], function() {
-
- /**
- * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a
- * character code is whitespace.
- *
- * @private
- * @param {number} charCode The character code to inspect.
- * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`.
- */
- function isSpace(charCode) {
- return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 ||
- (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279)));
- }
-
- return isSpace;
-});
diff --git a/internal/isStrictComparable.js b/internal/isStrictComparable.js
index 954911098..58444325d 100644
--- a/internal/isStrictComparable.js
+++ b/internal/isStrictComparable.js
@@ -1,4 +1,4 @@
-define(['../lang/isObject'], function(isObject) {
+define(['../isObject'], function(isObject) {
/**
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
diff --git a/internal/iteratorToArray.js b/internal/iteratorToArray.js
new file mode 100644
index 000000000..62bf8a369
--- /dev/null
+++ b/internal/iteratorToArray.js
@@ -0,0 +1,21 @@
+define([], function() {
+
+ /**
+ * Converts `iterator` to an array.
+ *
+ * @private
+ * @param {Object} iterator The iterator to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function iteratorToArray(iterator) {
+ var data,
+ result = [];
+
+ while (!(data = iterator.next()).done) {
+ result.push(data.value);
+ }
+ return result;
+ }
+
+ return iteratorToArray;
+});
diff --git a/internal/lazyClone.js b/internal/lazyClone.js
index 0179895ea..216799545 100644
--- a/internal/lazyClone.js
+++ b/internal/lazyClone.js
@@ -1,4 +1,4 @@
-define(['./LazyWrapper', './arrayCopy'], function(LazyWrapper, arrayCopy) {
+define(['./LazyWrapper', './copyArray'], function(LazyWrapper, copyArray) {
/**
* Creates a clone of the lazy wrapper object.
@@ -10,12 +10,12 @@ define(['./LazyWrapper', './arrayCopy'], function(LazyWrapper, arrayCopy) {
*/
function lazyClone() {
var result = new LazyWrapper(this.__wrapped__);
- result.__actions__ = arrayCopy(this.__actions__);
+ result.__actions__ = copyArray(this.__actions__);
result.__dir__ = this.__dir__;
result.__filtered__ = this.__filtered__;
- result.__iteratees__ = arrayCopy(this.__iteratees__);
+ result.__iteratees__ = copyArray(this.__iteratees__);
result.__takeCount__ = this.__takeCount__;
- result.__views__ = arrayCopy(this.__views__);
+ result.__views__ = copyArray(this.__views__);
return result;
}
diff --git a/internal/lazyValue.js b/internal/lazyValue.js
index 3b37b4011..14637269c 100644
--- a/internal/lazyValue.js
+++ b/internal/lazyValue.js
@@ -1,4 +1,4 @@
-define(['./baseWrapperValue', './getView', '../lang/isArray'], function(baseWrapperValue, getView, isArray) {
+define(['./baseWrapperValue', './getView', '../isArray'], function(baseWrapperValue, getView, isArray) {
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
@@ -7,7 +7,7 @@ define(['./baseWrapperValue', './getView', '../lang/isArray'], function(baseWrap
var LAZY_FILTER_FLAG = 1,
LAZY_MAP_FLAG = 2;
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;
/**
diff --git a/internal/mapClear.js b/internal/mapClear.js
new file mode 100644
index 000000000..bb7b60336
--- /dev/null
+++ b/internal/mapClear.js
@@ -0,0 +1,15 @@
+define(['./Hash', './Map'], function(Hash, Map) {
+
+ /**
+ * Removes all key-value entries from the map.
+ *
+ * @private
+ * @name clear
+ * @memberOf MapCache
+ */
+ function mapClear() {
+ this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash };
+ }
+
+ return mapClear;
+});
diff --git a/internal/mapDelete.js b/internal/mapDelete.js
index ce21061d2..fc0a57a5f 100644
--- a/internal/mapDelete.js
+++ b/internal/mapDelete.js
@@ -1,16 +1,20 @@
-define([], function() {
+define(['./Map', './assocDelete', './hashDelete', './isKeyable'], function(Map, assocDelete, hashDelete, isKeyable) {
/**
- * Removes `key` and its value from the cache.
+ * Removes `key` and its value from the map.
*
* @private
* @name delete
- * @memberOf _.memoize.Cache
+ * @memberOf MapCache
* @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function mapDelete(key) {
- return this.has(key) && delete this.__data__[key];
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
+ }
+ return Map ? data.map['delete'](key) : assocDelete(data.map, key);
}
return mapDelete;
diff --git a/internal/mapGet.js b/internal/mapGet.js
index 33535469e..155efbba0 100644
--- a/internal/mapGet.js
+++ b/internal/mapGet.js
@@ -1,19 +1,20 @@
-define([], function() {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
+define(['./Map', './assocGet', './hashGet', './isKeyable'], function(Map, assocGet, hashGet, isKeyable) {
/**
- * Gets the cached value for `key`.
+ * Gets the map value for `key`.
*
* @private
* @name get
- * @memberOf _.memoize.Cache
+ * @memberOf MapCache
* @param {string} key The key of the value to get.
- * @returns {*} Returns the cached value.
+ * @returns {*} Returns the entry value.
*/
function mapGet(key) {
- return key == '__proto__' ? undefined : this.__data__[key];
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashGet(typeof key == 'string' ? data.string : data.hash, key);
+ }
+ return Map ? data.map.get(key) : assocGet(data.map, key);
}
return mapGet;
diff --git a/internal/mapHas.js b/internal/mapHas.js
index d3eccbb05..f8bd0244c 100644
--- a/internal/mapHas.js
+++ b/internal/mapHas.js
@@ -1,22 +1,20 @@
-define([], function() {
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty = objectProto.hasOwnProperty;
+define(['./Map', './assocHas', './hashHas', './isKeyable'], function(Map, assocHas, hashHas, isKeyable) {
/**
- * Checks if a cached value for `key` exists.
+ * Checks if a map value for `key` exists.
*
* @private
* @name has
- * @memberOf _.memoize.Cache
+ * @memberOf MapCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function mapHas(key) {
- return key != '__proto__' && hasOwnProperty.call(this.__data__, key);
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashHas(typeof key == 'string' ? data.string : data.hash, key);
+ }
+ return Map ? data.map.has(key) : assocHas(data.map, key);
}
return mapHas;
diff --git a/internal/mapSet.js b/internal/mapSet.js
index 7c1ec34b9..26615a46e 100644
--- a/internal/mapSet.js
+++ b/internal/mapSet.js
@@ -1,18 +1,23 @@
-define([], function() {
+define(['./Map', './assocSet', './hashSet', './isKeyable'], function(Map, assocSet, hashSet, isKeyable) {
/**
- * Sets `value` to `key` of the cache.
+ * Sets the map `key` to `value`.
*
* @private
* @name set
- * @memberOf _.memoize.Cache
- * @param {string} key The key of the value to cache.
- * @param {*} value The value to cache.
- * @returns {Object} Returns the cache object.
+ * @memberOf MapCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the map cache object.
*/
function mapSet(key, value) {
- if (key != '__proto__') {
- this.__data__[key] = value;
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
+ } else if (Map) {
+ data.map.set(key, value);
+ } else {
+ assocSet(data.map, key, value);
}
return this;
}
diff --git a/internal/mapToArray.js b/internal/mapToArray.js
new file mode 100644
index 000000000..d674b7c30
--- /dev/null
+++ b/internal/mapToArray.js
@@ -0,0 +1,21 @@
+define([], function() {
+
+ /**
+ * Converts `map` to an array.
+ *
+ * @private
+ * @param {Object} map The map to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function mapToArray(map) {
+ var index = -1,
+ result = Array(map.size);
+
+ map.forEach(function(value, key) {
+ result[++index] = [key, value];
+ });
+ return result;
+ }
+
+ return mapToArray;
+});
diff --git a/internal/mergeData.js b/internal/mergeData.js
index 2c0a70857..a746b2a83 100644
--- a/internal/mergeData.js
+++ b/internal/mergeData.js
@@ -1,7 +1,8 @@
-define(['./arrayCopy', './composeArgs', './composeArgsRight', './replaceHolders'], function(arrayCopy, composeArgs, composeArgsRight, replaceHolders) {
+define(['./composeArgs', './composeArgsRight', './copyArray', './replaceHolders'], function(composeArgs, composeArgsRight, copyArray, replaceHolders) {
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
+ BIND_KEY_FLAG = 2,
CURRY_BOUND_FLAG = 4,
CURRY_FLAG = 8,
ARY_FLAG = 128,
@@ -10,18 +11,18 @@ define(['./arrayCopy', './composeArgs', './composeArgsRight', './replaceHolders'
/** Used as the internal argument placeholder. */
var PLACEHOLDER = '__lodash_placeholder__';
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;
/**
* Merges the function metadata of `source` into `data`.
*
- * Merging metadata reduces the number of wrappers required to invoke a function.
+ * Merging metadata reduces the number of wrappers used to invoke a function.
* This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
* may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
- * augment function arguments, making the order in which they are executed important,
+ * modify function arguments, making the order in which they are executed important,
* preventing the merging of metadata. However, we make an exception for a safe
- * common case where curried functions have `_.ary` and or `_.rearg` applied.
+ * combined case where curried functions have `_.ary` and or `_.rearg` applied.
*
* @private
* @param {Array} data The destination metadata.
@@ -32,12 +33,12 @@ define(['./arrayCopy', './composeArgs', './composeArgsRight', './replaceHolders'
var bitmask = data[1],
srcBitmask = source[1],
newBitmask = bitmask | srcBitmask,
- isCommon = newBitmask < ARY_FLAG;
+ isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
var isCombo =
- (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
- (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
- (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
+ (srcBitmask == ARY_FLAG && (bitmask == CURRY_FLAG)) ||
+ (srcBitmask == ARY_FLAG && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
+ (srcBitmask == (ARY_FLAG | REARG_FLAG) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
// Exit early if metadata can't be merged.
if (!(isCommon || isCombo)) {
@@ -53,20 +54,20 @@ define(['./arrayCopy', './composeArgs', './composeArgsRight', './replaceHolders'
var value = source[3];
if (value) {
var partials = data[3];
- data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
- data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
+ data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
+ data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
}
// Compose partial right arguments.
value = source[5];
if (value) {
partials = data[5];
- data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
- data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
+ data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
+ data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
}
// Use source `argPos` if available.
value = source[7];
if (value) {
- data[7] = arrayCopy(value);
+ data[7] = copyArray(value);
}
// Use source `ary` if it's smaller.
if (srcBitmask & ARY_FLAG) {
diff --git a/internal/mergeDefaults.js b/internal/mergeDefaults.js
index 77c9ba434..c63b6d0ab 100644
--- a/internal/mergeDefaults.js
+++ b/internal/mergeDefaults.js
@@ -1,4 +1,4 @@
-define(['../object/merge'], function(merge) {
+define(['./baseClone', './baseMerge', '../isObject'], function(baseClone, baseMerge, isObject) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -7,12 +7,20 @@ define(['../object/merge'], function(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.
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to merge.
+ * @param {Object} object The parent object of `objValue`.
+ * @param {Object} source The parent object of `srcValue`.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
+ * @returns {*} Returns the value to assign.
*/
- function mergeDefaults(objectValue, sourceValue) {
- return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);
+ function mergeDefaults(objValue, srcValue, key, object, source, stack) {
+ if (isObject(objValue) && isObject(srcValue)) {
+ stack.set(srcValue, objValue);
+ baseMerge(objValue, srcValue, mergeDefaults, stack);
+ }
+ return objValue === undefined ? baseClone(srcValue) : objValue;
}
return mergeDefaults;
diff --git a/internal/metaMap.js b/internal/metaMap.js
index 60dfa228e..248947119 100644
--- a/internal/metaMap.js
+++ b/internal/metaMap.js
@@ -1,7 +1,4 @@
-define(['./getNative', './root'], function(getNative, root) {
-
- /** Native method references. */
- var WeakMap = getNative(root, 'WeakMap');
+define(['./WeakMap'], function(WeakMap) {
/** Used to store function metadata. */
var metaMap = WeakMap && new WeakMap;
diff --git a/internal/nativeCreate.js b/internal/nativeCreate.js
new file mode 100644
index 000000000..d2a0f8d9b
--- /dev/null
+++ b/internal/nativeCreate.js
@@ -0,0 +1,7 @@
+define(['./getNative'], function(getNative) {
+
+ /* Built-in method references that are verified to be native. */
+ var nativeCreate = getNative(Object, 'create');
+
+ return nativeCreate;
+});
diff --git a/internal/parent.js b/internal/parent.js
new file mode 100644
index 000000000..742c5c801
--- /dev/null
+++ b/internal/parent.js
@@ -0,0 +1,16 @@
+define(['./baseSlice', '../get'], function(baseSlice, get) {
+
+ /**
+ * Gets the parent value at `path` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} path The path to get the parent value of.
+ * @returns {*} Returns the parent value.
+ */
+ function parent(object, path) {
+ return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
+ }
+
+ return parent;
+});
diff --git a/internal/pickByArray.js b/internal/pickByArray.js
deleted file mode 100644
index b9375cf55..000000000
--- a/internal/pickByArray.js
+++ /dev/null
@@ -1,29 +0,0 @@
-define(['./toObject'], function(toObject) {
-
- /**
- * A specialized version of `_.pick` which picks `object` properties specified
- * by `props`.
- *
- * @private
- * @param {Object} object The source object.
- * @param {string[]} props The property names to pick.
- * @returns {Object} Returns the new object.
- */
- function pickByArray(object, props) {
- object = toObject(object);
-
- var index = -1,
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index];
- if (key in object) {
- result[key] = object[key];
- }
- }
- return result;
- }
-
- return pickByArray;
-});
diff --git a/internal/pickByCallback.js b/internal/pickByCallback.js
deleted file mode 100644
index 4bd15b35f..000000000
--- a/internal/pickByCallback.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define(['./baseForIn'], function(baseForIn) {
-
- /**
- * A specialized version of `_.pick` which picks `object` properties `predicate`
- * returns truthy for.
- *
- * @private
- * @param {Object} object The source object.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {Object} Returns the new object.
- */
- function pickByCallback(object, predicate) {
- var result = {};
- baseForIn(object, function(value, key, object) {
- if (predicate(value, key, object)) {
- result[key] = value;
- }
- });
- return result;
- }
-
- return pickByCallback;
-});
diff --git a/internal/reorder.js b/internal/reorder.js
index 3c762492b..befc69ed3 100644
--- a/internal/reorder.js
+++ b/internal/reorder.js
@@ -1,9 +1,9 @@
-define(['./arrayCopy', './isIndex'], function(arrayCopy, isIndex) {
+define(['./copyArray', './isIndex'], function(copyArray, isIndex) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;
/**
@@ -19,7 +19,7 @@ define(['./arrayCopy', './isIndex'], function(arrayCopy, isIndex) {
function reorder(array, indexes) {
var arrLength = array.length,
length = nativeMin(indexes.length, arrLength),
- oldArray = arrayCopy(array);
+ oldArray = copyArray(array);
while (length--) {
var index = indexes[length];
diff --git a/internal/root.js b/internal/root.js
index 10a426173..90fca241e 100644
--- a/internal/root.js
+++ b/internal/root.js
@@ -1,4 +1,4 @@
-define([], function() {
+define(['./checkGlobal'], function(checkGlobal) {
/** Used to determine if values are of the language type `Object`. */
var objectTypes = {
@@ -7,19 +7,22 @@ define([], function() {
};
/** Detect free variable `exports`. */
- var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
+ var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
/** Detect free variable `module`. */
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
+ var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
/** Detect free variable `global` from Node.js. */
- var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;
+ var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
/** Detect free variable `self`. */
- var freeSelf = objectTypes[typeof self] && self && self.Object && self;
+ var freeSelf = checkGlobal(objectTypes[typeof self] && self);
/** Detect free variable `window`. */
- var freeWindow = objectTypes[typeof window] && window && window.Object && window;
+ var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+ /** Detect `this` as the global object. */
+ var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
/**
* Used as a reference to the global object.
@@ -27,7 +30,7 @@ define([], function() {
* The `this` value is used if it's the global object to avoid Greasemonkey's
* restricted `window` object, otherwise the `window` object is used.
*/
- var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
+ var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
return root;
});
diff --git a/internal/setData.js b/internal/setData.js
index baaf7b09c..28ef3e55a 100644
--- a/internal/setData.js
+++ b/internal/setData.js
@@ -1,6 +1,6 @@
-define(['./baseSetData', '../date/now'], function(baseSetData, now) {
+define(['./baseSetData', '../now'], function(baseSetData, now) {
- /** Used to detect when a function becomes hot. */
+ /** Used to detect hot functions by number of calls within a span of milliseconds. */
var HOT_COUNT = 150,
HOT_SPAN = 16;
diff --git a/internal/setToArray.js b/internal/setToArray.js
new file mode 100644
index 000000000..633f32e0a
--- /dev/null
+++ b/internal/setToArray.js
@@ -0,0 +1,21 @@
+define([], function() {
+
+ /**
+ * Converts `set` to an array.
+ *
+ * @private
+ * @param {Object} set The set to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function setToArray(set) {
+ var index = -1,
+ result = Array(set.size);
+
+ set.forEach(function(value) {
+ result[++index] = value;
+ });
+ return result;
+ }
+
+ return setToArray;
+});
diff --git a/internal/shimKeys.js b/internal/shimKeys.js
deleted file mode 100644
index 4a9d432f6..000000000
--- a/internal/shimKeys.js
+++ /dev/null
@@ -1,38 +0,0 @@
-define(['../lang/isArguments', '../lang/isArray', './isIndex', './isLength', '../object/keysIn'], function(isArguments, isArray, isIndex, isLength, keysIn) {
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty = objectProto.hasOwnProperty;
-
- /**
- * A fallback implementation of `Object.keys` which creates an array of the
- * own enumerable property names of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- */
- function shimKeys(object) {
- var props = keysIn(object),
- propsLength = props.length,
- length = propsLength && object.length;
-
- var allowIndexes = !!length && isLength(length) &&
- (isArray(object) || isArguments(object));
-
- var index = -1,
- result = [];
-
- while (++index < propsLength) {
- var key = props[index];
- if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
- result.push(key);
- }
- }
- return result;
- }
-
- return shimKeys;
-});
diff --git a/internal/sortedUniq.js b/internal/sortedUniq.js
deleted file mode 100644
index 9c4608080..000000000
--- a/internal/sortedUniq.js
+++ /dev/null
@@ -1,32 +0,0 @@
-define([], function() {
-
- /**
- * An implementation of `_.uniq` optimized for sorted arrays without support
- * for callback shorthands and `this` binding.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {Function} [iteratee] The function invoked per iteration.
- * @returns {Array} Returns the new duplicate free array.
- */
- function sortedUniq(array, iteratee) {
- var seen,
- index = -1,
- length = array.length,
- resIndex = -1,
- result = [];
-
- while (++index < length) {
- var value = array[index],
- computed = iteratee ? iteratee(value, index, array) : value;
-
- if (!index || seen !== computed) {
- seen = computed;
- result[++resIndex] = value;
- }
- }
- return result;
- }
-
- return sortedUniq;
-});
diff --git a/internal/stackClear.js b/internal/stackClear.js
new file mode 100644
index 000000000..7b7b12066
--- /dev/null
+++ b/internal/stackClear.js
@@ -0,0 +1,15 @@
+define([], function() {
+
+ /**
+ * Removes all key-value entries from the stack.
+ *
+ * @private
+ * @name clear
+ * @memberOf Stack
+ */
+ function stackClear() {
+ this.__data__ = { 'array': [], 'map': null };
+ }
+
+ return stackClear;
+});
diff --git a/internal/stackDelete.js b/internal/stackDelete.js
new file mode 100644
index 000000000..96a206f88
--- /dev/null
+++ b/internal/stackDelete.js
@@ -0,0 +1,20 @@
+define(['./assocDelete'], function(assocDelete) {
+
+ /**
+ * Removes `key` and its value from the stack.
+ *
+ * @private
+ * @name delete
+ * @memberOf Stack
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function stackDelete(key) {
+ var data = this.__data__,
+ array = data.array;
+
+ return array ? assocDelete(array, key) : data.map['delete'](key);
+ }
+
+ return stackDelete;
+});
diff --git a/internal/stackGet.js b/internal/stackGet.js
new file mode 100644
index 000000000..0cee47cfa
--- /dev/null
+++ b/internal/stackGet.js
@@ -0,0 +1,20 @@
+define(['./assocGet'], function(assocGet) {
+
+ /**
+ * Gets the stack value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Stack
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function stackGet(key) {
+ var data = this.__data__,
+ array = data.array;
+
+ return array ? assocGet(array, key) : data.map.get(key);
+ }
+
+ return stackGet;
+});
diff --git a/internal/stackHas.js b/internal/stackHas.js
new file mode 100644
index 000000000..c2d50af7c
--- /dev/null
+++ b/internal/stackHas.js
@@ -0,0 +1,20 @@
+define(['./assocHas'], function(assocHas) {
+
+ /**
+ * Checks if a stack value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Stack
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function stackHas(key) {
+ var data = this.__data__,
+ array = data.array;
+
+ return array ? assocHas(array, key) : data.map.has(key);
+ }
+
+ return stackHas;
+});
diff --git a/internal/stackSet.js b/internal/stackSet.js
new file mode 100644
index 000000000..1845a9c8f
--- /dev/null
+++ b/internal/stackSet.js
@@ -0,0 +1,36 @@
+define(['./MapCache', './assocSet'], function(MapCache, assocSet) {
+
+ /** Used as the size to enable large array optimizations. */
+ var LARGE_ARRAY_SIZE = 200;
+
+ /**
+ * Sets the stack `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Stack
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the stack cache object.
+ */
+ function stackSet(key, value) {
+ var data = this.__data__,
+ array = data.array;
+
+ if (array) {
+ if (array.length < (LARGE_ARRAY_SIZE - 1)) {
+ assocSet(array, key, value);
+ } else {
+ data.array = null;
+ data.map = new MapCache(array);
+ }
+ }
+ var map = data.map;
+ if (map) {
+ map.set(key, value);
+ }
+ return this;
+ }
+
+ return stackSet;
+});
diff --git a/internal/stringSize.js b/internal/stringSize.js
new file mode 100644
index 000000000..8550a82eb
--- /dev/null
+++ b/internal/stringSize.js
@@ -0,0 +1,48 @@
+define([], function() {
+
+ /** Used to compose unicode character classes. */
+ var rsAstralRange = '\\ud800-\\udfff',
+ rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsVarRange = '\\ufe0e\\ufe0f';
+
+ /** Used to compose unicode capture groups. */
+ var rsAstral = '[' + rsAstralRange + ']',
+ rsCombo = '[' + rsComboRange + ']',
+ rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
+ rsNonAstral = '[^' + rsAstralRange + ']',
+ rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+ rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+ rsZWJ = '\\u200d';
+
+ /** Used to compose unicode regexes. */
+ var reOptMod = rsModifier + '?',
+ rsOptVar = '[' + rsVarRange + ']?',
+ rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+ rsSeq = rsOptVar + reOptMod + rsOptJoin,
+ rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
+
+ /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
+ var reComplexSymbol = RegExp(rsSymbol + rsSeq, 'g');
+
+ /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+ var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+
+ /**
+ * Gets the number of symbols in `string`.
+ *
+ * @param {string} string The string to inspect.
+ * @returns {number} Returns the string size.
+ */
+ function stringSize(string) {
+ if (!(string && reHasComplexSymbol.test(string))) {
+ return string.length;
+ }
+ var result = reComplexSymbol.lastIndex = 0;
+ while (reComplexSymbol.test(string)) {
+ result++;
+ }
+ return result;
+ }
+
+ return stringSize;
+});
diff --git a/internal/stringToArray.js b/internal/stringToArray.js
new file mode 100644
index 000000000..a34afbf30
--- /dev/null
+++ b/internal/stringToArray.js
@@ -0,0 +1,39 @@
+define([], function() {
+
+ /** Used to compose unicode character classes. */
+ var rsAstralRange = '\\ud800-\\udfff',
+ rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsVarRange = '\\ufe0e\\ufe0f';
+
+ /** Used to compose unicode capture groups. */
+ var rsAstral = '[' + rsAstralRange + ']',
+ rsCombo = '[' + rsComboRange + ']',
+ rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
+ rsNonAstral = '[^' + rsAstralRange + ']',
+ rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+ rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+ rsZWJ = '\\u200d';
+
+ /** Used to compose unicode regexes. */
+ var reOptMod = rsModifier + '?',
+ rsOptVar = '[' + rsVarRange + ']?',
+ rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+ rsSeq = rsOptVar + reOptMod + rsOptJoin,
+ rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
+
+ /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
+ var reComplexSymbol = RegExp(rsSymbol + rsSeq, 'g');
+
+ /**
+ * Converts `string` to an array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function stringToArray(string) {
+ return string.match(reComplexSymbol);
+ }
+
+ return stringToArray;
+});
diff --git a/internal/toPath.js b/internal/stringToPath.js
similarity index 52%
rename from internal/toPath.js
rename to internal/stringToPath.js
index 3bafab1fd..720d03615 100644
--- a/internal/toPath.js
+++ b/internal/stringToPath.js
@@ -1,28 +1,25 @@
-define(['./baseToString', '../lang/isArray'], function(baseToString, isArray) {
+define(['../toString'], function(toString) {
/** Used to match property names within property paths. */
- var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
+ var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;
/**
- * Converts `value` to property path array if it's not one.
+ * Converts `string` to a property path array.
*
* @private
- * @param {*} value The value to process.
+ * @param {string} string The string to convert.
* @returns {Array} Returns the property path array.
*/
- function toPath(value) {
- if (isArray(value)) {
- return value;
- }
+ function stringToPath(string) {
var result = [];
- baseToString(value).replace(rePropName, function(match, number, quote, string) {
+ toString(string).replace(rePropName, function(match, number, quote, string) {
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
});
return result;
}
- return toPath;
+ return stringToPath;
});
diff --git a/internal/toArrayLikeObject.js b/internal/toArrayLikeObject.js
new file mode 100644
index 000000000..77ae155d2
--- /dev/null
+++ b/internal/toArrayLikeObject.js
@@ -0,0 +1,15 @@
+define(['../isArrayLikeObject'], function(isArrayLikeObject) {
+
+ /**
+ * Converts `value` to an array-like object if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Array} Returns the array-like object.
+ */
+ function toArrayLikeObject(value) {
+ return isArrayLikeObject(value) ? value : [];
+ }
+
+ return toArrayLikeObject;
+});
diff --git a/internal/toFunction.js b/internal/toFunction.js
new file mode 100644
index 000000000..c2e8140c6
--- /dev/null
+++ b/internal/toFunction.js
@@ -0,0 +1,15 @@
+define(['../identity'], function(identity) {
+
+ /**
+ * Converts `value` to a function if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Function} Returns the function.
+ */
+ function toFunction(value) {
+ return typeof value == 'function' ? value : identity;
+ }
+
+ return toFunction;
+});
diff --git a/internal/toIterable.js b/internal/toIterable.js
deleted file mode 100644
index c8f9a562c..000000000
--- a/internal/toIterable.js
+++ /dev/null
@@ -1,21 +0,0 @@
-define(['./isArrayLike', '../lang/isObject', '../object/values'], function(isArrayLike, isObject, values) {
-
- /**
- * Converts `value` to an array-like object if it's not one.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {Array|Object} Returns the array-like object.
- */
- function toIterable(value) {
- if (value == null) {
- return [];
- }
- if (!isArrayLike(value)) {
- return values(value);
- }
- return isObject(value) ? value : Object(value);
- }
-
- return toIterable;
-});
diff --git a/internal/toObject.js b/internal/toObject.js
deleted file mode 100644
index cabcf9963..000000000
--- a/internal/toObject.js
+++ /dev/null
@@ -1,15 +0,0 @@
-define(['../lang/isObject'], function(isObject) {
-
- /**
- * Converts `value` to an object if it's not one.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {Object} Returns the object.
- */
- function toObject(value) {
- return isObject(value) ? value : Object(value);
- }
-
- return toObject;
-});
diff --git a/internal/trimmedLeftIndex.js b/internal/trimmedLeftIndex.js
deleted file mode 100644
index 2e45445fa..000000000
--- a/internal/trimmedLeftIndex.js
+++ /dev/null
@@ -1,20 +0,0 @@
-define(['./isSpace'], function(isSpace) {
-
- /**
- * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace
- * character of `string`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @returns {number} Returns the index of the first non-whitespace character.
- */
- function trimmedLeftIndex(string) {
- var index = -1,
- length = string.length;
-
- while (++index < length && isSpace(string.charCodeAt(index))) {}
- return index;
- }
-
- return trimmedLeftIndex;
-});
diff --git a/internal/trimmedRightIndex.js b/internal/trimmedRightIndex.js
deleted file mode 100644
index 3391cb178..000000000
--- a/internal/trimmedRightIndex.js
+++ /dev/null
@@ -1,19 +0,0 @@
-define(['./isSpace'], function(isSpace) {
-
- /**
- * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace
- * character of `string`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @returns {number} Returns the index of the last non-whitespace character.
- */
- function trimmedRightIndex(string) {
- var index = string.length;
-
- while (index-- && isSpace(string.charCodeAt(index))) {}
- return index;
- }
-
- return trimmedRightIndex;
-});
diff --git a/internal/wrapperClone.js b/internal/wrapperClone.js
index 2fc0f56a4..23b08ae35 100644
--- a/internal/wrapperClone.js
+++ b/internal/wrapperClone.js
@@ -1,4 +1,4 @@
-define(['./LazyWrapper', './LodashWrapper', './arrayCopy'], function(LazyWrapper, LodashWrapper, arrayCopy) {
+define(['./LazyWrapper', './LodashWrapper', './copyArray'], function(LazyWrapper, LodashWrapper, copyArray) {
/**
* Creates a clone of `wrapper`.
@@ -8,9 +8,14 @@ define(['./LazyWrapper', './LodashWrapper', './arrayCopy'], function(LazyWrapper
* @returns {Object} Returns the cloned wrapper.
*/
function wrapperClone(wrapper) {
- return wrapper instanceof LazyWrapper
- ? wrapper.clone()
- : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
+ if (wrapper instanceof LazyWrapper) {
+ return wrapper.clone();
+ }
+ var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
+ result.__actions__ = copyArray(wrapper.__actions__);
+ result.__index__ = wrapper.__index__;
+ result.__values__ = wrapper.__values__;
+ return result;
}
return wrapperClone;
diff --git a/intersection.js b/intersection.js
new file mode 100644
index 000000000..15dec2ebf
--- /dev/null
+++ b/intersection.js
@@ -0,0 +1,25 @@
+define(['./internal/arrayMap', './internal/baseIntersection', './rest', './internal/toArrayLikeObject'], function(arrayMap, baseIntersection, rest, toArrayLikeObject) {
+
+ /**
+ * Creates an array of unique values that are included in all of the provided
+ * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of shared values.
+ * @example
+ * _.intersection([2, 1], [4, 2], [1, 2]);
+ * // => [2]
+ */
+ var intersection = rest(function(arrays) {
+ var mapped = arrayMap(arrays, toArrayLikeObject);
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped)
+ : [];
+ });
+
+ return intersection;
+});
diff --git a/intersectionBy.js b/intersectionBy.js
new file mode 100644
index 000000000..c7877cfd2
--- /dev/null
+++ b/intersectionBy.js
@@ -0,0 +1,41 @@
+define(['./internal/arrayMap', './internal/baseIntersection', './internal/baseIteratee', './last', './rest', './internal/toArrayLikeObject'], function(arrayMap, baseIntersection, baseIteratee, last, rest, toArrayLikeObject) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.intersection` except that it accepts `iteratee`
+ * which is invoked for each element of each `arrays` to generate the criterion
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ * @example
+ *
+ * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+ * // => [2.1]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }]
+ */
+ var intersectionBy = rest(function(arrays) {
+ var iteratee = last(arrays),
+ mapped = arrayMap(arrays, toArrayLikeObject);
+
+ if (iteratee === last(mapped)) {
+ iteratee = undefined;
+ } else {
+ mapped.pop();
+ }
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped, baseIteratee(iteratee))
+ : [];
+ });
+
+ return intersectionBy;
+});
diff --git a/intersectionWith.js b/intersectionWith.js
new file mode 100644
index 000000000..76c8ed0fd
--- /dev/null
+++ b/intersectionWith.js
@@ -0,0 +1,40 @@
+define(['./internal/arrayMap', './internal/baseIntersection', './last', './rest', './internal/toArrayLikeObject'], function(arrayMap, baseIntersection, last, rest, toArrayLikeObject) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.intersection` except that it accepts `comparator`
+ * which is invoked to compare elements of `arrays`. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.intersectionWith(objects, others, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }]
+ */
+ var intersectionWith = rest(function(arrays) {
+ var comparator = last(arrays),
+ mapped = arrayMap(arrays, toArrayLikeObject);
+
+ if (comparator === last(mapped)) {
+ comparator = undefined;
+ } else {
+ mapped.pop();
+ }
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped, undefined, comparator)
+ : [];
+ });
+
+ return intersectionWith;
+});
diff --git a/object/invert.js b/invert.js
similarity index 51%
rename from object/invert.js
rename to invert.js
index 6b4f0b071..541011005 100644
--- a/object/invert.js
+++ b/invert.js
@@ -1,9 +1,6 @@
-define(['../internal/isIterateeCall', './keys'], function(isIterateeCall, keys) {
+define(['./internal/arrayReduce', './keys'], function(arrayReduce, keys) {
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
@@ -12,14 +9,14 @@ define(['../internal/isIterateeCall', './keys'], function(isIterateeCall, keys)
/**
* Creates an object composed of the inverted keys and values of `object`.
* If `object` contains duplicate values, subsequent values overwrite property
- * assignments of previous values unless `multiValue` is `true`.
+ * assignments of previous values unless `multiVal` is `true`.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to invert.
- * @param {boolean} [multiValue] Allow multiple values per key.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param {boolean} [multiVal] Allow multiple values per key.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Object} Returns the new inverted object.
* @example
*
@@ -28,24 +25,14 @@ define(['../internal/isIterateeCall', './keys'], function(isIterateeCall, keys)
* _.invert(object);
* // => { '1': 'c', '2': 'b' }
*
- * // with `multiValue`
+ * // with `multiVal`
* _.invert(object, true);
* // => { '1': ['a', 'c'], '2': ['b'] }
*/
- function invert(object, multiValue, guard) {
- if (guard && isIterateeCall(object, multiValue, guard)) {
- multiValue = undefined;
- }
- var index = -1,
- props = keys(object),
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index],
- value = object[key];
-
- if (multiValue) {
+ function invert(object, multiVal, guard) {
+ return arrayReduce(keys(object), function(result, key) {
+ var value = object[key];
+ if (multiVal && !guard) {
if (hasOwnProperty.call(result, value)) {
result[value].push(key);
} else {
@@ -55,8 +42,8 @@ define(['../internal/isIterateeCall', './keys'], function(isIterateeCall, keys)
else {
result[value] = key;
}
- }
- return result;
+ return result;
+ }, {});
}
return invert;
diff --git a/invoke.js b/invoke.js
new file mode 100644
index 000000000..757233776
--- /dev/null
+++ b/invoke.js
@@ -0,0 +1,23 @@
+define(['./internal/baseInvoke', './rest'], function(baseInvoke, rest) {
+
+ /**
+ * Invokes the method at `path` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {...*} [args] The arguments to invoke the method with.
+ * @returns {*} Returns the result of the invoked method.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
+ *
+ * _.invoke(object, 'a[0].b.c.slice', 1, 3);
+ * // => [2, 3]
+ */
+ var invoke = rest(baseInvoke);
+
+ return invoke;
+});
diff --git a/collection/invoke.js b/invokeMap.js
similarity index 64%
rename from collection/invoke.js
rename to invokeMap.js
index 91fd61222..d8a23cc7e 100644
--- a/collection/invoke.js
+++ b/invokeMap.js
@@ -1,4 +1,4 @@
-define(['../internal/baseEach', '../internal/invokePath', '../internal/isArrayLike', '../internal/isKey', '../function/restParam'], function(baseEach, invokePath, isArrayLike, isKey, restParam) {
+define(['./internal/apply', './internal/baseEach', './internal/baseInvoke', './isArrayLike', './internal/isKey', './rest'], function(apply, baseEach, baseInvoke, isArrayLike, isKey, rest) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -12,20 +12,20 @@ define(['../internal/baseEach', '../internal/invokePath', '../internal/isArrayLi
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Array|Function|string} path The path of the method to invoke or
* the function invoked per iteration.
- * @param {...*} [args] The arguments to invoke the method with.
+ * @param {...*} [args] The arguments to invoke each method with.
* @returns {Array} Returns the array of results.
* @example
*
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
+ * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
* // => [[1, 5, 7], [1, 2, 3]]
*
- * _.invoke([123, 456], String.prototype.split, '');
+ * _.invokeMap([123, 456], String.prototype.split, '');
* // => [['1', '2', '3'], ['4', '5', '6']]
*/
- var invoke = restParam(function(collection, path, args) {
+ var invokeMap = rest(function(collection, path, args) {
var index = -1,
isFunc = typeof path == 'function',
isProp = isKey(path),
@@ -33,10 +33,10 @@ define(['../internal/baseEach', '../internal/invokePath', '../internal/isArrayLi
baseEach(collection, function(value) {
var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
- result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);
+ result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
});
return result;
});
- return invoke;
+ return invokeMap;
});
diff --git a/isArguments.js b/isArguments.js
new file mode 100644
index 000000000..52409921e
--- /dev/null
+++ b/isArguments.js
@@ -0,0 +1,44 @@
+define(['./isArrayLikeObject'], function(isArrayLikeObject) {
+
+ /** `Object#toString` result references. */
+ var argsTag = '[object Arguments]';
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString = objectProto.toString;
+
+ /** Built-in value references. */
+ var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+ /**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+ function isArguments(value) {
+ // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+ return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
+ (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
+ }
+
+ return isArguments;
+});
diff --git a/isArray.js b/isArray.js
new file mode 100644
index 000000000..a27d86820
--- /dev/null
+++ b/isArray.js
@@ -0,0 +1,29 @@
+define([], function() {
+
+ /**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(document.body.children);
+ * // => false
+ *
+ * _.isArray('abc');
+ * // => false
+ *
+ * _.isArray(_.noop);
+ * // => false
+ */
+ var isArray = Array.isArray;
+
+ return isArray;
+});
diff --git a/isArrayLike.js b/isArrayLike.js
new file mode 100644
index 000000000..4747c3dcd
--- /dev/null
+++ b/isArrayLike.js
@@ -0,0 +1,34 @@
+define(['./internal/getLength', './isFunction', './isLength'], function(getLength, isFunction, isLength) {
+
+ /**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+ function isArrayLike(value) {
+ return value != null &&
+ !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
+ }
+
+ return isArrayLike;
+});
diff --git a/isArrayLikeObject.js b/isArrayLikeObject.js
new file mode 100644
index 000000000..31f66167c
--- /dev/null
+++ b/isArrayLikeObject.js
@@ -0,0 +1,32 @@
+define(['./isArrayLike', './isObjectLike'], function(isArrayLike, isObjectLike) {
+
+ /**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+ function isArrayLikeObject(value) {
+ return isObjectLike(value) && isArrayLike(value);
+ }
+
+ return isArrayLikeObject;
+});
diff --git a/lang/isBoolean.js b/isBoolean.js
similarity index 72%
rename from lang/isBoolean.js
rename to isBoolean.js
index 2545332f4..50168627f 100644
--- a/lang/isBoolean.js
+++ b/isBoolean.js
@@ -1,16 +1,16 @@
-define(['../internal/isObjectLike'], function(isObjectLike) {
+define(['./isObjectLike'], function(isObjectLike) {
/** `Object#toString` result references. */
var boolTag = '[object Boolean]';
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a boolean primitive or object.
@@ -29,7 +29,8 @@ define(['../internal/isObjectLike'], function(isObjectLike) {
* // => false
*/
function isBoolean(value) {
- return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag);
+ return value === true || value === false ||
+ (isObjectLike(value) && objectToString.call(value) == boolTag);
}
return isBoolean;
diff --git a/lang/isDate.js b/isDate.js
similarity index 76%
rename from lang/isDate.js
rename to isDate.js
index fc8d78c6f..4acd73b1c 100644
--- a/lang/isDate.js
+++ b/isDate.js
@@ -1,16 +1,16 @@
-define(['../internal/isObjectLike'], function(isObjectLike) {
+define(['./isObjectLike'], function(isObjectLike) {
/** `Object#toString` result references. */
var dateTag = '[object Date]';
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a `Date` object.
@@ -29,7 +29,7 @@ define(['../internal/isObjectLike'], function(isObjectLike) {
* // => false
*/
function isDate(value) {
- return isObjectLike(value) && objToString.call(value) == dateTag;
+ return isObjectLike(value) && objectToString.call(value) == dateTag;
}
return isDate;
diff --git a/lang/isElement.js b/isElement.js
similarity index 77%
rename from lang/isElement.js
rename to isElement.js
index 780c44916..45db28b74 100644
--- a/lang/isElement.js
+++ b/isElement.js
@@ -1,7 +1,7 @@
-define(['../internal/isObjectLike', './isPlainObject'], function(isObjectLike, isPlainObject) {
+define(['./isObjectLike', './isPlainObject'], function(isObjectLike, isPlainObject) {
/**
- * Checks if `value` is a DOM element.
+ * Checks if `value` is likely a DOM element.
*
* @static
* @memberOf _
diff --git a/lang/isEmpty.js b/isEmpty.js
similarity index 59%
rename from lang/isEmpty.js
rename to isEmpty.js
index b7f6b20b1..fcb586a6e 100644
--- a/lang/isEmpty.js
+++ b/isEmpty.js
@@ -1,4 +1,4 @@
-define(['./isArguments', './isArray', '../internal/isArrayLike', './isFunction', '../internal/isObjectLike', './isString', '../object/keys'], function(isArguments, isArray, isArrayLike, isFunction, isObjectLike, isString, keys) {
+define(['./isFunction', './isObjectLike', './keys', './size'], function(isFunction, isObjectLike, keys, size) {
/**
* Checks if `value` is empty. A value is considered empty unless it's an
@@ -28,14 +28,9 @@ define(['./isArguments', './isArray', '../internal/isArrayLike', './isFunction',
* // => false
*/
function isEmpty(value) {
- if (value == null) {
- return true;
- }
- if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
- (isObjectLike(value) && isFunction(value.splice)))) {
- return !value.length;
- }
- return !keys(value).length;
+ return (!isObjectLike(value) || isFunction(value.splice))
+ ? !size(value)
+ : !keys(value).length;
}
return isEmpty;
diff --git a/isEqual.js b/isEqual.js
new file mode 100644
index 000000000..b1e37500e
--- /dev/null
+++ b/isEqual.js
@@ -0,0 +1,35 @@
+define(['./internal/baseIsEqual'], function(baseIsEqual) {
+
+ /**
+ * Performs a deep comparison between two values to determine if they are
+ * equivalent.
+ *
+ * **Note:** This method supports comparing arrays, array buffers, booleans,
+ * date objects, error objects, maps, numbers, `Object` objects, regexes,
+ * sets, strings, symbols, and typed arrays. `Object` objects are compared
+ * by their own, not inherited, enumerable properties. Functions and DOM
+ * nodes are **not** supported.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var other = { 'user': 'fred' };
+ *
+ * _.isEqual(object, other);
+ * // => true
+ *
+ * object === other;
+ * // => false
+ */
+ function isEqual(value, other) {
+ return baseIsEqual(value, other);
+ }
+
+ return isEqual;
+});
diff --git a/isEqualWith.js b/isEqualWith.js
new file mode 100644
index 000000000..ae371140f
--- /dev/null
+++ b/isEqualWith.js
@@ -0,0 +1,44 @@
+define(['./internal/baseIsEqual'], function(baseIsEqual) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.isEqual` except that it accepts `customizer` which is
+ * invoked to compare values. If `customizer` returns `undefined` comparisons are
+ * handled by the method instead. The `customizer` is invoked with up to seven arguments:
+ * (objValue, othValue [, index|key, object, other, stack]).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * function isGreeting(value) {
+ * return /^h(?:i|ello)$/.test(value);
+ * }
+ *
+ * function customizer(objValue, othValue) {
+ * if (isGreeting(objValue) && isGreeting(othValue)) {
+ * return true;
+ * }
+ * }
+ *
+ * var array = ['hello', 'goodbye'];
+ * var other = ['hi', 'goodbye'];
+ *
+ * _.isEqualWith(array, other, customizer);
+ * // => true
+ */
+ function isEqualWith(value, other, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ var result = customizer ? customizer(value, other) : undefined;
+ return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
+ }
+
+ return isEqualWith;
+});
diff --git a/lang/isError.js b/isError.js
similarity index 74%
rename from lang/isError.js
rename to isError.js
index 484eb4c5c..e0f46f04b 100644
--- a/lang/isError.js
+++ b/isError.js
@@ -1,16 +1,16 @@
-define(['../internal/isObjectLike'], function(isObjectLike) {
+define(['./isObjectLike'], function(isObjectLike) {
/** `Object#toString` result references. */
var errorTag = '[object Error]';
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/**
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
@@ -30,7 +30,8 @@ define(['../internal/isObjectLike'], function(isObjectLike) {
* // => false
*/
function isError(value) {
- return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag;
+ return isObjectLike(value) &&
+ typeof value.message == 'string' && objectToString.call(value) == errorTag;
}
return isError;
diff --git a/lang/isFinite.js b/isFinite.js
similarity index 55%
rename from lang/isFinite.js
rename to isFinite.js
index bedd3d6ca..7ffa8754f 100644
--- a/lang/isFinite.js
+++ b/isFinite.js
@@ -1,12 +1,12 @@
-define(['../internal/root'], function(root) {
+define(['./internal/root'], function(root) {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeIsFinite = root.isFinite;
/**
* Checks if `value` is a finite primitive number.
*
- * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).
+ * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
*
* @static
* @memberOf _
@@ -15,17 +15,14 @@ define(['../internal/root'], function(root) {
* @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
* @example
*
- * _.isFinite(10);
+ * _.isFinite(3);
* // => true
*
- * _.isFinite('10');
- * // => false
+ * _.isFinite(Number.MAX_VALUE);
+ * // => true
*
- * _.isFinite(true);
- * // => false
- *
- * _.isFinite(Object(10));
- * // => false
+ * _.isFinite(3.14);
+ * // => true
*
* _.isFinite(Infinity);
* // => false
diff --git a/lang/isFunction.js b/isFunction.js
similarity index 64%
rename from lang/isFunction.js
rename to isFunction.js
index 5d42d79c9..2f2239aed 100644
--- a/lang/isFunction.js
+++ b/isFunction.js
@@ -1,16 +1,17 @@
define(['./isObject'], function(isObject) {
/** `Object#toString` result references. */
- var funcTag = '[object Function]';
+ var funcTag = '[object Function]',
+ genTag = '[object GeneratorFunction]';
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a `Function` object.
@@ -30,9 +31,10 @@ define(['./isObject'], function(isObject) {
*/
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 which returns 'object' for typed array constructors.
- return isObject(value) && objToString.call(value) == funcTag;
+ // in Safari 8 which returns 'object' for typed array constructors, and
+ // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+ var tag = isObject(value) ? objectToString.call(value) : '';
+ return tag == funcTag || tag == genTag;
}
return isFunction;
diff --git a/isInteger.js b/isInteger.js
new file mode 100644
index 000000000..2d2c75b98
--- /dev/null
+++ b/isInteger.js
@@ -0,0 +1,32 @@
+define(['./toInteger'], function(toInteger) {
+
+ /**
+ * Checks if `value` is an integer.
+ *
+ * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
+ * @example
+ *
+ * _.isInteger(3);
+ * // => true
+ *
+ * _.isInteger(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isInteger(Infinity);
+ * // => false
+ *
+ * _.isInteger('3');
+ * // => false
+ */
+ function isInteger(value) {
+ return typeof value == 'number' && value == toInteger(value);
+ }
+
+ return isInteger;
+});
diff --git a/isLength.js b/isLength.js
new file mode 100644
index 000000000..d23408916
--- /dev/null
+++ b/isLength.js
@@ -0,0 +1,35 @@
+define([], function() {
+
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER = 9007199254740991;
+
+ /**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+ function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+ }
+
+ return isLength;
+});
diff --git a/isMatch.js b/isMatch.js
new file mode 100644
index 000000000..3260dd10c
--- /dev/null
+++ b/isMatch.js
@@ -0,0 +1,30 @@
+define(['./internal/baseIsMatch', './internal/getMatchData'], function(baseIsMatch, getMatchData) {
+
+ /**
+ * Performs a deep comparison between `object` and `source` to determine if
+ * `object` contains equivalent property values.
+ *
+ * **Note:** This method supports comparing the same values as `_.isEqual`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ * @example
+ *
+ * var object = { 'user': 'fred', 'age': 40 };
+ *
+ * _.isMatch(object, { 'age': 40 });
+ * // => true
+ *
+ * _.isMatch(object, { 'age': 36 });
+ * // => false
+ */
+ function isMatch(object, source) {
+ return object === source || baseIsMatch(object, source, getMatchData(source));
+ }
+
+ return isMatch;
+});
diff --git a/isMatchWith.js b/isMatchWith.js
new file mode 100644
index 000000000..6b11b913c
--- /dev/null
+++ b/isMatchWith.js
@@ -0,0 +1,43 @@
+define(['./internal/baseIsMatch', './internal/getMatchData'], function(baseIsMatch, getMatchData) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.isMatch` except that it accepts `customizer` which
+ * is invoked to compare values. If `customizer` returns `undefined` comparisons
+ * are handled by the method instead. The `customizer` is invoked with three
+ * arguments: (objValue, srcValue, index|key, object, source).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ * @example
+ *
+ * function isGreeting(value) {
+ * return /^h(?:i|ello)$/.test(value);
+ * }
+ *
+ * function customizer(objValue, srcValue) {
+ * if (isGreeting(objValue) && isGreeting(srcValue)) {
+ * return true;
+ * }
+ * }
+ *
+ * var object = { 'greeting': 'hello' };
+ * var source = { 'greeting': 'hi' };
+ *
+ * _.isMatchWith(object, source, customizer);
+ * // => true
+ */
+ function isMatchWith(object, source, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return baseIsMatch(object, source, getMatchData(source), customizer);
+ }
+
+ return isMatchWith;
+});
diff --git a/lang/isNaN.js b/isNaN.js
similarity index 96%
rename from lang/isNaN.js
rename to isNaN.js
index 04a24465e..ab308b8bb 100644
--- a/lang/isNaN.js
+++ b/isNaN.js
@@ -27,7 +27,7 @@ define(['./isNumber'], function(isNumber) {
*/
function isNaN(value) {
// An `NaN` primitive is the only value that is not equal to itself.
- // Perform the `toStringTag` check first to avoid errors with some host objects in IE.
+ // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
return isNumber(value) && value != +value;
}
diff --git a/lang/isNative.js b/isNative.js
similarity index 62%
rename from lang/isNative.js
rename to isNative.js
index 662fd2139..02c6183be 100644
--- a/lang/isNative.js
+++ b/isNative.js
@@ -1,20 +1,23 @@
-define(['./isFunction', '../internal/isObjectLike'], function(isFunction, isObjectLike) {
+define(['./isFunction', './internal/isHostObject', './isObjectLike'], function(isFunction, isHostObject, isObjectLike) {
+
+ /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
+ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
/** Used to detect host constructors (Safari > 5). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to resolve the decompiled source of functions. */
- var fnToString = Function.prototype.toString;
+ var funcToString = Function.prototype.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
- fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+ funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
@@ -39,9 +42,10 @@ define(['./isFunction', '../internal/isObjectLike'], function(isFunction, isObje
return false;
}
if (isFunction(value)) {
- return reIsNative.test(fnToString.call(value));
+ return reIsNative.test(funcToString.call(value));
}
- return isObjectLike(value) && reIsHostCtor.test(value);
+ return isObjectLike(value) &&
+ (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
}
return isNative;
diff --git a/isNil.js b/isNil.js
new file mode 100644
index 000000000..38b8af622
--- /dev/null
+++ b/isNil.js
@@ -0,0 +1,27 @@
+define([], function() {
+
+ /**
+ * Checks if `value` is `null` or `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
+ * @example
+ *
+ * _.isNil(null);
+ * // => true
+ *
+ * _.isNil(void 0);
+ * // => true
+ *
+ * _.isNil(NaN);
+ * // => false
+ */
+ function isNil(value) {
+ return value == null;
+ }
+
+ return isNil;
+});
diff --git a/lang/isNull.js b/isNull.js
similarity index 100%
rename from lang/isNull.js
rename to isNull.js
diff --git a/lang/isNumber.js b/isNumber.js
similarity index 68%
rename from lang/isNumber.js
rename to isNumber.js
index 3a97326dd..eb466b2bc 100644
--- a/lang/isNumber.js
+++ b/isNumber.js
@@ -1,16 +1,16 @@
-define(['../internal/isObjectLike'], function(isObjectLike) {
+define(['./isObjectLike'], function(isObjectLike) {
/** `Object#toString` result references. */
var numberTag = '[object Number]';
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a `Number` primitive or object.
@@ -25,17 +25,21 @@ define(['../internal/isObjectLike'], function(isObjectLike) {
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
- * _.isNumber(8.4);
+ * _.isNumber(3);
* // => true
*
- * _.isNumber(NaN);
+ * _.isNumber(Number.MIN_VALUE);
* // => true
*
- * _.isNumber('8.4');
+ * _.isNumber(Infinity);
+ * // => true
+ *
+ * _.isNumber('3');
* // => false
*/
function isNumber(value) {
- return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
+ return typeof value == 'number' ||
+ (isObjectLike(value) && objectToString.call(value) == numberTag);
}
return isNumber;
diff --git a/lang/isObject.js b/isObject.js
similarity index 91%
rename from lang/isObject.js
rename to isObject.js
index 0d8b30ca3..099c756d3 100644
--- a/lang/isObject.js
+++ b/isObject.js
@@ -17,7 +17,10 @@ define([], function() {
* _.isObject([1, 2, 3]);
* // => true
*
- * _.isObject(1);
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
* // => false
*/
function isObject(value) {
diff --git a/isObjectLike.js b/isObjectLike.js
new file mode 100644
index 000000000..8d3f5bdaf
--- /dev/null
+++ b/isObjectLike.js
@@ -0,0 +1,31 @@
+define([], function() {
+
+ /**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+ function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+ }
+
+ return isObjectLike;
+});
diff --git a/isPlainObject.js b/isPlainObject.js
new file mode 100644
index 000000000..20c0b4d80
--- /dev/null
+++ b/isPlainObject.js
@@ -0,0 +1,68 @@
+define(['./internal/isHostObject', './isObjectLike'], function(isHostObject, isObjectLike) {
+
+ /** `Object#toString` result references. */
+ var objectTag = '[object Object]';
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to resolve the decompiled source of functions. */
+ var funcToString = Function.prototype.toString;
+
+ /** Used to infer the `Object` constructor. */
+ var objectCtorString = funcToString.call(Object);
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString = objectProto.toString;
+
+ /** Built-in value references. */
+ var getPrototypeOf = 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`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * }
+ *
+ * _.isPlainObject(new Foo);
+ * // => false
+ *
+ * _.isPlainObject([1, 2, 3]);
+ * // => false
+ *
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
+ * // => true
+ *
+ * _.isPlainObject(Object.create(null));
+ * // => true
+ */
+ function isPlainObject(value) {
+ if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
+ return false;
+ }
+ var proto = objectProto;
+ if (typeof value.constructor == 'function') {
+ proto = getPrototypeOf(value);
+ }
+ if (proto === null) {
+ return true;
+ }
+ var Ctor = proto.constructor;
+ return (typeof Ctor == 'function' &&
+ Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
+ }
+
+ return isPlainObject;
+});
diff --git a/lang/isRegExp.js b/isRegExp.js
similarity index 81%
rename from lang/isRegExp.js
rename to isRegExp.js
index f600e646d..7da1d82bb 100644
--- a/lang/isRegExp.js
+++ b/isRegExp.js
@@ -3,14 +3,14 @@ define(['./isObject'], function(isObject) {
/** `Object#toString` result references. */
var regexpTag = '[object RegExp]';
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a `RegExp` object.
@@ -29,7 +29,7 @@ define(['./isObject'], function(isObject) {
* // => false
*/
function isRegExp(value) {
- return isObject(value) && objToString.call(value) == regexpTag;
+ return isObject(value) && objectToString.call(value) == regexpTag;
}
return isRegExp;
diff --git a/isSafeInteger.js b/isSafeInteger.js
new file mode 100644
index 000000000..c315a93b8
--- /dev/null
+++ b/isSafeInteger.js
@@ -0,0 +1,36 @@
+define(['./isInteger'], function(isInteger) {
+
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER = 9007199254740991;
+
+ /**
+ * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
+ * double precision number which isn't the result of a rounded unsafe integer.
+ *
+ * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
+ * @example
+ *
+ * _.isSafeInteger(3);
+ * // => true
+ *
+ * _.isSafeInteger(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isSafeInteger(Infinity);
+ * // => false
+ *
+ * _.isSafeInteger('3');
+ * // => false
+ */
+ function isSafeInteger(value) {
+ return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
+ }
+
+ return isSafeInteger;
+});
diff --git a/lang/isString.js b/isString.js
similarity index 70%
rename from lang/isString.js
rename to isString.js
index 7bee4b1a0..9a1a85198 100644
--- a/lang/isString.js
+++ b/isString.js
@@ -1,16 +1,16 @@
-define(['../internal/isObjectLike'], function(isObjectLike) {
+define(['./isArray', './isObjectLike'], function(isArray, isObjectLike) {
/** `Object#toString` result references. */
var stringTag = '[object String]';
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a `String` primitive or object.
@@ -29,7 +29,8 @@ define(['../internal/isObjectLike'], function(isObjectLike) {
* // => false
*/
function isString(value) {
- return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
+ return typeof value == 'string' ||
+ (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
}
return isString;
diff --git a/isSymbol.js b/isSymbol.js
new file mode 100644
index 000000000..93d8de34c
--- /dev/null
+++ b/isSymbol.js
@@ -0,0 +1,37 @@
+define(['./isObjectLike'], function(isObjectLike) {
+
+ /** `Object#toString` result references. */
+ var symbolTag = '[object Symbol]';
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString = objectProto.toString;
+
+ /**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */
+ function isSymbol(value) {
+ return typeof value == 'symbol' ||
+ (isObjectLike(value) && objectToString.call(value) == symbolTag);
+ }
+
+ return isSymbol;
+});
diff --git a/lang/isTypedArray.js b/isTypedArray.js
similarity index 91%
rename from lang/isTypedArray.js
rename to isTypedArray.js
index bafddfbde..108042111 100644
--- a/lang/isTypedArray.js
+++ b/isTypedArray.js
@@ -1,4 +1,4 @@
-define(['../internal/isLength', '../internal/isObjectLike'], function(isLength, isObjectLike) {
+define(['./isLength', './isObjectLike'], function(isLength, isObjectLike) {
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
@@ -41,14 +41,14 @@ define(['../internal/isLength', '../internal/isObjectLike'], function(isLength,
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a typed array.
@@ -67,7 +67,7 @@ define(['../internal/isLength', '../internal/isObjectLike'], function(isLength,
* // => false
*/
function isTypedArray(value) {
- return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
+ return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
}
return isTypedArray;
diff --git a/lang/isUndefined.js b/isUndefined.js
similarity index 100%
rename from lang/isUndefined.js
rename to isUndefined.js
diff --git a/iteratee.js b/iteratee.js
new file mode 100644
index 000000000..d6095c163
--- /dev/null
+++ b/iteratee.js
@@ -0,0 +1,39 @@
+define(['./internal/baseIteratee', './isArray', './isObjectLike', './matches'], function(baseIteratee, isArray, isObjectLike, matches) {
+
+ /**
+ * Creates a function that invokes `func` with the arguments of the created
+ * function. If `func` is a property name the created callback returns the
+ * property value for a given element. If `func` is an object the created
+ * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {*} [func=_.identity] The value to convert to a callback.
+ * @returns {Function} Returns the callback.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 }
+ * ];
+ *
+ * // create custom iteratee shorthands
+ * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
+ * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
+ * return !p ? callback(func) : function(object) {
+ * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
+ * };
+ * });
+ *
+ * _.filter(users, 'age > 36');
+ * // => [{ 'user': 'fred', 'age': 40 }]
+ */
+ function iteratee(func) {
+ return (isObjectLike(func) && !isArray(func))
+ ? matches(func)
+ : baseIteratee(func);
+ }
+
+ return iteratee;
+});
diff --git a/join.js b/join.js
new file mode 100644
index 000000000..e9f8a9fbc
--- /dev/null
+++ b/join.js
@@ -0,0 +1,28 @@
+define([], function() {
+
+ /** Used for built-in method references. */
+ var arrayProto = Array.prototype;
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeJoin = arrayProto.join;
+
+ /**
+ * Converts all elements in `array` into a string separated by `separator`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to convert.
+ * @param {string} [separator=','] The element separator.
+ * @returns {string} Returns the joined string.
+ * @example
+ *
+ * _.join(['a', 'b', 'c'], '~');
+ * // => 'a~b~c'
+ */
+ function join(array, separator) {
+ return array ? nativeJoin.call(array, separator) : '';
+ }
+
+ return join;
+});
diff --git a/string/kebabCase.js b/kebabCase.js
similarity index 89%
rename from string/kebabCase.js
rename to kebabCase.js
index 4bbea5bc6..7a0230c41 100644
--- a/string/kebabCase.js
+++ b/kebabCase.js
@@ -1,4 +1,4 @@
-define(['../internal/createCompounder'], function(createCompounder) {
+define(['./internal/createCompounder'], function(createCompounder) {
/**
* Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
diff --git a/keyBy.js b/keyBy.js
new file mode 100644
index 000000000..65ee419b5
--- /dev/null
+++ b/keyBy.js
@@ -0,0 +1,35 @@
+define(['./internal/createAggregator'], function(createAggregator) {
+
+ /**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` through `iteratee`. The corresponding value
+ * of each key is the last element responsible for generating the key. The
+ * iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * var keyData = [
+ * { 'dir': 'left', 'code': 97 },
+ * { 'dir': 'right', 'code': 100 }
+ * ];
+ *
+ * _.keyBy(keyData, 'dir');
+ * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
+ *
+ * _.keyBy(keyData, function(o) {
+ * return String.fromCharCode(o.code);
+ * });
+ * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+ */
+ var keyBy = createAggregator(function(result, value, key) {
+ result[key] = value;
+ });
+
+ return keyBy;
+});
diff --git a/keys.js b/keys.js
new file mode 100644
index 000000000..70a3ee209
--- /dev/null
+++ b/keys.js
@@ -0,0 +1,51 @@
+define(['./internal/baseHas', './internal/baseKeys', './internal/indexKeys', './isArrayLike', './internal/isIndex', './internal/isPrototype'], function(baseHas, baseKeys, indexKeys, isArrayLike, isIndex, isPrototype) {
+
+ /**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+ function keys(object) {
+ var isProto = isPrototype(object);
+ if (!(isProto || isArrayLike(object))) {
+ return baseKeys(object);
+ }
+ var indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.length;
+
+ for (var key in object) {
+ if (baseHas(object, key) &&
+ !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+ !(isProto && key == 'constructor')) {
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ return keys;
+});
diff --git a/object/keysIn.js b/keysIn.js
similarity index 51%
rename from object/keysIn.js
rename to keysIn.js
index 1eeafc169..a646c8308 100644
--- a/object/keysIn.js
+++ b/keysIn.js
@@ -1,6 +1,6 @@
-define(['../lang/isArguments', '../lang/isArray', '../internal/isIndex', '../internal/isLength', '../lang/isObject'], function(isArguments, isArray, isIndex, isLength, isObject) {
+define(['./internal/baseKeysIn', './internal/indexKeys', './internal/isIndex', './internal/isPrototype'], function(baseKeysIn, indexKeys, isIndex, isPrototype) {
- /** Used for native method references. */
+ /** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
@@ -29,27 +29,18 @@ define(['../lang/isArguments', '../lang/isArray', '../internal/isIndex', '../int
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
*/
function keysIn(object) {
- if (object == null) {
- return [];
- }
- if (!isObject(object)) {
- object = Object(object);
- }
- var length = object.length;
- length = (length && isLength(length) &&
- (isArray(object) || isArguments(object)) && length) || 0;
+ var index = -1,
+ isProto = isPrototype(object),
+ props = baseKeysIn(object),
+ propsLength = props.length,
+ indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.length;
- var Ctor = object.constructor,
- index = -1,
- isProto = typeof Ctor == 'function' && Ctor.prototype === object,
- result = Array(length),
- skipIndexes = length > 0;
-
- while (++index < length) {
- result[index] = (index + '');
- }
- for (var key in object) {
- if (!(skipIndexes && isIndex(key, length)) &&
+ while (++index < propsLength) {
+ var key = props[index];
+ if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
result.push(key);
}
diff --git a/lang.js b/lang.js
index f15f29d2d..eeb5591a0 100644
--- a/lang.js
+++ b/lang.js
@@ -1,34 +1,51 @@
-define(['./lang/clone', './lang/cloneDeep', './lang/eq', './lang/gt', './lang/gte', './lang/isArguments', './lang/isArray', './lang/isBoolean', './lang/isDate', './lang/isElement', './lang/isEmpty', './lang/isEqual', './lang/isError', './lang/isFinite', './lang/isFunction', './lang/isMatch', './lang/isNaN', './lang/isNative', './lang/isNull', './lang/isNumber', './lang/isObject', './lang/isPlainObject', './lang/isRegExp', './lang/isString', './lang/isTypedArray', './lang/isUndefined', './lang/lt', './lang/lte', './lang/toArray', './lang/toPlainObject'], function(clone, cloneDeep, eq, gt, gte, isArguments, isArray, isBoolean, isDate, isElement, isEmpty, isEqual, isError, isFinite, isFunction, isMatch, isNaN, isNative, isNull, isNumber, isObject, isPlainObject, isRegExp, isString, isTypedArray, isUndefined, lt, lte, toArray, toPlainObject) {
+define(['./clone', './cloneDeep', './cloneDeepWith', './cloneWith', './eq', './gt', './gte', './isArguments', './isArray', './isArrayLike', './isArrayLikeObject', './isBoolean', './isDate', './isElement', './isEmpty', './isEqual', './isEqualWith', './isError', './isFinite', './isFunction', './isInteger', './isLength', './isMatch', './isMatchWith', './isNaN', './isNative', './isNil', './isNull', './isNumber', './isObject', './isObjectLike', './isPlainObject', './isRegExp', './isSafeInteger', './isString', './isSymbol', './isTypedArray', './isUndefined', './lt', './lte', './toArray', './toInteger', './toLength', './toNumber', './toPlainObject', './toSafeInteger', './toString'], function(clone, cloneDeep, cloneDeepWith, cloneWith, eq, gt, gte, isArguments, isArray, isArrayLike, isArrayLikeObject, isBoolean, isDate, isElement, isEmpty, isEqual, isEqualWith, isError, isFinite, isFunction, isInteger, isLength, isMatch, isMatchWith, isNaN, isNative, isNil, isNull, isNumber, isObject, isObjectLike, isPlainObject, isRegExp, isSafeInteger, isString, isSymbol, isTypedArray, isUndefined, lt, lte, toArray, toInteger, toLength, toNumber, toPlainObject, toSafeInteger, toString) {
return {
'clone': clone,
'cloneDeep': cloneDeep,
+ 'cloneDeepWith': cloneDeepWith,
+ 'cloneWith': cloneWith,
'eq': eq,
'gt': gt,
'gte': gte,
'isArguments': isArguments,
'isArray': isArray,
+ 'isArrayLike': isArrayLike,
+ 'isArrayLikeObject': isArrayLikeObject,
'isBoolean': isBoolean,
'isDate': isDate,
'isElement': isElement,
'isEmpty': isEmpty,
'isEqual': isEqual,
+ 'isEqualWith': isEqualWith,
'isError': isError,
'isFinite': isFinite,
'isFunction': isFunction,
+ 'isInteger': isInteger,
+ 'isLength': isLength,
'isMatch': isMatch,
+ 'isMatchWith': isMatchWith,
'isNaN': isNaN,
'isNative': isNative,
+ 'isNil': isNil,
'isNull': isNull,
'isNumber': isNumber,
'isObject': isObject,
+ 'isObjectLike': isObjectLike,
'isPlainObject': isPlainObject,
'isRegExp': isRegExp,
+ 'isSafeInteger': isSafeInteger,
'isString': isString,
+ 'isSymbol': isSymbol,
'isTypedArray': isTypedArray,
'isUndefined': isUndefined,
'lt': lt,
'lte': lte,
'toArray': toArray,
- 'toPlainObject': toPlainObject
+ 'toInteger': toInteger,
+ 'toLength': toLength,
+ 'toNumber': toNumber,
+ 'toPlainObject': toPlainObject,
+ 'toSafeInteger': toSafeInteger,
+ 'toString': toString
};
});
diff --git a/lang/clone.js b/lang/clone.js
deleted file mode 100644
index 55498f8e3..000000000
--- a/lang/clone.js
+++ /dev/null
@@ -1,69 +0,0 @@
-define(['../internal/baseClone', '../internal/bindCallback', '../internal/isIterateeCall'], function(baseClone, bindCallback, isIterateeCall) {
-
- /**
- * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned,
- * otherwise they are assigned by reference. If `customizer` is provided it's
- * invoked to produce the cloned values. If `customizer` returns `undefined`
- * cloning is handled by the method instead. The `customizer` is bound to
- * `thisArg` and invoked with up to three argument; (value [, index|key, object]).
- *
- * **Note:** This method is loosely based on the
- * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
- * The enumerable properties of `arguments` objects and objects created by
- * constructors other than `Object` are cloned to plain `Object` objects. An
- * empty object is returned for uncloneable values such as functions, DOM nodes,
- * Maps, Sets, and WeakMaps.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep] Specify a deep clone.
- * @param {Function} [customizer] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `customizer`.
- * @returns {*} Returns the cloned value.
- * @example
- *
- * var users = [
- * { 'user': 'barney' },
- * { 'user': 'fred' }
- * ];
- *
- * var shallow = _.clone(users);
- * shallow[0] === users[0];
- * // => true
- *
- * var deep = _.clone(users, true);
- * deep[0] === users[0];
- * // => false
- *
- * // using a customizer callback
- * var el = _.clone(document.body, function(value) {
- * if (_.isElement(value)) {
- * return value.cloneNode(false);
- * }
- * });
- *
- * el === document.body
- * // => false
- * el.nodeName
- * // => BODY
- * el.childNodes.length;
- * // => 0
- */
- function clone(value, isDeep, customizer, thisArg) {
- if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {
- isDeep = false;
- }
- else if (typeof isDeep == 'function') {
- thisArg = customizer;
- customizer = isDeep;
- isDeep = false;
- }
- return typeof customizer == 'function'
- ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 3))
- : baseClone(value, isDeep);
- }
-
- return clone;
-});
diff --git a/lang/cloneDeep.js b/lang/cloneDeep.js
deleted file mode 100644
index 7d3c44230..000000000
--- a/lang/cloneDeep.js
+++ /dev/null
@@ -1,55 +0,0 @@
-define(['../internal/baseClone', '../internal/bindCallback'], function(baseClone, bindCallback) {
-
- /**
- * Creates a deep clone of `value`. If `customizer` is provided it's invoked
- * to produce the cloned values. If `customizer` returns `undefined` cloning
- * is handled by the method instead. The `customizer` is bound to `thisArg`
- * and invoked with up to three argument; (value [, index|key, object]).
- *
- * **Note:** This method is loosely based on the
- * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
- * The enumerable properties of `arguments` objects and objects created by
- * constructors other than `Object` are cloned to plain `Object` objects. An
- * empty object is returned for uncloneable values such as functions, DOM nodes,
- * Maps, Sets, and WeakMaps.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to deep clone.
- * @param {Function} [customizer] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `customizer`.
- * @returns {*} Returns the deep cloned value.
- * @example
- *
- * var users = [
- * { 'user': 'barney' },
- * { 'user': 'fred' }
- * ];
- *
- * var deep = _.cloneDeep(users);
- * deep[0] === users[0];
- * // => false
- *
- * // using a customizer callback
- * var el = _.cloneDeep(document.body, function(value) {
- * if (_.isElement(value)) {
- * return value.cloneNode(true);
- * }
- * });
- *
- * el === document.body
- * // => false
- * el.nodeName
- * // => BODY
- * el.childNodes.length;
- * // => 20
- */
- function cloneDeep(value, customizer, thisArg) {
- return typeof customizer == 'function'
- ? baseClone(value, true, bindCallback(customizer, thisArg, 3))
- : baseClone(value, true);
- }
-
- return cloneDeep;
-});
diff --git a/lang/eq.js b/lang/eq.js
deleted file mode 100644
index 7459fa8af..000000000
--- a/lang/eq.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./isEqual"], function(isEqual) {
- return isEqual;
-});
diff --git a/lang/isArguments.js b/lang/isArguments.js
deleted file mode 100644
index 17d3c9cf1..000000000
--- a/lang/isArguments.js
+++ /dev/null
@@ -1,34 +0,0 @@
-define(['../internal/isArrayLike', '../internal/isObjectLike'], function(isArrayLike, isObjectLike) {
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** 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.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- * @example
- *
- * _.isArguments(function() { return arguments; }());
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
- function isArguments(value) {
- return isObjectLike(value) && isArrayLike(value) &&
- hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
- }
-
- return isArguments;
-});
diff --git a/lang/isArray.js b/lang/isArray.js
deleted file mode 100644
index 075585188..000000000
--- a/lang/isArray.js
+++ /dev/null
@@ -1,39 +0,0 @@
-define(['../internal/getNative', '../internal/isLength', '../internal/isObjectLike'], function(getNative, isLength, isObjectLike) {
-
- /** `Object#toString` result references. */
- var arrayTag = '[object Array]';
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /**
- * 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 for those with the same name as other `lodash` methods. */
- var nativeIsArray = getNative(Array, 'isArray');
-
- /**
- * Checks if `value` is classified as an `Array` object.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- * @example
- *
- * _.isArray([1, 2, 3]);
- * // => true
- *
- * _.isArray(function() { return arguments; }());
- * // => false
- */
- var isArray = nativeIsArray || function(value) {
- return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
- };
-
- return isArray;
-});
diff --git a/lang/isEqual.js b/lang/isEqual.js
deleted file mode 100644
index e0f26a622..000000000
--- a/lang/isEqual.js
+++ /dev/null
@@ -1,57 +0,0 @@
-define(['../internal/baseIsEqual', '../internal/bindCallback'], function(baseIsEqual, bindCallback) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Performs a deep comparison between two values to determine if they are
- * equivalent. If `customizer` is provided it's invoked to compare values.
- * If `customizer` returns `undefined` comparisons are handled by the method
- * instead. The `customizer` is bound to `thisArg` and invoked with up to
- * three arguments: (value, other [, index|key]).
- *
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties. Functions and DOM nodes
- * are **not** supported. Provide a customizer function to extend support
- * for comparing other values.
- *
- * @static
- * @memberOf _
- * @alias eq
- * @category Lang
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @param {Function} [customizer] The function to customize value comparisons.
- * @param {*} [thisArg] The `this` binding of `customizer`.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- * @example
- *
- * var object = { 'user': 'fred' };
- * var other = { 'user': 'fred' };
- *
- * object == other;
- * // => false
- *
- * _.isEqual(object, other);
- * // => true
- *
- * // using a customizer callback
- * var array = ['hello', 'goodbye'];
- * var other = ['hi', 'goodbye'];
- *
- * _.isEqual(array, other, function(value, other) {
- * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) {
- * return true;
- * }
- * });
- * // => true
- */
- function isEqual(value, other, customizer, thisArg) {
- customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
- var result = customizer ? customizer(value, other) : undefined;
- return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
- }
-
- return isEqual;
-});
diff --git a/lang/isMatch.js b/lang/isMatch.js
deleted file mode 100644
index 70b1cc843..000000000
--- a/lang/isMatch.js
+++ /dev/null
@@ -1,51 +0,0 @@
-define(['../internal/baseIsMatch', '../internal/bindCallback', '../internal/getMatchData'], function(baseIsMatch, bindCallback, getMatchData) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Performs a deep comparison between `object` and `source` to determine if
- * `object` contains equivalent property values. If `customizer` is provided
- * it's invoked to compare values. If `customizer` returns `undefined`
- * comparisons are handled by the method instead. The `customizer` is bound
- * to `thisArg` and invoked with three arguments: (value, other, index|key).
- *
- * **Note:** This method supports comparing properties of arrays, booleans,
- * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions
- * and DOM nodes are **not** supported. Provide a customizer function to extend
- * support for comparing other values.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {Object} object The object to inspect.
- * @param {Object} source The object of property values to match.
- * @param {Function} [customizer] The function to customize value comparisons.
- * @param {*} [thisArg] The `this` binding of `customizer`.
- * @returns {boolean} Returns `true` if `object` is a match, else `false`.
- * @example
- *
- * var object = { 'user': 'fred', 'age': 40 };
- *
- * _.isMatch(object, { 'age': 40 });
- * // => true
- *
- * _.isMatch(object, { 'age': 36 });
- * // => false
- *
- * // using a customizer callback
- * var object = { 'greeting': 'hello' };
- * var source = { 'greeting': 'hi' };
- *
- * _.isMatch(object, source, function(value, other) {
- * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined;
- * });
- * // => true
- */
- function isMatch(object, source, customizer, thisArg) {
- customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
- return baseIsMatch(object, getMatchData(source), customizer);
- }
-
- return isMatch;
-});
diff --git a/lang/isPlainObject.js b/lang/isPlainObject.js
deleted file mode 100644
index cd3b829e7..000000000
--- a/lang/isPlainObject.js
+++ /dev/null
@@ -1,73 +0,0 @@
-define(['../internal/baseForIn', './isArguments', '../internal/isObjectLike'], function(baseForIn, isArguments, isObjectLike) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /** `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`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
- * of values.
- */
- var objToString = objectProto.toString;
-
- /**
- * Checks if `value` is a plain object, that is, an object created by the
- * `Object` constructor or one with a `[[Prototype]]` of `null`.
- *
- * **Note:** This method assumes objects created by the `Object` constructor
- * have no inherited enumerable properties.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- * @example
- *
- * function Foo() {
- * this.a = 1;
- * }
- *
- * _.isPlainObject(new Foo);
- * // => false
- *
- * _.isPlainObject([1, 2, 3]);
- * // => false
- *
- * _.isPlainObject({ 'x': 0, 'y': 0 });
- * // => true
- *
- * _.isPlainObject(Object.create(null));
- * // => true
- */
- 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;
- }
- // 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);
- }
-
- return isPlainObject;
-});
diff --git a/lang/toArray.js b/lang/toArray.js
deleted file mode 100644
index ea89fce86..000000000
--- a/lang/toArray.js
+++ /dev/null
@@ -1,30 +0,0 @@
-define(['../internal/arrayCopy', '../internal/getLength', '../internal/isLength', '../object/values'], function(arrayCopy, getLength, isLength, values) {
-
- /**
- * Converts `value` to an array.
- *
- * @static
- * @memberOf _
- * @category Lang
- * @param {*} value The value to convert.
- * @returns {Array} Returns the converted array.
- * @example
- *
- * (function() {
- * return _.toArray(arguments).slice(1);
- * }(1, 2, 3));
- * // => [2, 3]
- */
- function toArray(value) {
- var length = value ? getLength(value) : 0;
- if (!isLength(length)) {
- return values(value);
- }
- if (!length) {
- return [];
- }
- return arrayCopy(value);
- }
-
- return toArray;
-});
diff --git a/array/last.js b/last.js
similarity index 100%
rename from array/last.js
rename to last.js
diff --git a/array/lastIndexOf.js b/lastIndexOf.js
similarity index 53%
rename from array/lastIndexOf.js
rename to lastIndexOf.js
index 6ef22b422..fa52de315 100644
--- a/array/lastIndexOf.js
+++ b/lastIndexOf.js
@@ -1,6 +1,9 @@
-define(['../internal/binaryIndex', '../internal/indexOfNaN'], function(binaryIndex, indexOfNaN) {
+define(['./internal/indexOfNaN', './toInteger'], function(indexOfNaN, toInteger) {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
@@ -13,8 +16,7 @@ define(['../internal/binaryIndex', '../internal/indexOfNaN'], function(binaryInd
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=array.length-1] The index to search from
- * or `true` to perform a binary search on a sorted array.
+ * @param {number} [fromIndex=array.length-1] The index to search from.
* @returns {number} Returns the index of the matched value, else `-1`.
* @example
*
@@ -24,10 +26,6 @@ define(['../internal/binaryIndex', '../internal/indexOfNaN'], function(binaryInd
* // using `fromIndex`
* _.lastIndexOf([1, 2, 1, 2], 2, 2);
* // => 1
- *
- * // performing a binary search
- * _.lastIndexOf([1, 1, 2, 2], 2, true);
- * // => 3
*/
function lastIndexOf(array, value, fromIndex) {
var length = array ? array.length : 0;
@@ -35,15 +33,9 @@ define(['../internal/binaryIndex', '../internal/indexOfNaN'], function(binaryInd
return -1;
}
var index = length;
- if (typeof fromIndex == 'number') {
- index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1;
- } else if (fromIndex) {
- index = binaryIndex(array, value, true) - 1;
- var other = array[index];
- if (value === value ? (value === other) : (other !== other)) {
- return index;
- }
- return -1;
+ if (fromIndex !== undefined) {
+ index = toInteger(fromIndex);
+ index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
}
if (value !== value) {
return indexOfNaN(array, index, true);
diff --git a/lowerCase.js b/lowerCase.js
new file mode 100644
index 000000000..5480a421a
--- /dev/null
+++ b/lowerCase.js
@@ -0,0 +1,27 @@
+define(['./internal/createCompounder'], function(createCompounder) {
+
+ /**
+ * Converts `string`, as space separated words, to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the lower cased string.
+ * @example
+ *
+ * _.lowerCase('--Foo-Bar');
+ * // => 'foo bar'
+ *
+ * _.lowerCase('fooBar');
+ * // => 'foo bar'
+ *
+ * _.lowerCase('__FOO_BAR__');
+ * // => 'foo bar'
+ */
+ var lowerCase = createCompounder(function(result, word, index) {
+ return result + (index ? ' ' : '') + word.toLowerCase();
+ });
+
+ return lowerCase;
+});
diff --git a/lowerFirst.js b/lowerFirst.js
new file mode 100644
index 000000000..59f29bcdf
--- /dev/null
+++ b/lowerFirst.js
@@ -0,0 +1,22 @@
+define(['./internal/createCaseFirst'], function(createCaseFirst) {
+
+ /**
+ * Converts the first character of `string` to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.lowerFirst('Fred');
+ * // => 'fred'
+ *
+ * _.lowerFirst('FRED');
+ * // => 'fRED'
+ */
+ var lowerFirst = createCaseFirst('toLowerCase');
+
+ return lowerFirst;
+});
diff --git a/lang/lt.js b/lt.js
similarity index 100%
rename from lang/lt.js
rename to lt.js
diff --git a/lang/lte.js b/lte.js
similarity index 100%
rename from lang/lte.js
rename to lte.js
diff --git a/main.js b/main.js
index 3b8b89575..7224e37dc 100644
--- a/main.js
+++ b/main.js
@@ -1,10 +1,10 @@
/**
* @license
- * lodash 3.10.1 (Custom Build)
- * Build: `lodash modern exports="amd" -d -o ./main.js`
- * Copyright 2012-2015 The Dojo Foundation
+ * lodash 4.0.0 (Custom Build)
+ * Build: `lodash exports="amd" -d -o ./main.js`
+ * Copyright 2012-2016 The Dojo Foundation
* Based on Underscore.js 1.8.3
- * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
* Available under MIT license
*/
;(function() {
@@ -13,7 +13,7 @@
var undefined;
/** Used as the semantic version number. */
- var VERSION = '3.10.1';
+ var VERSION = '4.0.0';
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -24,13 +24,18 @@
PARTIAL_FLAG = 32,
PARTIAL_RIGHT_FLAG = 64,
ARY_FLAG = 128,
- REARG_FLAG = 256;
+ REARG_FLAG = 256,
+ FLIP_FLAG = 512;
- /** Used as default options for `_.trunc`. */
+ /** Used to compose bitmasks for comparison styles. */
+ var UNORDERED_COMPARE_FLAG = 1,
+ PARTIAL_COMPARE_FLAG = 2;
+
+ /** Used as default options for `_.truncate`. */
var DEFAULT_TRUNC_LENGTH = 30,
DEFAULT_TRUNC_OMISSION = '...';
- /** Used to detect when a function becomes hot. */
+ /** Used to detect hot functions by number of calls within a span of milliseconds. */
var HOT_COUNT = 150,
HOT_SPAN = 16;
@@ -39,11 +44,26 @@
/** Used to indicate the type of lazy iteratees. */
var LAZY_FILTER_FLAG = 1,
- LAZY_MAP_FLAG = 2;
+ LAZY_MAP_FLAG = 2,
+ LAZY_WHILE_FLAG = 3;
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
+ /** Used to stand-in for `undefined` hash values. */
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+ /** Used as references for various `Number` constants. */
+ var INFINITY = 1 / 0,
+ MAX_SAFE_INTEGER = 9007199254740991,
+ MAX_INTEGER = 1.7976931348623157e+308,
+ NAN = 0 / 0;
+
+ /** Used as references for the maximum length and index of an array. */
+ var MAX_ARRAY_LENGTH = 4294967295,
+ MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
+ HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
+
/** Used as the internal argument placeholder. */
var PLACEHOLDER = '__lodash_placeholder__';
@@ -54,12 +74,14 @@
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
+ genTag = '[object GeneratorFunction]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
+ symbolTag = '[object Symbol]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
@@ -90,19 +112,18 @@
reInterpolate = /<%=([\s\S]+?)%>/g;
/** Used to match property names within property paths. */
- var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
+ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
reIsPlainProp = /^\w*$/,
- rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
+ rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
- /**
- * 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 = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,
- reHasRegExpChars = RegExp(reRegExpChars.source);
+ /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
+ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
+ reHasRegExpChar = RegExp(reRegExpChar.source);
- /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
- var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g;
+ /** Used to match leading and trailing whitespace. */
+ var reTrim = /^\s+|\s+$/g,
+ reTrimStart = /^\s+/,
+ reTrimEnd = /\s+$/;
/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;
@@ -114,13 +135,22 @@
var reFlags = /\w*$/;
/** Used to detect hexadecimal string values. */
- var reHasHexPrefix = /^0[xX]/;
+ var reHasHexPrefix = /^0x/i;
+
+ /** Used to detect bad signed hexadecimal string values. */
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+
+ /** Used to detect binary string values. */
+ var reIsBinary = /^0b[01]+$/i;
/** Used to detect host constructors (Safari > 5). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
+ /** Used to detect octal string values. */
+ var reIsOctal = /^0o[0-7]+$/i;
+
/** Used to detect unsigned integer values. */
- var reIsUint = /^\d+$/;
+ var reIsUint = /^(?:0|[1-9]\d*)$/;
/** Used to match latin-1 supplementary letters (excluding mathematical operators). */
var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
@@ -131,21 +161,75 @@
/** Used to match unescaped characters in compiled string literals. */
var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
- /** Used to match words to create compound words. */
- var reWords = (function() {
- var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]',
- lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+';
+ /** Used to compose unicode character classes. */
+ var rsAstralRange = '\\ud800-\\udfff',
+ rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsDingbatRange = '\\u2700-\\u27bf',
+ rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
+ rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
+ rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
+ rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
+ rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
+ rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
+ rsVarRange = '\\ufe0e\\ufe0f',
+ rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
- return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');
- }());
+ /** Used to compose unicode capture groups. */
+ var rsAstral = '[' + rsAstralRange + ']',
+ rsBreak = '[' + rsBreakRange + ']',
+ rsCombo = '[' + rsComboRange + ']',
+ rsDigits = '\\d+',
+ rsDingbat = '[' + rsDingbatRange + ']',
+ rsLower = '[' + rsLowerRange + ']',
+ rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
+ rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
+ rsNonAstral = '[^' + rsAstralRange + ']',
+ rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+ rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+ rsUpper = '[' + rsUpperRange + ']',
+ rsZWJ = '\\u200d';
+
+ /** Used to compose unicode regexes. */
+ var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
+ rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
+ reOptMod = rsModifier + '?',
+ rsOptVar = '[' + rsVarRange + ']?',
+ rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+ rsSeq = rsOptVar + reOptMod + rsOptJoin,
+ rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
+ rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
+
+ /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
+ var reComboMark = RegExp(rsCombo, 'g');
+
+ /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
+ var reComplexSymbol = RegExp(rsSymbol + rsSeq, 'g');
+
+ /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+ var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+
+ /** Used to match non-compound words composed of alphanumeric characters. */
+ var reBasicWord = /[a-zA-Z0-9]+/g;
+
+ /** Used to match complex or compound words. */
+ var reComplexWord = RegExp([
+ rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
+ rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
+ rsUpper + '?' + rsLowerMisc + '+',
+ rsDigits + '(?:' + rsLowerMisc + '+)?',
+ rsEmoji
+ ].join('|'), 'g');
+
+ /** Used to detect strings that need a more robust regexp to match words. */
+ var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
/** Used to assign default `context` object properties. */
var contextProps = [
- 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
- 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
- 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite',
- 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
- 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap'
+ 'Array', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function',
+ 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
+ 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
+ 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
+ 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
];
/** Used to make template sourceURLs easier to identify. */
@@ -173,12 +257,13 @@
cloneableTags[dateTag] = cloneableTags[float32Tag] =
cloneableTags[float64Tag] = cloneableTags[int8Tag] =
cloneableTags[int16Tag] = cloneableTags[int32Tag] =
- cloneableTags[numberTag] = cloneableTags[objectTag] =
- cloneableTags[regexpTag] = cloneableTags[stringTag] =
- cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
- cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+ cloneableTags[mapTag] = cloneableTags[numberTag] =
+ cloneableTags[objectTag] = cloneableTags[regexpTag] =
+ cloneableTags[setTag] = cloneableTags[stringTag] =
+ cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
+ cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
+ cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] =
- cloneableTags[mapTag] = cloneableTags[setTag] =
cloneableTags[weakMapTag] = false;
/** Used to map latin-1 supplementary letters to basic latin letters. */
@@ -228,15 +313,6 @@
'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 = {
'\\': '\\',
@@ -247,20 +323,27 @@
'\u2029': 'u2029'
};
+ /** Built-in method references without a dependency on `root`. */
+ var freeParseFloat = parseFloat,
+ freeParseInt = parseInt;
+
/** Detect free variable `exports`. */
- var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
+ var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
/** Detect free variable `module`. */
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
+ var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
/** Detect free variable `global` from Node.js. */
- var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;
+ var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
/** Detect free variable `self`. */
- var freeSelf = objectTypes[typeof self] && self && self.Object && self;
+ var freeSelf = checkGlobal(objectTypes[typeof self] && self);
/** Detect free variable `window`. */
- var freeWindow = objectTypes[typeof window] && window && window.Object && window;
+ var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+ /** Detect `this` as the global object. */
+ var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
/**
* Used as a reference to the global object.
@@ -268,20 +351,586 @@
* The `this` value is used if it's the global object to avoid Greasemonkey's
* restricted `window` object, otherwise the `window` object is used.
*/
- var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
+ var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
/*--------------------------------------------------------------------------*/
/**
- * The base implementation of `compareAscending` which compares values and
- * sorts them in ascending order without guaranteeing a stable sort.
+ * Adds the key-value `pair` to `map`.
+ *
+ * @private
+ * @param {Object} map The map to modify.
+ * @param {Array} pair The key-value pair to add.
+ * @returns {Object} Returns `map`.
+ */
+ function addMapEntry(map, pair) {
+ map.set(pair[0], pair[1]);
+ return map;
+ }
+
+ /**
+ * Adds `value` to `set`.
+ *
+ * @private
+ * @param {Object} set The set to modify.
+ * @param {*} value The value to add.
+ * @returns {Object} Returns `set`.
+ */
+ function addSetEntry(set, value) {
+ set.add(value);
+ return set;
+ }
+
+ /**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */
+ function apply(func, thisArg, args) {
+ var length = args ? args.length : 0;
+ switch (length) {
+ case 0: return func.call(thisArg);
+ case 1: return func.call(thisArg, args[0]);
+ case 2: return func.call(thisArg, args[0], args[1]);
+ case 3: return func.call(thisArg, args[0], args[1], args[2]);
+ }
+ return func.apply(thisArg, args);
+ }
+
+ /**
+ * Creates a new array concatenating `array` with `other`.
+ *
+ * @private
+ * @param {Array} array The first array to concatenate.
+ * @param {Array} other The second array to concatenate.
+ * @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;
+ }
+
+ /**
+ * A specialized version of `_.forEach` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayEach(array, iteratee) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (iteratee(array[index], index, array) === false) {
+ break;
+ }
+ }
+ return array;
+ }
+
+ /**
+ * A specialized version of `_.forEachRight` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayEachRight(array, iteratee) {
+ var length = array.length;
+
+ while (length--) {
+ if (iteratee(array[length], length, array) === false) {
+ break;
+ }
+ }
+ return array;
+ }
+
+ /**
+ * A specialized version of `_.every` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
+ */
+ function arrayEvery(array, predicate) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (!predicate(array[index], index, array)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * A specialized version of `_.filter` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ */
+ function arrayFilter(array, predicate) {
+ var index = -1,
+ length = array.length,
+ resIndex = -1,
+ result = [];
+
+ while (++index < length) {
+ var value = array[index];
+ if (predicate(value, index, array)) {
+ result[++resIndex] = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * A specialized version of `_.includes` for arrays without support for
+ * specifying an index to search from.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} target The value to search for.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */
+ function arrayIncludes(array, value) {
+ return !!array.length && baseIndexOf(array, value, 0) > -1;
+ }
+
+ /**
+ * A specialized version of `_.includesWith` for arrays without support for
+ * specifying an index to search from.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} target The value to search for.
+ * @param {Function} comparator The comparator invoked per element.
+ * @returns {boolean} Returns `true` if `target` is found, else `false`.
+ */
+ function arrayIncludesWith(array, value, comparator) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (comparator(value, array[index])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * A specialized version of `_.map` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+ function arrayMap(array, iteratee) {
+ var index = -1,
+ length = array.length,
+ result = Array(length);
+
+ while (++index < length) {
+ result[index] = iteratee(array[index], index, array);
+ }
+ 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
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initFromArray] Specify using the first element of `array` as the initial value.
+ * @returns {*} Returns the accumulated value.
+ */
+ function arrayReduce(array, iteratee, accumulator, initFromArray) {
+ var index = -1,
+ length = array.length;
+
+ if (initFromArray && length) {
+ accumulator = array[++index];
+ }
+ while (++index < length) {
+ accumulator = iteratee(accumulator, array[index], index, array);
+ }
+ return accumulator;
+ }
+
+ /**
+ * A specialized version of `_.reduceRight` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initFromArray] Specify using the last element of `array` as the initial value.
+ * @returns {*} Returns the accumulated value.
+ */
+ function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
+ var length = array.length;
+ if (initFromArray && length) {
+ accumulator = array[--length];
+ }
+ while (length--) {
+ accumulator = iteratee(accumulator, array[length], length, array);
+ }
+ return accumulator;
+ }
+
+ /**
+ * A specialized version of `_.some` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
+ */
+ function arraySome(array, predicate) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (predicate(array[index], index, array)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * The base implementation of methods like `_.max` and `_.min` which accepts a
+ * `comparator` to determine the extremum value.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The iteratee invoked per iteration.
+ * @param {Function} comparator The comparator used to compare values.
+ * @returns {*} Returns the extremum value.
+ */
+ function baseExtremum(array, iteratee, comparator) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var value = array[index],
+ current = iteratee(value);
+
+ if (current != null && (computed === undefined
+ ? current === current
+ : comparator(current, computed)
+ )) {
+ var computed = current,
+ result = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of methods like `_.find` and `_.findKey`, without
+ * support for iteratee shorthands, which iterates over `collection` using
+ * the provided `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to search.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
+ * @returns {*} Returns the found element or its key, else `undefined`.
+ */
+ function baseFind(collection, predicate, eachFunc, retKey) {
+ var result;
+ eachFunc(collection, function(value, key, collection) {
+ if (predicate(value, key, collection)) {
+ result = retKey ? key : value;
+ return false;
+ }
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.findIndex` and `_.findLastIndex` without
+ * support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function baseFindIndex(array, predicate, fromRight) {
+ var length = array.length,
+ index = fromRight ? length : -1;
+
+ while ((fromRight ? index-- : ++index < length)) {
+ if (predicate(array[index], index, array)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function baseIndexOf(array, value, fromIndex) {
+ if (value !== value) {
+ return indexOfNaN(array, fromIndex);
+ }
+ var index = fromIndex - 1,
+ length = array.length;
+
+ while (++index < length) {
+ if (array[index] === value) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * The base implementation of `_.reduce` and `_.reduceRight`, without support
+ * for iteratee shorthands, which iterates over `collection` using the provided
+ * `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} accumulator The initial value.
+ * @param {boolean} initFromCollection Specify using the first or last element of `collection` as the initial value.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @returns {*} Returns the accumulated value.
+ */
+ function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
+ eachFunc(collection, function(value, index, collection) {
+ accumulator = initFromCollection
+ ? (initFromCollection = false, value)
+ : iteratee(accumulator, value, index, collection);
+ });
+ return accumulator;
+ }
+
+ /**
+ * The base implementation of `_.sortBy` which uses `comparer` to define
+ * the sort order of `array` and replaces criteria objects with their
+ * corresponding values.
+ *
+ * @private
+ * @param {Array} array The array to sort.
+ * @param {Function} comparer The function to define sort order.
+ * @returns {Array} Returns `array`.
+ */
+ function baseSortBy(array, comparer) {
+ var length = array.length;
+
+ array.sort(comparer);
+ while (length--) {
+ array[length] = array[length].value;
+ }
+ return array;
+ }
+
+ /**
+ * The base implementation of `_.sum` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {number} Returns the sum.
+ */
+ function baseSum(array, iteratee) {
+ var result,
+ index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var current = iteratee(array[index]);
+ if (current !== undefined) {
+ result = result === undefined ? current : (result + current);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */
+ function baseTimes(n, iteratee) {
+ var index = -1,
+ result = Array(n);
+
+ while (++index < n) {
+ result[index] = iteratee(index);
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
+ * of key-value pairs for `object` corresponding to the property names of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the new array of key-value pairs.
+ */
+ function baseToPairs(object, props) {
+ return arrayMap(props, function(key) {
+ return [key, object[key]];
+ });
+ }
+
+ /**
+ * The base implementation of `_.unary` without support for storing wrapper metadata.
+ *
+ * @private
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new function.
+ */
+ function baseUnary(func) {
+ return function(value) {
+ return func(value);
+ };
+ }
+
+ /**
+ * The base implementation of `_.values` and `_.valuesIn` which creates an
+ * array of `object` property values corresponding to the property names
+ * of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the array of property values.
+ */
+ function baseValues(object, props) {
+ return arrayMap(props, function(key) {
+ return object[key];
+ });
+ }
+
+ /**
+ * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
+ * that is not found in the character symbols.
+ *
+ * @private
+ * @param {Array} strSymbols The string symbols to inspect.
+ * @param {Array} chrSymbols The character symbols to find.
+ * @returns {number} Returns the index of the first unmatched string symbol.
+ */
+ function charsStartIndex(strSymbols, chrSymbols) {
+ var index = -1,
+ length = strSymbols.length;
+
+ while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
+ return index;
+ }
+
+ /**
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
+ * that is not found in the character symbols.
+ *
+ * @private
+ * @param {Array} strSymbols The string symbols to inspect.
+ * @param {Array} chrSymbols The character symbols to find.
+ * @returns {number} Returns the index of the last unmatched string symbol.
+ */
+ function charsEndIndex(strSymbols, chrSymbols) {
+ var index = strSymbols.length;
+
+ while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
+ return index;
+ }
+
+ /**
+ * Checks if `value` is a global object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+ */
+ function checkGlobal(value) {
+ return (value && value.Object === Object) ? value : null;
+ }
+
+ /**
+ * Compares values to sort them in ascending order.
*
* @private
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @returns {number} Returns the sort order indicator for `value`.
*/
- function baseCompareAscending(value, other) {
+ function compareAscending(value, other) {
if (value !== other) {
var valIsNull = value === null,
valIsUndef = value === undefined,
@@ -306,135 +955,17 @@
}
/**
- * The base implementation of `_.findIndex` and `_.findLastIndex` without
- * support for callback shorthands and `this` binding.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {Function} predicate The function invoked per iteration.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
- function baseFindIndex(array, predicate, fromRight) {
- var length = array.length,
- index = fromRight ? length : -1;
-
- while ((fromRight ? index-- : ++index < length)) {
- if (predicate(array[index], index, array)) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * The base implementation of `_.indexOf` without support for binary searches.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} fromIndex The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
- function baseIndexOf(array, value, fromIndex) {
- if (value !== value) {
- return indexOfNaN(array, fromIndex);
- }
- var index = fromIndex - 1,
- length = array.length;
-
- while (++index < length) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * The base implementation of `_.isFunction` without support for environments
- * with incorrect `typeof` results.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
- */
- function baseIsFunction(value) {
- // Avoid a Chakra JIT bug in compatibility modes of IE 11.
- // See https://github.com/jashkenas/underscore/issues/1621 for more details.
- return typeof value == 'function' || false;
- }
-
- /**
- * Converts `value` to a string if it's not one. An empty string is returned
- * for `null` or `undefined` values.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {string} Returns the string.
- */
- function baseToString(value) {
- return value == null ? '' : (value + '');
- }
-
- /**
- * Used by `_.trim` and `_.trimLeft` to get the index of the first character
- * of `string` that is not found in `chars`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @param {string} chars The characters to find.
- * @returns {number} Returns the index of the first character not found in `chars`.
- */
- function charsLeftIndex(string, chars) {
- var index = -1,
- length = string.length;
-
- while (++index < length && chars.indexOf(string.charAt(index)) > -1) {}
- return index;
- }
-
- /**
- * Used by `_.trim` and `_.trimRight` to get the index of the last character
- * of `string` that is not found in `chars`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @param {string} chars The characters to find.
- * @returns {number} Returns the index of the last character not found in `chars`.
- */
- function charsRightIndex(string, chars) {
- var index = string.length;
-
- while (index-- && chars.indexOf(string.charAt(index)) > -1) {}
- return index;
- }
-
- /**
- * Used by `_.sortBy` to compare transformed elements of a collection and stable
- * sort them in ascending order.
- *
- * @private
- * @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) {
- return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index);
- }
-
- /**
- * Used by `_.sortByOrder` to compare multiple properties of a value to another
+ * Used by `_.orderBy` to compare multiple properties of a value to another
* and stable sort them.
*
- * 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".
+ * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
+ * specify an order of "desc" for descending or "asc" for ascending sort order
+ * of corresponding values.
*
* @private
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
- * @param {boolean[]} orders The order to sort by for each property.
+ * @param {boolean[]|string[]} orders The order to sort by for each property.
* @returns {number} Returns the sort order indicator for `object`.
*/
function compareMultiple(object, other, orders) {
@@ -445,13 +976,13 @@
ordersLength = orders.length;
while (++index < length) {
- var result = baseCompareAscending(objCriteria[index], othCriteria[index]);
+ var result = compareAscending(objCriteria[index], othCriteria[index]);
if (result) {
if (index >= ordersLength) {
return result;
}
var order = orders[index];
- return result * ((order === 'asc' || order === true) ? 1 : -1);
+ return result * (order == 'desc' ? -1 : 1);
}
}
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
@@ -486,24 +1017,6 @@
return htmlEscapes[chr];
}
- /**
- * 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.
*
@@ -538,27 +1051,70 @@
}
/**
- * Checks if `value` is object-like.
+ * Checks if `value` is a host object in IE < 9.
*
* @private
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
*/
- function isObjectLike(value) {
- return !!value && typeof value == 'object';
+ function isHostObject(value) {
+ // Many host objects are `Object` objects that can coerce to strings
+ // despite having improperly defined `toString` methods.
+ var result = false;
+ if (value != null && typeof value.toString != 'function') {
+ try {
+ result = !!(value + '');
+ } catch (e) {}
+ }
+ return result;
}
/**
- * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a
- * character code is whitespace.
+ * Checks if `value` is a valid array-like index.
*
* @private
- * @param {number} charCode The character code to inspect.
- * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`.
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
*/
- function isSpace(charCode) {
- return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 ||
- (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279)));
+ function isIndex(value, length) {
+ value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+ length = length == null ? MAX_SAFE_INTEGER : length;
+ return value > -1 && value % 1 == 0 && value < length;
+ }
+
+ /**
+ * Converts `iterator` to an array.
+ *
+ * @private
+ * @param {Object} iterator The iterator to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function iteratorToArray(iterator) {
+ var data,
+ result = [];
+
+ while (!(data = iterator.next()).done) {
+ result.push(data.value);
+ }
+ return result;
+ }
+
+ /**
+ * Converts `map` to an array.
+ *
+ * @private
+ * @param {Object} map The map to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function mapToArray(map) {
+ var index = -1,
+ result = Array(map.size);
+
+ map.forEach(function(value, key) {
+ result[++index] = [key, value];
+ });
+ return result;
}
/**
@@ -586,62 +1142,48 @@
}
/**
- * An implementation of `_.uniq` optimized for sorted arrays without support
- * for callback shorthands and `this` binding.
+ * Converts `set` to an array.
*
* @private
- * @param {Array} array The array to inspect.
- * @param {Function} [iteratee] The function invoked per iteration.
- * @returns {Array} Returns the new duplicate free array.
+ * @param {Object} set The set to convert.
+ * @returns {Array} Returns the converted array.
*/
- function sortedUniq(array, iteratee) {
- var seen,
- index = -1,
- length = array.length,
- resIndex = -1,
- result = [];
+ function setToArray(set) {
+ var index = -1,
+ result = Array(set.size);
- while (++index < length) {
- var value = array[index],
- computed = iteratee ? iteratee(value, index, array) : value;
+ set.forEach(function(value) {
+ result[++index] = value;
+ });
+ return result;
+ }
- if (!index || seen !== computed) {
- seen = computed;
- result[++resIndex] = value;
- }
+ /**
+ * Gets the number of symbols in `string`.
+ *
+ * @param {string} string The string to inspect.
+ * @returns {number} Returns the string size.
+ */
+ function stringSize(string) {
+ if (!(string && reHasComplexSymbol.test(string))) {
+ return string.length;
+ }
+ var result = reComplexSymbol.lastIndex = 0;
+ while (reComplexSymbol.test(string)) {
+ result++;
}
return result;
}
/**
- * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace
- * character of `string`.
+ * Converts `string` to an array.
*
* @private
- * @param {string} string The string to inspect.
- * @returns {number} Returns the index of the first non-whitespace character.
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the converted array.
*/
- function trimmedLeftIndex(string) {
- var index = -1,
- length = string.length;
-
- while (++index < length && isSpace(string.charCodeAt(index))) {}
- return index;
- }
-
- /**
- * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace
- * character of `string`.
- *
- * @private
- * @param {string} string The string to inspect.
- * @returns {number} Returns the index of the last non-whitespace character.
- */
- function trimmedRightIndex(string) {
- var index = string.length;
-
- while (index-- && isSpace(string.charCodeAt(index))) {}
- return index;
+ function stringToArray(string) {
+ return string.match(reComplexSymbol);
}
/**
@@ -658,11 +1200,11 @@
/*--------------------------------------------------------------------------*/
/**
- * Create a new pristine `lodash` function using the given `context` object.
+ * Create a new pristine `lodash` function using the `context` object.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Object} [context=root] The context object.
* @returns {Function} Returns a new `lodash` function.
* @example
@@ -693,31 +1235,21 @@
* var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
*/
function runInContext(context) {
- // Avoid issues with some ES3 environments that attempt to use values, named
- // after built-in constructors like `Object`, for the creation of literals.
- // ES5 clears this up by stating that literals must use built-in constructors.
- // See https://es5.github.io/#x11.1.5 for more details.
- context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
+ context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
- /** Native constructor references. */
- var Array = context.Array,
- Date = context.Date,
+ /** Built-in constructor references. */
+ var Date = context.Date,
Error = context.Error,
- Function = context.Function,
Math = context.Math,
- Number = context.Number,
- Object = context.Object,
RegExp = context.RegExp,
- String = context.String,
TypeError = context.TypeError;
- /** Used for native method references. */
- var arrayProto = Array.prototype,
- objectProto = Object.prototype,
- stringProto = String.prototype;
+ /** Used for built-in method references. */
+ var arrayProto = context.Array.prototype,
+ objectProto = context.Object.prototype;
/** Used to resolve the decompiled source of functions. */
- var fnToString = Function.prototype.toString;
+ var funcToString = context.Function.prototype.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
@@ -725,82 +1257,93 @@
/** Used to generate unique IDs. */
var idCounter = 0;
+ /** Used to infer the `Object` constructor. */
+ var objectCtorString = funcToString.call(Object);
+
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
- var objToString = objectProto.toString;
+ var objectToString = objectProto.toString;
/** Used to restore the original `_` reference in `_.noConflict`. */
var oldDash = root._;
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
- fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+ funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
- /** Native method references. */
- var ArrayBuffer = context.ArrayBuffer,
- clearTimeout = context.clearTimeout,
- parseFloat = context.parseFloat,
- pow = Math.pow,
- propertyIsEnumerable = objectProto.propertyIsEnumerable,
- Set = getNative(context, 'Set'),
- setTimeout = context.setTimeout,
- splice = arrayProto.splice,
+ /** Built-in value references. */
+ var _Symbol = context.Symbol,
+ Reflect = context.Reflect,
Uint8Array = context.Uint8Array,
- WeakMap = getNative(context, 'WeakMap');
+ clearTimeout = context.clearTimeout,
+ enumerate = Reflect ? Reflect.enumerate : undefined,
+ getPrototypeOf = Object.getPrototypeOf,
+ getOwnPropertySymbols = Object.getOwnPropertySymbols,
+ iteratorSymbol = typeof (iteratorSymbol = _Symbol && _Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
+ propertyIsEnumerable = objectProto.propertyIsEnumerable,
+ setTimeout = context.setTimeout,
+ splice = arrayProto.splice;
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeCeil = Math.ceil,
- nativeCreate = getNative(Object, 'create'),
nativeFloor = Math.floor,
- nativeIsArray = getNative(Array, 'isArray'),
nativeIsFinite = context.isFinite,
- nativeKeys = getNative(Object, 'keys'),
+ nativeJoin = arrayProto.join,
+ nativeKeys = Object.keys,
nativeMax = Math.max,
nativeMin = Math.min,
- nativeNow = getNative(Date, 'now'),
nativeParseInt = context.parseInt,
- nativeRandom = Math.random;
+ nativeRandom = Math.random,
+ nativeReverse = arrayProto.reverse;
- /** Used as references for `-Infinity` and `Infinity`. */
- var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY,
- POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
-
- /** Used as references for the maximum length and index of an array. */
- var MAX_ARRAY_LENGTH = 4294967295,
- MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
- HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
-
- /**
- * 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;
+ /* Built-in method references that are verified to be native. */
+ var Map = getNative(context, 'Map'),
+ Set = getNative(context, 'Set'),
+ WeakMap = getNative(context, 'WeakMap'),
+ nativeCreate = getNative(Object, 'create');
/** Used to store function metadata. */
var metaMap = WeakMap && new WeakMap;
+ /** Used to detect maps and sets. */
+ var mapCtorString = Map ? funcToString.call(Map) : '',
+ setCtorString = Set ? funcToString.call(Set) : '';
+
+ /** Used to convert symbols to primitives and strings. */
+ var symbolProto = _Symbol ? _Symbol.prototype : undefined,
+ symbolValueOf = _Symbol ? symbolProto.valueOf : undefined,
+ symbolToString = _Symbol ? symbolProto.toString : undefined;
+
/** Used to lookup unminified function names. */
var realNames = {};
/*------------------------------------------------------------------------*/
/**
- * Creates a `lodash` object which wraps `value` to enable implicit chaining.
- * Methods that operate on and return arrays, collections, and functions can
- * be chained together. Methods that retrieve a single value or may return a
- * primitive value will automatically end the chain 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.
+ * Creates a `lodash` object which wraps `value` to enable implicit method
+ * chaining. Methods that operate on and return arrays, collections, and
+ * functions can be chained together. Methods that retrieve a single value or
+ * may return a primitive value will automatically end the chain sequence and
+ * return the unwrapped value. Otherwise, the value must be unwrapped with
+ * `_#value`.
+ *
+ * Explicit chaining, which must be unwrapped with `_#value` in all cases,
+ * may be enabled using `_.chain`.
+ *
+ * The execution of chained methods is lazy, that is, it's deferred until
+ * `_#value` is implicitly or explicitly called.
*
* Lazy evaluation allows several methods to support shortcut fusion. Shortcut
- * fusion is an optimization strategy which merge iteratee calls; this can help
- * to avoid the creation of intermediate data structures and greatly reduce the
- * number of iteratee executions.
+ * fusion is an optimization to merge iteratee calls; this avoids the creation
+ * of intermediate arrays and can greatly reduce the number of iteratee executions.
+ * Sections of a chain sequence qualify for shortcut fusion if the section is
+ * applied to an array of at least two hundred elements and any iteratees
+ * accept only one argument. The heuristic for whether a section qualifies
+ * for shortcut fusion is subject to change.
*
* Chaining is supported in custom builds as long as the `_#value` method is
* directly or indirectly included in the build.
@@ -808,75 +1351,81 @@
* In addition to lodash methods, wrappers have `Array` and `String` methods.
*
* The wrapper `Array` methods are:
- * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
- * `splice`, and `unshift`
+ * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
*
* The wrapper `String` methods are:
* `replace` and `split`
*
* The wrapper methods that support shortcut fusion are:
- * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
- * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
- * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
- * and `where`
+ * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
+ * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
+ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
*
* 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`, `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`
+ * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
+ * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
+ * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
+ * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
+ * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
+ * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
+ * `flowRight`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
+ * `forOwnRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
+ * `intersection`, `intersectionBy`, `intersectionWith`, invert`, `invokeMap`,
+ * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`,
+ * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`,
+ * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`,
+ * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`,
+ * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`,
+ * `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`,
+ * `reject`, `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`,
+ * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`,
+ * `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`,
+ * `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`,
+ * `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`,
+ * `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `without`,
+ * `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, and `zipWith`
*
* The wrapper methods that are **not** chainable by default are:
- * `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.
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
+ * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
+ * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
+ * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `get`, `gt`, `gte`,
+ * `has`, `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`,
+ * `invoke`, `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`,
+ * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
+ * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`,
+ * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
+ * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
+ * `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, `last`,
+ * `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`,
+ * `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, `padEnd`,
+ * `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`,
+ * `result`, `round`, `runInContext`, `sample`, `shift`, `size`, `snakeCase`,
+ * `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`,
+ * `startCase`, `startsWith`, `subtract`, `sum`, sumBy`, `template`, `times`,
+ * `toLower`, `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, toString`,
+ * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
+ * `upperCase`, `upperFirst`, `value`, and `words`
*
* @name _
* @constructor
- * @category Chain
+ * @category Seq
* @param {*} value The value to wrap in a `lodash` instance.
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
+ * function square(n) {
+ * return n * n;
+ * }
+ *
* var wrapped = _([1, 2, 3]);
*
* // returns an unwrapped value
- * wrapped.reduce(function(total, n) {
- * return total + n;
- * });
+ * wrapped.reduce(_.add);
* // => 6
*
* // returns a wrapped value
- * var squares = wrapped.map(function(n) {
- * return n * n;
- * });
+ * var squares = wrapped.map(square);
*
* _.isArray(squares);
* // => false
@@ -889,7 +1438,7 @@
if (value instanceof LodashWrapper) {
return value;
}
- if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
+ if (hasOwnProperty.call(value, '__wrapped__')) {
return wrapperClone(value);
}
}
@@ -911,23 +1460,15 @@
* @private
* @param {*} value The value to wrap.
* @param {boolean} [chainAll] Enable chaining for all wrapper methods.
- * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.
*/
- function LodashWrapper(value, chainAll, actions) {
+ function LodashWrapper(value, chainAll) {
this.__wrapped__ = value;
- this.__actions__ = actions || [];
+ this.__actions__ = [];
this.__chain__ = !!chainAll;
+ this.__index__ = 0;
+ this.__values__ = undefined;
}
- /**
- * An object environment feature flags.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- var support = lodash.support = {};
-
/**
* By default, the template delimiters used by lodash are like those in
* embedded Ruby (ERB). Change the following template settings to use
@@ -1003,7 +1544,7 @@
this.__dir__ = 1;
this.__filtered__ = false;
this.__iteratees__ = [];
- this.__takeCount__ = POSITIVE_INFINITY;
+ this.__takeCount__ = MAX_ARRAY_LENGTH;
this.__views__ = [];
}
@@ -1017,12 +1558,12 @@
*/
function lazyClone() {
var result = new LazyWrapper(this.__wrapped__);
- result.__actions__ = arrayCopy(this.__actions__);
+ result.__actions__ = copyArray(this.__actions__);
result.__dir__ = this.__dir__;
result.__filtered__ = this.__filtered__;
- result.__iteratees__ = arrayCopy(this.__iteratees__);
+ result.__iteratees__ = copyArray(this.__iteratees__);
result.__takeCount__ = this.__takeCount__;
- result.__views__ = arrayCopy(this.__views__);
+ result.__views__ = copyArray(this.__views__);
return result;
}
@@ -1106,69 +1647,164 @@
/*------------------------------------------------------------------------*/
/**
- * Creates a cache object to store key/value pairs.
+ * Creates an hash object.
*
* @private
- * @static
- * @name Cache
- * @memberOf _.memoize
+ * @returns {Object} Returns the new hash object.
*/
- function MapCache() {
- this.__data__ = {};
+ function Hash() {}
+
+ /**
+ * Removes `key` and its value from the hash.
+ *
+ * @private
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+ */
+ function hashDelete(hash, key) {
+ return hashHas(hash, key) && delete hash[key];
}
/**
- * Removes `key` and its value from the cache.
+ * Gets the hash value for `key`.
+ *
+ * @private
+ * @param {Object} hash The hash to query.
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function hashGet(hash, key) {
+ if (nativeCreate) {
+ var result = hash[key];
+ return result === HASH_UNDEFINED ? undefined : result;
+ }
+ return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
+ }
+
+ /**
+ * Checks if a hash value for `key` exists.
+ *
+ * @private
+ * @param {Object} hash The hash to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function hashHas(hash, key) {
+ return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
+ }
+
+ /**
+ * Sets the hash `key` to `value`.
+ *
+ * @private
+ * @param {Object} hash The hash to modify.
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ */
+ function hashSet(hash, key, value) {
+ hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a map cache object to store key-value pairs.
+ *
+ * @private
+ * @param {Array} [values] The values to cache.
+ */
+ function MapCache(values) {
+ var index = -1,
+ length = values ? values.length : 0;
+
+ this.clear();
+ while (++index < length) {
+ var entry = values[index];
+ this.set(entry[0], entry[1]);
+ }
+ }
+
+ /**
+ * Removes all key-value entries from the map.
+ *
+ * @private
+ * @name clear
+ * @memberOf MapCache
+ */
+ function mapClear() {
+ this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash };
+ }
+
+ /**
+ * Removes `key` and its value from the map.
*
* @private
* @name delete
- * @memberOf _.memoize.Cache
+ * @memberOf MapCache
* @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function mapDelete(key) {
- return this.has(key) && delete this.__data__[key];
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
+ }
+ return Map ? data.map['delete'](key) : assocDelete(data.map, key);
}
/**
- * Gets the cached value for `key`.
+ * Gets the map value for `key`.
*
* @private
* @name get
- * @memberOf _.memoize.Cache
+ * @memberOf MapCache
* @param {string} key The key of the value to get.
- * @returns {*} Returns the cached value.
+ * @returns {*} Returns the entry value.
*/
function mapGet(key) {
- return key == '__proto__' ? undefined : this.__data__[key];
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashGet(typeof key == 'string' ? data.string : data.hash, key);
+ }
+ return Map ? data.map.get(key) : assocGet(data.map, key);
}
/**
- * Checks if a cached value for `key` exists.
+ * Checks if a map value for `key` exists.
*
* @private
* @name has
- * @memberOf _.memoize.Cache
+ * @memberOf MapCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function mapHas(key) {
- return key != '__proto__' && hasOwnProperty.call(this.__data__, key);
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ return hashHas(typeof key == 'string' ? data.string : data.hash, key);
+ }
+ return Map ? data.map.has(key) : assocHas(data.map, key);
}
/**
- * Sets `value` to `key` of the cache.
+ * Sets the map `key` to `value`.
*
* @private
* @name set
- * @memberOf _.memoize.Cache
- * @param {string} key The key of the value to cache.
- * @param {*} value The value to cache.
- * @returns {Object} Returns the cache object.
+ * @memberOf MapCache
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the map cache object.
*/
function mapSet(key, value) {
- if (key != '__proto__') {
- this.__data__[key] = value;
+ var data = this.__data__;
+ if (isKeyable(key)) {
+ hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
+ } else if (Map) {
+ data.map.set(key, value);
+ } else {
+ assocSet(data.map, key, value);
}
return this;
}
@@ -1177,38 +1813,42 @@
/**
*
- * Creates a cache object to store unique values.
+ * Creates a set cache object to store unique values.
*
* @private
* @param {Array} [values] The values to cache.
*/
function SetCache(values) {
- var length = values ? values.length : 0;
+ var index = -1,
+ length = values ? values.length : 0;
- this.data = { 'hash': nativeCreate(null), 'set': new Set };
- while (length--) {
- this.push(values[length]);
+ this.__data__ = new MapCache;
+ while (++index < length) {
+ this.push(values[index]);
}
}
/**
- * Checks if `value` is in `cache` mimicking the return signature of
- * `_.indexOf` by returning `0` if the value is found, else `-1`.
+ * Checks if `value` is in `cache`.
*
* @private
- * @param {Object} cache The cache to search.
+ * @param {Object} cache The set cache to search.
* @param {*} value The value to search for.
- * @returns {number} Returns `0` if `value` is found, else `-1`.
+ * @returns {number} Returns `true` if `value` is found, else `false`.
*/
- function cacheIndexOf(cache, value) {
- var data = cache.data,
- result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];
+ function cacheHas(cache, value) {
+ var map = cache.__data__;
+ if (isKeyable(value)) {
+ var data = map.__data__,
+ hash = typeof value == 'string' ? data.string : data.hash;
- return result ? 0 : -1;
+ return hash[value] === HASH_UNDEFINED;
+ }
+ return map.has(value);
}
/**
- * Adds `value` to the cache.
+ * Adds `value` to the set cache.
*
* @private
* @name push
@@ -1216,366 +1856,267 @@
* @param {*} value The value to cache.
*/
function cachePush(value) {
- var data = this.data;
- if (typeof value == 'string' || isObject(value)) {
- data.set.add(value);
- } else {
- data.hash[value] = true;
+ var map = this.__data__;
+ if (isKeyable(value)) {
+ var data = map.__data__,
+ hash = typeof value == 'string' ? data.string : data.hash;
+
+ hash[value] = HASH_UNDEFINED;
+ }
+ else {
+ map.set(value, HASH_UNDEFINED);
}
}
/*------------------------------------------------------------------------*/
/**
- * Creates a new array joining `array` with `other`.
+ * Creates a stack cache object to store key-value pairs.
*
* @private
- * @param {Array} array The array to join.
- * @param {Array} other The other array to join.
- * @returns {Array} Returns the new concatenated array.
+ * @param {Array} [values] The values to cache.
*/
- function arrayConcat(array, other) {
+ function Stack(values) {
var index = -1,
- length = array.length,
- othIndex = -1,
- othLength = other.length,
- result = Array(length + othLength);
+ length = values ? values.length : 0;
+ this.clear();
while (++index < length) {
- result[index] = array[index];
+ var entry = values[index];
+ this.set(entry[0], entry[1]);
}
- while (++othIndex < othLength) {
- result[index++] = other[othIndex];
- }
- return result;
}
/**
- * Copies the values of `source` to `array`.
+ * Removes all key-value entries from the stack.
*
* @private
- * @param {Array} source The array to copy values from.
- * @param {Array} [array=[]] The array to copy values to.
- * @returns {Array} Returns `array`.
+ * @name clear
+ * @memberOf Stack
*/
- function arrayCopy(source, array) {
- var index = -1,
- length = source.length;
-
- array || (array = Array(length));
- while (++index < length) {
- array[index] = source[index];
- }
- return array;
+ function stackClear() {
+ this.__data__ = { 'array': [], 'map': null };
}
/**
- * A specialized version of `_.forEach` for arrays without support for callback
- * shorthands and `this` binding.
+ * Removes `key` and its value from the stack.
*
* @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns `array`.
+ * @name delete
+ * @memberOf Stack
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
- function arrayEach(array, iteratee) {
- var index = -1,
- length = array.length;
+ function stackDelete(key) {
+ var data = this.__data__,
+ array = data.array;
- while (++index < length) {
- if (iteratee(array[index], index, array) === false) {
- break;
+ return array ? assocDelete(array, key) : data.map['delete'](key);
+ }
+
+ /**
+ * Gets the stack value for `key`.
+ *
+ * @private
+ * @name get
+ * @memberOf Stack
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
+ */
+ function stackGet(key) {
+ var data = this.__data__,
+ array = data.array;
+
+ return array ? assocGet(array, key) : data.map.get(key);
+ }
+
+ /**
+ * Checks if a stack value for `key` exists.
+ *
+ * @private
+ * @name has
+ * @memberOf Stack
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function stackHas(key) {
+ var data = this.__data__,
+ array = data.array;
+
+ return array ? assocHas(array, key) : data.map.has(key);
+ }
+
+ /**
+ * Sets the stack `key` to `value`.
+ *
+ * @private
+ * @name set
+ * @memberOf Stack
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns the stack cache object.
+ */
+ function stackSet(key, value) {
+ var data = this.__data__,
+ array = data.array;
+
+ if (array) {
+ if (array.length < (LARGE_ARRAY_SIZE - 1)) {
+ assocSet(array, key, value);
+ } else {
+ data.array = null;
+ data.map = new MapCache(array);
}
}
- return array;
- }
-
- /**
- * A specialized version of `_.forEachRight` 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 {Array} Returns `array`.
- */
- function arrayEachRight(array, iteratee) {
- var length = array.length;
-
- while (length--) {
- if (iteratee(array[length], length, array) === false) {
- break;
- }
+ var map = data.map;
+ if (map) {
+ map.set(key, value);
}
- return array;
+ return this;
}
+ /*------------------------------------------------------------------------*/
+
/**
- * A specialized version of `_.every` for arrays without support for callback
- * shorthands and `this` binding.
+ * Removes `key` and its value from the associative array.
*
* @private
- * @param {Array} array The array to iterate over.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`.
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the value to remove.
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
- function arrayEvery(array, predicate) {
- var index = -1,
- length = array.length;
-
- while (++index < length) {
- if (!predicate(array[index], index, array)) {
- return false;
- }
+ function assocDelete(array, key) {
+ var index = assocIndexOf(array, key);
+ if (index < 0) {
+ return false;
+ }
+ var lastIndex = array.length - 1;
+ if (index == lastIndex) {
+ array.pop();
+ } else {
+ splice.call(array, index, 1);
}
return true;
}
/**
- * A specialized version of `baseExtremum` for arrays which invokes `iteratee`
- * with one argument: (value).
+ * Gets the associative array value for `key`.
*
* @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {Function} comparator The function used to compare values.
- * @param {*} exValue The initial extremum value.
- * @returns {*} Returns the extremum value.
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the value to get.
+ * @returns {*} Returns the entry value.
*/
- function arrayExtremum(array, iteratee, comparator, exValue) {
- var index = -1,
- length = array.length,
- computed = exValue,
- result = computed;
+ function assocGet(array, key) {
+ var index = assocIndexOf(array, key);
+ return index < 0 ? undefined : array[index][1];
+ }
- while (++index < length) {
- var value = array[index],
- current = +iteratee(value);
+ /**
+ * Checks if an associative array value for `key` exists.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {string} key The key of the entry to check.
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+ */
+ function assocHas(array, key) {
+ return assocIndexOf(array, key) > -1;
+ }
- if (comparator(current, computed)) {
- computed = current;
- result = value;
+ /**
+ * Gets the index at which the first occurrence of `key` is found in `array`
+ * of key-value pairs.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} key The key to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function assocIndexOf(array, key) {
+ var length = array.length;
+ while (length--) {
+ if (eq(array[length][0], key)) {
+ return length;
}
}
- return result;
+ return -1;
}
/**
- * A specialized version of `_.filter` for arrays without support for callback
- * shorthands and `this` binding.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {Array} Returns the new filtered array.
- */
- function arrayFilter(array, predicate) {
- var index = -1,
- length = array.length,
- resIndex = -1,
- result = [];
-
- while (++index < length) {
- var value = array[index];
- if (predicate(value, index, array)) {
- result[++resIndex] = value;
- }
- }
- return result;
- }
-
- /**
- * A specialized version of `_.map` 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 {Array} Returns the new mapped array.
- */
- function arrayMap(array, iteratee) {
- var index = -1,
- length = array.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = iteratee(array[index], index, array);
- }
- return result;
- }
-
- /**
- * Appends the elements of `values` to `array`.
+ * Sets the associative array `key` to `value`.
*
* @private
* @param {Array} array The array to modify.
- * @param {Array} values The values to append.
- * @returns {Array} Returns `array`.
+ * @param {string} key The key of the value to set.
+ * @param {*} value The value to set.
*/
- function arrayPush(array, values) {
- var index = -1,
- length = values.length,
- offset = array.length;
-
- while (++index < length) {
- array[offset + index] = values[index];
+ function assocSet(array, key, value) {
+ var index = assocIndexOf(array, key);
+ if (index < 0) {
+ array.push([key, value]);
+ } else {
+ array[index][1] = value;
}
- return array;
}
+ /*------------------------------------------------------------------------*/
+
/**
- * A specialized version of `_.reduce` for arrays without support for callback
- * shorthands and `this` binding.
+ * Used by `_.defaults` to customize its `_.assignIn` use.
*
* @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {*} [accumulator] The initial value.
- * @param {boolean} [initFromArray] Specify using the first element of `array`
- * as the initial value.
- * @returns {*} Returns the accumulated value.
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to assign.
+ * @param {Object} object The parent object of `objValue`.
+ * @returns {*} Returns the value to assign.
*/
- function arrayReduce(array, iteratee, accumulator, initFromArray) {
- var index = -1,
- length = array.length;
-
- if (initFromArray && length) {
- accumulator = array[++index];
+ function assignInDefaults(objValue, srcValue, key, object) {
+ if (objValue === undefined ||
+ (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+ return srcValue;
}
- while (++index < length) {
- accumulator = iteratee(accumulator, array[index], index, array);
- }
- return accumulator;
+ return objValue;
}
/**
- * A specialized version of `_.reduceRight` for arrays without support for
- * callback shorthands and `this` binding.
+ * This function is like `assignValue` except that it doesn't assign `undefined` values.
*
* @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {*} [accumulator] The initial value.
- * @param {boolean} [initFromArray] Specify using the last element of `array`
- * as the initial value.
- * @returns {*} Returns the accumulated value.
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
*/
- function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
- var length = array.length;
- if (initFromArray && length) {
- accumulator = array[--length];
+ function assignMergeValue(object, key, value) {
+ if ((value !== undefined && !eq(object[key], value)) ||
+ (typeof key == 'number' && value === undefined && !(key in object))) {
+ object[key] = value;
}
- while (length--) {
- accumulator = iteratee(accumulator, array[length], length, array);
- }
- return accumulator;
}
/**
- * A specialized version of `_.some` for arrays without support for callback
- * shorthands and `this` binding.
+ * Assigns `value` to `key` of `object` if the existing value is not equivalent
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons.
*
* @private
- * @param {Array} array The array to iterate over.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
*/
- function arraySome(array, predicate) {
- var index = -1,
- length = array.length;
-
- while (++index < length) {
- if (predicate(array[index], index, array)) {
- return true;
- }
+ function assignValue(object, key, value) {
+ var objValue = object[key];
+ if ((!eq(objValue, value) ||
+ (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
+ (value === undefined && !(key in object))) {
+ object[key] = value;
}
- return false;
}
/**
- * 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, iteratee) {
- var length = array.length,
- result = 0;
-
- while (length--) {
- result += +iteratee(array[length]) || 0;
- }
- return result;
- }
-
- /**
- * Used by `_.defaults` to customize its `_.assign` 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 assignDefaults(objectValue, sourceValue) {
- return objectValue === undefined ? sourceValue : objectValue;
- }
-
- /**
- * Used by `_.template` to customize its `_.assign` use.
- *
- * **Note:** This function is like `assignDefaults` except that it ignores
- * inherited property values when checking if a property is `undefined`.
- *
- * @private
- * @param {*} objectValue The destination object property value.
- * @param {*} sourceValue The source object property value.
- * @param {string} key The key associated with the object and source values.
- * @param {Object} object The destination object.
- * @returns {*} Returns the value to assign to the destination object.
- */
- function assignOwnDefaults(objectValue, sourceValue, key, object) {
- return (objectValue === undefined || !hasOwnProperty.call(object, key))
- ? sourceValue
- : objectValue;
- }
-
- /**
- * A specialized version of `_.assign` for customizing assigned values without
- * support for argument juggling, multiple sources, and `this` binding `customizer`
- * functions.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {Function} customizer The function to customize assigned values.
- * @returns {Object} Returns `object`.
- */
- function assignWith(object, source, customizer) {
- var index = -1,
- props = keys(source),
- length = props.length;
-
- while (++index < length) {
- var key = props[index],
- value = object[key],
- result = customizer(value, source[key], key, object, source);
-
- if ((result === result ? (result !== value) : (value === value)) ||
- (value === undefined && !(key in object))) {
- object[key] = result;
- }
- }
- return object;
- }
-
- /**
- * The base implementation of `_.assign` without support for argument juggling,
- * multiple sources, and `customizer` functions.
+ * The base implementation of `_.assign` without support for multiple sources
+ * or `customizer` functions.
*
* @private
* @param {Object} object The destination object.
@@ -1583,107 +2124,67 @@
* @returns {Object} Returns `object`.
*/
function baseAssign(object, source) {
- return source == null
- ? object
- : baseCopy(source, keys(source), object);
+ return object && copyObject(source, keys(source), object);
}
/**
- * The base implementation of `_.at` without support for string collections
- * and individual key arguments.
+ * The base implementation of `_.at` without support for individual paths.
*
* @private
- * @param {Array|Object} collection The collection to iterate over.
- * @param {number[]|string[]} props The property names or indexes of elements to pick.
+ * @param {Object} object The object to iterate over.
+ * @param {string[]} paths The property paths of elements to pick.
* @returns {Array} Returns the new array of picked elements.
*/
- function baseAt(collection, props) {
+ function baseAt(object, paths) {
var index = -1,
- isNil = collection == null,
- isArr = !isNil && isArrayLike(collection),
- length = isArr ? collection.length : 0,
- propsLength = props.length,
- result = Array(propsLength);
+ isNil = object == null,
+ length = paths.length,
+ result = Array(length);
- while(++index < propsLength) {
- var key = props[index];
- if (isArr) {
- result[index] = isIndex(key, length) ? collection[key] : undefined;
- } else {
- result[index] = isNil ? undefined : collection[key];
- }
+ while (++index < length) {
+ result[index] = isNil ? undefined : get(object, paths[index]);
}
return result;
}
/**
- * Copies properties of `source` to `object`.
+ * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
*
* @private
- * @param {Object} source The object to copy properties from.
- * @param {Array} props The property names to copy.
- * @param {Object} [object={}] The object to copy properties to.
- * @returns {Object} Returns `object`.
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
*/
- function baseCopy(source, props, object) {
- object || (object = {});
-
- var index = -1,
- length = props.length;
-
- while (++index < length) {
- var key = props[index];
- object[key] = source[key];
+ function baseClamp(number, lower, upper) {
+ if (number === number) {
+ if (upper !== undefined) {
+ number = number <= upper ? number : upper;
+ }
+ if (lower !== undefined) {
+ number = number >= lower ? number : lower;
+ }
}
- return object;
+ return number;
}
/**
- * The base implementation of `_.callback` which supports specifying the
- * number of arguments to provide to `func`.
- *
- * @private
- * @param {*} [func=_.identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {number} [argCount] The number of arguments to provide to `func`.
- * @returns {Function} Returns the callback.
- */
- function baseCallback(func, thisArg, argCount) {
- var type = typeof func;
- if (type == 'function') {
- return thisArg === undefined
- ? func
- : bindCallback(func, thisArg, argCount);
- }
- if (func == null) {
- return identity;
- }
- if (type == 'object') {
- return baseMatches(func);
- }
- return thisArg === undefined
- ? property(func)
- : baseMatchesProperty(func, thisArg);
- }
-
- /**
- * The base implementation of `_.clone` without support for argument juggling
- * and `this` binding `customizer` functions.
+ * The base implementation of `_.clone` and `_.cloneDeep` which tracks
+ * traversed objects.
*
* @private
* @param {*} value The value to clone.
* @param {boolean} [isDeep] Specify a deep clone.
- * @param {Function} [customizer] The function to customize cloning values.
+ * @param {Function} [customizer] The function to customize cloning.
* @param {string} [key] The key of `value`.
- * @param {Object} [object] The object `value` belongs to.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates clones with source counterparts.
+ * @param {Object} [object] The parent object of `value`.
+ * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
* @returns {*} Returns the cloned value.
*/
- function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
+ function baseClone(value, isDeep, customizer, key, object, stack) {
var result;
if (customizer) {
- result = object ? customizer(value, key, object) : customizer(value);
+ result = object ? customizer(value, key, object, stack) : customizer(value);
}
if (result !== undefined) {
return result;
@@ -1695,16 +2196,19 @@
if (isArr) {
result = initCloneArray(value);
if (!isDeep) {
- return arrayCopy(value, result);
+ return copyArray(value, result);
}
} else {
- var tag = objToString.call(value),
- isFunc = tag == funcTag;
+ var tag = getTag(value),
+ isFunc = tag == funcTag || tag == genTag;
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+ if (isHostObject(value)) {
+ return object ? value : {};
+ }
result = initCloneObject(isFunc ? {} : value);
if (!isDeep) {
- return baseAssign(result, value);
+ return copySymbols(value, baseAssign(result, value));
}
} else {
return cloneableTags[tag]
@@ -1713,24 +2217,47 @@
}
}
// Check for circular references and return its corresponding clone.
- stackA || (stackA = []);
- stackB || (stackB = []);
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == value) {
- return stackB[length];
- }
+ stack || (stack = new Stack);
+ var stacked = stack.get(value);
+ if (stacked) {
+ return stacked;
}
- // Add the source value to the stack of traversed objects and associate it with its clone.
- stackA.push(value);
- stackB.push(result);
+ stack.set(value, result);
// Recursively populate clone (susceptible to call stack limits).
(isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
- result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
+ assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
});
- return result;
+ return isArr ? result : copySymbols(value, result);
+ }
+
+ /**
+ * The base implementation of `_.conforms` which doesn't clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {Function} Returns the new function.
+ */
+ function baseConforms(source) {
+ var props = keys(source),
+ length = props.length;
+
+ return function(object) {
+ if (object == null) {
+ return !length;
+ }
+ var index = length;
+ while (index--) {
+ var key = props[index],
+ predicate = source[key],
+ value = object[key];
+
+ if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
+ return false;
+ }
+ }
+ return true;
+ };
}
/**
@@ -1754,8 +2281,8 @@
}());
/**
- * The base implementation of `_.delay` and `_.defer` which accepts an index
- * of where to slice the arguments to provide to `func`.
+ * The base implementation of `_.delay` and `_.defer` which accepts an array
+ * of `func` arguments.
*
* @private
* @param {Function} func The function to delay.
@@ -1771,46 +2298,54 @@
}
/**
- * The base implementation of `_.difference` which accepts a single array
- * of values to exclude.
+ * The base implementation of methods like `_.difference` without support for
+ * excluding multiple arrays or iteratee shorthands.
*
* @private
* @param {Array} array The array to inspect.
* @param {Array} values The values to exclude.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
* @returns {Array} Returns the new array of filtered values.
*/
- function baseDifference(array, values) {
- var length = array ? array.length : 0,
- result = [];
+ function baseDifference(array, values, iteratee, comparator) {
+ var index = -1,
+ includes = arrayIncludes,
+ isCommon = true,
+ length = array.length,
+ result = [],
+ valuesLength = values.length;
if (!length) {
return result;
}
- var index = -1,
- indexOf = getIndexOf(),
- isCommon = indexOf === baseIndexOf,
- cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
- valuesLength = values.length;
-
- if (cache) {
- indexOf = cacheIndexOf;
+ if (iteratee) {
+ values = arrayMap(values, baseUnary(iteratee));
+ }
+ if (comparator) {
+ includes = arrayIncludesWith;
isCommon = false;
- values = cache;
+ }
+ else if (values.length >= LARGE_ARRAY_SIZE) {
+ includes = cacheHas;
+ isCommon = false;
+ values = new SetCache(values);
}
outer:
while (++index < length) {
- var value = array[index];
+ var value = array[index],
+ computed = iteratee ? iteratee(value) : value;
- if (isCommon && value === value) {
+ if (isCommon && computed === computed) {
var valuesIndex = valuesLength;
while (valuesIndex--) {
- if (values[valuesIndex] === value) {
+ if (values[valuesIndex] === computed) {
continue outer;
}
}
result.push(value);
}
- else if (indexOf(values, value, 0) < 0) {
+ else if (!includes(values, computed, comparator)) {
result.push(value);
}
}
@@ -1818,36 +2353,32 @@
}
/**
- * The base implementation of `_.forEach` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forEach` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
- * @returns {Array|Object|string} Returns `collection`.
+ * @returns {Array|Object} Returns `collection`.
*/
var baseEach = createBaseEach(baseForOwn);
/**
- * The base implementation of `_.forEachRight` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forEachRight` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
- * @returns {Array|Object|string} Returns `collection`.
+ * @returns {Array|Object} Returns `collection`.
*/
var baseEachRight = createBaseEach(baseForOwnRight, true);
/**
- * The base implementation of `_.every` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.every` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
*/
function baseEvery(collection, predicate) {
var result = true;
@@ -1858,32 +2389,6 @@
return result;
}
- /**
- * Gets the extremum value of `collection` invoking `iteratee` for each value
- * in `collection` to generate the criterion by which the value is ranked.
- * The `iteratee` is invoked with three arguments: (value, index|key, collection).
- *
- * @private
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {Function} comparator The function used to compare values.
- * @param {*} exValue The initial extremum value.
- * @returns {*} Returns the extremum value.
- */
- function baseExtremum(collection, iteratee, comparator, exValue) {
- var computed = exValue,
- result = computed;
-
- baseEach(collection, function(value, index, collection) {
- var current = +iteratee(value, index, collection);
- if (comparator(current, computed) || (current === exValue && current === result)) {
- computed = current;
- result = value;
- }
- });
- return result;
- }
-
/**
* The base implementation of `_.fill` without an iteratee call guard.
*
@@ -1897,29 +2402,26 @@
function baseFill(array, value, start, end) {
var length = array.length;
- start = start == null ? 0 : (+start || 0);
+ start = toInteger(start);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
- end = (end === undefined || end > length) ? length : (+end || 0);
+ end = (end === undefined || end > length) ? length : toInteger(end);
if (end < 0) {
end += length;
}
- length = start > end ? 0 : (end >>> 0);
- start >>>= 0;
-
- while (start < length) {
+ end = start > end ? 0 : toLength(end);
+ while (start < end) {
array[start++] = value;
}
return array;
}
/**
- * The base implementation of `_.filter` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.filter` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
*/
@@ -1934,32 +2436,7 @@
}
/**
- * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
- * without support for callback shorthands and `this` binding, which iterates
- * over `collection` using the provided `eachFunc`.
- *
- * @private
- * @param {Array|Object|string} collection The collection to search.
- * @param {Function} predicate The function invoked per iteration.
- * @param {Function} eachFunc The function to iterate over `collection`.
- * @param {boolean} [retKey] Specify returning the key of the found element
- * instead of the element itself.
- * @returns {*} Returns the found element or its key, else `undefined`.
- */
- function baseFind(collection, predicate, eachFunc, retKey) {
- var result;
- eachFunc(collection, function(value, key, collection) {
- if (predicate(value, key, collection)) {
- result = retKey ? key : value;
- return false;
- }
- });
- return result;
- }
-
- /**
- * The base implementation of `_.flatten` with added support for restricting
- * flattening and specifying the start index.
+ * The base implementation of `_.flatten` with support for restricting flattening.
*
* @private
* @param {Array} array The array to flatten.
@@ -1976,7 +2453,7 @@
while (++index < length) {
var value = array[index];
- if (isObjectLike(value) && isArrayLike(value) &&
+ if (isArrayLikeObject(value) &&
(isStrict || isArray(value) || isArguments(value))) {
if (isDeep) {
// Recursively flatten arrays (susceptible to call stack limits).
@@ -2018,8 +2495,7 @@
var baseForRight = createBaseFor(true);
/**
- * The base implementation of `_.forIn` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forIn` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to iterate over.
@@ -2027,12 +2503,11 @@
* @returns {Object} Returns `object`.
*/
function baseForIn(object, iteratee) {
- return baseFor(object, iteratee, keysIn);
+ return object == null ? object : baseFor(object, iteratee, keysIn);
}
/**
- * The base implementation of `_.forOwn` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to iterate over.
@@ -2040,12 +2515,11 @@
* @returns {Object} Returns `object`.
*/
function baseForOwn(object, iteratee) {
- return baseFor(object, iteratee, keys);
+ return object && baseFor(object, iteratee, keys);
}
/**
- * The base implementation of `_.forOwnRight` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to iterate over.
@@ -2053,7 +2527,7 @@
* @returns {Object} Returns `object`.
*/
function baseForOwnRight(object, iteratee) {
- return baseForRight(object, iteratee, keys);
+ return object && baseForRight(object, iteratee, keys);
}
/**
@@ -2066,37 +2540,22 @@
* @returns {Array} Returns the new array of filtered property names.
*/
function baseFunctions(object, props) {
- var index = -1,
- length = props.length,
- resIndex = -1,
- result = [];
-
- while (++index < length) {
- var key = props[index];
- if (isFunction(object[key])) {
- result[++resIndex] = key;
- }
- }
- return result;
+ return arrayFilter(props, function(key) {
+ return isFunction(object[key]);
+ });
}
/**
- * The base implementation of `get` without support for string paths
- * and default values.
+ * The base implementation of `_.get` without support for default values.
*
* @private
* @param {Object} object The object to query.
- * @param {Array} path The path of the property to get.
- * @param {string} [pathKey] The key representation of path.
+ * @param {Array|string} path The path of the property to get.
* @returns {*} Returns the resolved value.
*/
- function baseGet(object, path, pathKey) {
- if (object == null) {
- return;
- }
- if (pathKey !== undefined && pathKey in toObject(object)) {
- path = [pathKey];
- }
+ function baseGet(object, path) {
+ path = isKey(path, object) ? [path + ''] : baseToPath(path);
+
var index = 0,
length = path.length;
@@ -2107,26 +2566,144 @@
}
/**
- * The base implementation of `_.isEqual` without support for `this` binding
- * `customizer` functions.
+ * The base implementation of `_.has` without support for deep paths.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+ function baseHas(object, key) {
+ // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
+ // that are composed entirely of index properties, return `false` for
+ // `hasOwnProperty` checks of them.
+ return hasOwnProperty.call(object, key) ||
+ (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
+ }
+
+ /**
+ * The base implementation of `_.hasIn` without support for deep paths.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+ function baseHasIn(object, key) {
+ return key in Object(object);
+ }
+
+ /**
+ * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
+ *
+ * @private
+ * @param {number} number The number to check.
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
+ */
+ function baseInRange(number, start, end) {
+ return number >= nativeMin(start, end) && number < nativeMax(start, end);
+ }
+
+ /**
+ * The base implementation of methods like `_.intersection`, without support
+ * for iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ */
+ function baseIntersection(arrays, iteratee, comparator) {
+ var includes = comparator ? arrayIncludesWith : arrayIncludes,
+ othLength = arrays.length,
+ othIndex = othLength,
+ caches = Array(othLength),
+ result = [];
+
+ while (othIndex--) {
+ var array = arrays[othIndex];
+ if (othIndex && iteratee) {
+ array = arrayMap(array, baseUnary(iteratee));
+ }
+ caches[othIndex] = !comparator && (iteratee || array.length >= 120)
+ ? new SetCache(othIndex && array)
+ : undefined;
+ }
+ array = arrays[0];
+
+ var index = -1,
+ length = array.length,
+ seen = caches[0];
+
+ outer:
+ while (++index < length) {
+ var value = array[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) {
+ var othIndex = othLength;
+ while (--othIndex) {
+ var cache = caches[othIndex];
+ if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) {
+ continue outer;
+ }
+ }
+ if (seen) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.invoke` without support for individual
+ * method arguments.
+ *
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {Array} args The arguments to invoke the method with.
+ * @returns {*} Returns the result of the invoked method.
+ */
+ function baseInvoke(object, path, args) {
+ if (!isKey(path, object)) {
+ path = baseToPath(path);
+ object = parent(object, path);
+ path = last(path);
+ }
+ var func = object == null ? object : object[path];
+ return func == null ? undefined : apply(func, object, args);
+ }
+
+ /**
+ * The base implementation of `_.isEqual` which supports partial comparisons
+ * and tracks traversed objects.
*
* @private
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
- * @param {Function} [customizer] The function to customize comparing values.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
- * @param {Array} [stackA] Tracks traversed `value` objects.
- * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {boolean} [bitmask] The bitmask of comparison flags.
+ * The bitmask may be composed of the following flags:
+ * 1 - Unordered comparison
+ * 2 - Partial comparison
+ * @param {Object} [stack] Tracks traversed `value` and `other` objects.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
*/
- function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
+ function baseIsEqual(value, other, customizer, bitmask, stack) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
- return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
+ return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
}
/**
@@ -2138,20 +2715,19 @@
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} [customizer] The function to customize comparing objects.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
- * @param {Array} [stackA=[]] Tracks traversed `value` objects.
- * @param {Array} [stackB=[]] Tracks traversed `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+ function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
- objTag = objToString.call(object);
+ objTag = getTag(object);
if (objTag == argsTag) {
objTag = objectTag;
} else if (objTag != objectTag) {
@@ -2159,65 +2735,47 @@
}
}
if (!othIsArr) {
- othTag = objToString.call(other);
+ othTag = getTag(other);
if (othTag == argsTag) {
othTag = objectTag;
} else if (othTag != objectTag) {
othIsArr = isTypedArray(other);
}
}
- var objIsObj = objTag == objectTag,
- othIsObj = othTag == objectTag,
+ var objIsObj = objTag == objectTag && !isHostObject(object),
+ othIsObj = othTag == objectTag && !isHostObject(other),
isSameTag = objTag == othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
- return equalByTag(object, other, objTag);
+ return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
}
- if (!isLoose) {
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
+ if (!isPartial) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
- return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
+ return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
}
}
if (!isSameTag) {
return false;
}
- // Assume cyclic values are equal.
- // For more information on detecting circular references see https://es5.github.io/#JO.
- stackA || (stackA = []);
- stackB || (stackB = []);
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == object) {
- return stackB[length] == other;
- }
- }
- // Add `object` and `other` to the stack of traversed objects.
- stackA.push(object);
- stackB.push(other);
-
- var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
-
- stackA.pop();
- stackB.pop();
-
- return result;
+ stack || (stack = new Stack);
+ return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
}
/**
- * The base implementation of `_.isMatch` without support for callback
- * shorthands and `this` binding.
+ * The base implementation of `_.isMatch` without support for iteratee shorthands.
*
* @private
* @param {Object} object The object to inspect.
- * @param {Array} matchData The propery names, values, and compare flags to match.
- * @param {Function} [customizer] The function to customize comparing objects.
+ * @param {Object} source The object of property values to match.
+ * @param {Array} matchData The property names, values, and compare flags to match.
+ * @param {Function} [customizer] The function to customize comparisons.
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
*/
- function baseIsMatch(object, matchData, customizer) {
+ function baseIsMatch(object, source, matchData, customizer) {
var index = matchData.length,
length = index,
noCustomizer = !customizer;
@@ -2225,7 +2783,7 @@
if (object == null) {
return !length;
}
- object = toObject(object);
+ object = Object(object);
while (index--) {
var data = matchData[index];
if ((noCustomizer && data[2])
@@ -2246,8 +2804,10 @@
return false;
}
} else {
- var result = customizer ? customizer(objValue, srcValue, key) : undefined;
- if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
+ var stack = new Stack,
+ result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
+
+ if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) : result)) {
return false;
}
}
@@ -2256,11 +2816,71 @@
}
/**
- * The base implementation of `_.map` without support for callback shorthands
- * and `this` binding.
+ * The base implementation of `_.iteratee`.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {*} [value=_.identity] The value to convert to an iteratee.
+ * @returns {Function} Returns the iteratee.
+ */
+ function baseIteratee(value) {
+ var type = typeof value;
+ if (type == 'function') {
+ return value;
+ }
+ if (value == null) {
+ return identity;
+ }
+ if (type == 'object') {
+ return isArray(value)
+ ? baseMatchesProperty(value[0], value[1])
+ : baseMatches(value);
+ }
+ return property(value);
+ }
+
+ /**
+ * The base implementation of `_.keys` which doesn't skip the constructor
+ * property of prototypes or treat sparse arrays as dense.
+ *
+ * @private
+ * @type Function
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeys(object) {
+ return nativeKeys(Object(object));
+ }
+
+ /**
+ * The base implementation of `_.keysIn` which doesn't skip the constructor
+ * property of prototypes or treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeysIn(object) {
+ object = object == null ? object : Object(object);
+
+ var result = [];
+ for (var key in object) {
+ result.push(key);
+ }
+ return result;
+ }
+
+ // Fallback for IE < 9 with es6-shim.
+ if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
+ baseKeysIn = function(object) {
+ return iteratorToArray(enumerate(object));
+ };
+ }
+
+ /**
+ * The base implementation of `_.map` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
@@ -2275,7 +2895,7 @@
}
/**
- * The base implementation of `_.matches` which does not clone `source`.
+ * The base implementation of `_.matches` which doesn't clone `source`.
*
* @private
* @param {Object} source The object of property values to match.
@@ -2291,92 +2911,63 @@
if (object == null) {
return false;
}
- return object[key] === value && (value !== undefined || (key in toObject(object)));
+ return object[key] === value &&
+ (value !== undefined || (key in Object(object)));
};
}
return function(object) {
- return baseIsMatch(object, matchData);
+ return object === source || baseIsMatch(object, source, matchData);
};
}
/**
- * The base implementation of `_.matchesProperty` which does not clone `srcValue`.
+ * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
*
* @private
* @param {string} path The path of the property to get.
- * @param {*} srcValue The value to compare.
+ * @param {*} srcValue The value to match.
* @returns {Function} Returns the new function.
*/
function baseMatchesProperty(path, srcValue) {
- var isArr = isArray(path),
- isCommon = isKey(path) && isStrictComparable(srcValue),
- pathKey = (path + '');
-
- path = toPath(path);
return function(object) {
- if (object == null) {
- return false;
- }
- var key = pathKey;
- object = toObject(object);
- if ((isArr || !isCommon) && !(key in object)) {
- object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
- if (object == null) {
- return false;
- }
- key = last(path);
- object = toObject(object);
- }
- return object[key] === srcValue
- ? (srcValue !== undefined || (key in object))
- : baseIsEqual(srcValue, object[key], undefined, true);
+ var objValue = get(object, path);
+ return (objValue === undefined && objValue === srcValue)
+ ? hasIn(object, path)
+ : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
};
}
/**
- * The base implementation of `_.merge` without support for argument juggling,
- * multiple sources, and `this` binding `customizer` functions.
+ * The base implementation of `_.merge` without support for multiple sources.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @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`.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
- function baseMerge(object, source, customizer, stackA, stackB) {
- if (!isObject(object)) {
- return object;
+ function baseMerge(object, source, customizer, stack) {
+ if (object === source) {
+ return;
}
- var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
- props = isSrcArr ? undefined : keys(source);
-
+ var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source);
arrayEach(props || source, function(srcValue, key) {
if (props) {
key = srcValue;
srcValue = source[key];
}
- if (isObjectLike(srcValue)) {
- stackA || (stackA = []);
- stackB || (stackB = []);
- baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
+ if (isObject(srcValue)) {
+ stack || (stack = new Stack);
+ baseMergeDeep(object, source, key, baseMerge, customizer, stack);
}
else {
- var value = object[key],
- result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
- isCommon = result === undefined;
-
- if (isCommon) {
- result = srcValue;
- }
- if ((result !== undefined || (isSrcArr && !(key in object))) &&
- (isCommon || (result === result ? (result !== value) : (value === value)))) {
- object[key] = result;
+ var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
+ if (newValue === undefined) {
+ newValue = srcValue;
}
+ assignMergeValue(object, key, newValue);
}
});
- return object;
}
/**
@@ -2389,52 +2980,110 @@
* @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 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`.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
- function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
- var length = stackA.length,
- srcValue = source[key];
+ function baseMergeDeep(object, source, key, mergeFunc, customizer, stack) {
+ var objValue = object[key],
+ srcValue = source[key],
+ stacked = stack.get(srcValue) || stack.get(objValue);
- while (length--) {
- if (stackA[length] == srcValue) {
- object[key] = stackB[length];
- return;
- }
+ if (stacked) {
+ assignMergeValue(object, key, stacked);
+ return;
}
- var value = object[key],
- result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
- isCommon = result === undefined;
+ var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined,
+ isCommon = newValue === undefined;
if (isCommon) {
- result = srcValue;
- if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
- result = isArray(value)
- ? value
- : (isArrayLike(value) ? arrayCopy(value) : []);
+ newValue = srcValue;
+ if (isArray(srcValue) || isTypedArray(srcValue)) {
+ newValue = isArray(objValue)
+ ? objValue
+ : ((isArrayLikeObject(objValue)) ? copyArray(objValue) : baseClone(srcValue));
}
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
- result = isArguments(value)
- ? toPlainObject(value)
- : (isPlainObject(value) ? value : {});
+ newValue = isArguments(objValue)
+ ? toPlainObject(objValue)
+ : (isObject(objValue) ? objValue : baseClone(srcValue));
}
else {
- isCommon = false;
+ isCommon = isFunction(srcValue);
}
}
- // Add the source value to the stack of traversed objects and associate
- // it with its merged value.
- stackA.push(srcValue);
- stackB.push(result);
+ stack.set(srcValue, newValue);
if (isCommon) {
// Recursively merge objects and arrays (susceptible to call stack limits).
- object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
- } else if (result === result ? (result !== value) : (value === value)) {
- object[key] = result;
+ mergeFunc(newValue, srcValue, customizer, stack);
}
+ assignMergeValue(object, key, newValue);
+ }
+
+ /**
+ * The base implementation of `_.orderBy` without param guards.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
+ * @param {string[]} orders The sort orders of `iteratees`.
+ * @returns {Array} Returns the new sorted array.
+ */
+ function baseOrderBy(collection, iteratees, orders) {
+ var index = -1,
+ toIteratee = getIteratee();
+
+ iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
+ return toIteratee(iteratee);
+ });
+
+ var result = baseMap(collection, function(value, key, collection) {
+ var criteria = arrayMap(iteratees, function(iteratee) {
+ return iteratee(value);
+ });
+ return { 'criteria': criteria, 'index': ++index, 'value': value };
+ });
+
+ return baseSortBy(result, function(object, other) {
+ return compareMultiple(object, other, orders);
+ });
+ }
+
+ /**
+ * The base implementation of `_.pick` without support for individual
+ * property names.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {string[]} props The property names to pick.
+ * @returns {Object} Returns the new object.
+ */
+ function basePick(object, props) {
+ object = Object(object);
+ return arrayReduce(props, function(result, key) {
+ if (key in object) {
+ result[key] = object[key];
+ }
+ return result;
+ }, {});
+ }
+
+ /**
+ * The base implementation of `_.pickBy` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {Function} predicate The function invoked per property.
+ * @returns {Object} Returns the new object.
+ */
+ function basePickBy(object, predicate) {
+ var result = {};
+ baseForIn(object, function(value, key) {
+ if (predicate(value)) {
+ result[key] = value;
+ }
+ });
+ return result;
}
/**
@@ -2458,16 +3107,59 @@
* @returns {Function} Returns the new function.
*/
function basePropertyDeep(path) {
- var pathKey = (path + '');
- path = toPath(path);
return function(object) {
- return baseGet(object, path, pathKey);
+ return baseGet(object, path);
};
}
+ /**
+ * The base implementation of `_.pullAll`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @returns {Array} Returns `array`.
+ */
+ function basePullAll(array, values) {
+ return basePullAllBy(array, values);
+ }
+
+ /**
+ * The base implementation of `_.pullAllBy` without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns `array`.
+ */
+ function basePullAllBy(array, values, iteratee) {
+ var index = -1,
+ length = values.length,
+ seen = array;
+
+ if (iteratee) {
+ seen = arrayMap(array, function(value) { return iteratee(value); });
+ }
+ while (++index < length) {
+ var fromIndex = 0,
+ value = values[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
+ if (seen !== array) {
+ splice.call(seen, fromIndex, 1);
+ }
+ splice.call(array, fromIndex, 1);
+ }
+ }
+ return array;
+ }
+
/**
* The base implementation of `_.pullAt` without support for individual
- * index arguments and capturing the removed elements.
+ * indexes or capturing the removed elements.
*
* @private
* @param {Array} array The array to modify.
@@ -2475,51 +3167,102 @@
* @returns {Array} Returns `array`.
*/
function basePullAt(array, indexes) {
- var length = array ? indexes.length : 0;
+ var length = array ? indexes.length : 0,
+ lastIndex = length - 1;
+
while (length--) {
var index = indexes[length];
- if (index != previous && isIndex(index)) {
+ if (lastIndex == length || index != previous) {
var previous = index;
- splice.call(array, index, 1);
+ if (isIndex(index)) {
+ splice.call(array, index, 1);
+ }
+ else if (!isKey(index, array)) {
+ var path = baseToPath(index),
+ object = parent(array, path);
+
+ if (object != null) {
+ delete object[last(path)];
+ }
+ }
+ else {
+ delete array[index];
+ }
}
}
return array;
}
/**
- * The base implementation of `_.random` without support for argument juggling
- * and returning floating-point numbers.
+ * The base implementation of `_.random` without support for returning
+ * floating-point numbers.
*
* @private
- * @param {number} min The minimum possible value.
- * @param {number} max The maximum possible value.
+ * @param {number} lower The lower bound.
+ * @param {number} upper The upper bound.
* @returns {number} Returns the random number.
*/
- function baseRandom(min, max) {
- return min + nativeFloor(nativeRandom() * (max - min + 1));
+ function baseRandom(lower, upper) {
+ return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
}
/**
- * The base implementation of `_.reduce` and `_.reduceRight` without support
- * for callback shorthands and `this` binding, which iterates over `collection`
- * using the provided `eachFunc`.
+ * The base implementation of `_.range` and `_.rangeRight` which doesn't
+ * coerce arguments to numbers.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {*} accumulator The initial value.
- * @param {boolean} initFromCollection Specify using the first or last element
- * of `collection` as the initial value.
- * @param {Function} eachFunc The function to iterate over `collection`.
- * @returns {*} Returns the accumulated value.
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} step The value to increment or decrement by.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the new array of numbers.
*/
- function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
- eachFunc(collection, function(value, index, collection) {
- accumulator = initFromCollection
- ? (initFromCollection = false, value)
- : iteratee(accumulator, value, index, collection);
- });
- return accumulator;
+ function baseRange(start, end, step, fromRight) {
+ var index = -1,
+ length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
+ result = Array(length);
+
+ while (length--) {
+ result[fromRight ? length : ++index] = start;
+ start += step;
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.set`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize path creation.
+ * @returns {Object} Returns `object`.
+ */
+ function baseSet(object, path, value, customizer) {
+ path = isKey(path, object) ? [path + ''] : baseToPath(path);
+
+ var index = -1,
+ length = path.length,
+ lastIndex = length - 1,
+ nested = object;
+
+ while (nested != null && ++index < length) {
+ var key = path[index];
+ if (isObject(nested)) {
+ var newValue = value;
+ if (index != lastIndex) {
+ var objValue = nested[key];
+ newValue = customizer ? customizer(objValue, key, nested) : undefined;
+ if (newValue === undefined) {
+ newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue;
+ }
+ }
+ assignValue(nested, key, newValue);
+ }
+ nested = nested[key];
+ }
+ return object;
}
/**
@@ -2548,11 +3291,10 @@
var index = -1,
length = array.length;
- start = start == null ? 0 : (+start || 0);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
- end = (end === undefined || end > length) ? length : (+end || 0);
+ end = end > length ? length : end;
if (end < 0) {
end += length;
}
@@ -2567,14 +3309,12 @@
}
/**
- * The base implementation of `_.some` without support for callback shorthands
- * and `this` binding.
+ * The base implementation of `_.some` without support for iteratee shorthands.
*
* @private
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
*/
function baseSome(collection, predicate) {
var result;
@@ -2587,188 +3327,8 @@
}
/**
- * The base implementation of `_.sortBy` which uses `comparer` to define
- * the sort order of `array` and replaces criteria objects with their
- * corresponding values.
- *
- * @private
- * @param {Array} array The array to sort.
- * @param {Function} comparer The function to define sort order.
- * @returns {Array} Returns `array`.
- */
- function baseSortBy(array, comparer) {
- var length = array.length;
-
- array.sort(comparer);
- while (length--) {
- array[length] = array[length].value;
- }
- return array;
- }
-
- /**
- * The base implementation of `_.sortByOrder` without param guards.
- *
- * @private
- * @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`.
- * @returns {Array} Returns the new sorted array.
- */
- function baseSortByOrder(collection, iteratees, orders) {
- var callback = getCallback(),
- index = -1;
-
- iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); });
-
- var result = baseMap(collection, function(value) {
- var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); });
- return { 'criteria': criteria, 'index': ++index, 'value': value };
- });
-
- return baseSortBy(result, function(object, other) {
- return compareMultiple(object, other, orders);
- });
- }
-
- /**
- * The base implementation of `_.sum` without support for callback shorthands
- * and `this` binding.
- *
- * @private
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {number} Returns the sum.
- */
- function baseSum(collection, iteratee) {
- var result = 0;
- baseEach(collection, function(value, index, collection) {
- result += +iteratee(value, index, collection) || 0;
- });
- return result;
- }
-
- /**
- * The base implementation of `_.uniq` without support for callback shorthands
- * and `this` binding.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {Function} [iteratee] The function invoked per iteration.
- * @returns {Array} Returns the new duplicate free array.
- */
- function baseUniq(array, iteratee) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array.length,
- isCommon = indexOf === baseIndexOf,
- isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
- seen = isLarge ? createCache() : null,
- result = [];
-
- if (seen) {
- indexOf = cacheIndexOf;
- isCommon = false;
- } else {
- isLarge = false;
- seen = iteratee ? [] : result;
- }
- outer:
- while (++index < length) {
- var value = array[index],
- computed = iteratee ? iteratee(value, index, array) : value;
-
- if (isCommon && value === value) {
- var seenIndex = seen.length;
- while (seenIndex--) {
- if (seen[seenIndex] === computed) {
- continue outer;
- }
- }
- if (iteratee) {
- seen.push(computed);
- }
- result.push(value);
- }
- else if (indexOf(seen, computed, 0) < 0) {
- if (iteratee || isLarge) {
- seen.push(computed);
- }
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * The base implementation of `_.values` and `_.valuesIn` which creates an
- * array of `object` property values corresponding to the property names
- * of `props`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array} props The property names to get values for.
- * @returns {Object} Returns the array of property values.
- */
- function baseValues(object, props) {
- var index = -1,
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = object[props[index]];
- }
- return result;
- }
-
- /**
- * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`,
- * and `_.takeWhile` without support for callback shorthands and `this` binding.
- *
- * @private
- * @param {Array} array The array to query.
- * @param {Function} predicate The function invoked per iteration.
- * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Array} Returns the slice of `array`.
- */
- function baseWhile(array, predicate, isDrop, fromRight) {
- var length = array.length,
- index = fromRight ? length : -1;
-
- while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}
- return isDrop
- ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
- : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
- }
-
- /**
- * The base implementation of `wrapperValue` which returns the result of
- * performing a sequence of actions on the unwrapped `value`, where each
- * successive action is supplied the return value of the previous.
- *
- * @private
- * @param {*} value The unwrapped value.
- * @param {Array} actions Actions to peform to resolve the unwrapped value.
- * @returns {*} Returns the resolved value.
- */
- function baseWrapperValue(value, actions) {
- var result = value;
- if (result instanceof LazyWrapper) {
- result = result.value();
- }
- var index = -1,
- length = actions.length;
-
- while (++index < length) {
- var action = actions[index];
- result = action.func.apply(action.thisArg, arrayPush([result], action.args));
- }
- return result;
- }
-
- /**
- * Performs a binary search of `array` to determine the index at which `value`
+ * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
+ * performs a binary search of `array` to determine the index at which `value`
* should be inserted into `array` in order to maintain its sort order.
*
* @private
@@ -2778,7 +3338,7 @@
* @returns {number} Returns the index at which `value` should be inserted
* into `array`.
*/
- function binaryIndex(array, value, retHighest) {
+ function baseSortedIndex(array, value, retHighest) {
var low = 0,
high = array ? array.length : low;
@@ -2795,23 +3355,22 @@
}
return high;
}
- return binaryIndexBy(array, value, identity, retHighest);
+ return baseSortedIndexBy(array, value, identity, retHighest);
}
/**
- * This function is like `binaryIndex` except that it invokes `iteratee` for
- * `value` and each element of `array` to compute their sort ranking. The
- * iteratee is invoked with one argument; (value).
+ * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
+ * which invokes `iteratee` for `value` and each element of `array` to compute
+ * their sort ranking. The iteratee is invoked with one argument; (value).
*
* @private
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} iteratee The iteratee invoked per element.
* @param {boolean} [retHighest] Specify returning the highest qualified index.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
*/
- function binaryIndexBy(array, value, iteratee, retHighest) {
+ function baseSortedIndexBy(array, value, iteratee, retHighest) {
value = iteratee(value);
var low = 0,
@@ -2847,56 +3406,282 @@
}
/**
- * A specialized version of `baseCallback` which only supports `this` binding
- * and specifying the number of arguments to provide to `func`.
+ * The base implementation of `_.sortedUniq`.
*
* @private
- * @param {Function} func The function to bind.
- * @param {*} thisArg The `this` binding of `func`.
- * @param {number} [argCount] The number of arguments to provide to `func`.
- * @returns {Function} Returns the callback.
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
*/
- function bindCallback(func, thisArg, argCount) {
- if (typeof func != 'function') {
- return identity;
- }
- if (thisArg === undefined) {
- return func;
- }
- switch (argCount) {
- case 1: return function(value) {
- return func.call(thisArg, value);
- };
- case 3: return function(value, index, collection) {
- return func.call(thisArg, value, index, collection);
- };
- case 4: return function(accumulator, value, index, collection) {
- return func.call(thisArg, accumulator, value, index, collection);
- };
- case 5: return function(value, other, key, object, source) {
- return func.call(thisArg, value, other, key, object, source);
- };
- }
- return function() {
- return func.apply(thisArg, arguments);
- };
+ function baseSortedUniq(array) {
+ return baseSortedUniqBy(array);
}
/**
- * Creates a clone of the given array buffer.
+ * The base implementation of `_.sortedUniqBy` without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ */
+ function baseSortedUniqBy(array, iteratee) {
+ var index = 0,
+ length = array.length,
+ value = array[0],
+ computed = iteratee ? iteratee(value) : value,
+ seen = computed,
+ resIndex = 0,
+ result = [value];
+
+ while (++index < length) {
+ value = array[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ if (!eq(computed, seen)) {
+ seen = computed;
+ result[++resIndex] = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.toPath` which only converts `value` to a
+ * path if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Array} Returns the property path array.
+ */
+ function baseToPath(value) {
+ return isArray(value) ? value : stringToPath(value);
+ }
+
+ /**
+ * The base implementation of `_.uniqBy` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ */
+ function baseUniq(array, iteratee, comparator) {
+ var index = -1,
+ includes = arrayIncludes,
+ length = array.length,
+ isCommon = true,
+ result = [],
+ seen = result;
+
+ if (comparator) {
+ isCommon = false;
+ includes = arrayIncludesWith;
+ }
+ else if (length >= LARGE_ARRAY_SIZE) {
+ var set = iteratee ? null : createSet(array);
+ if (set) {
+ return setToArray(set);
+ }
+ isCommon = false;
+ includes = cacheHas;
+ seen = new SetCache;
+ }
+ else {
+ seen = iteratee ? [] : result;
+ }
+ outer:
+ while (++index < length) {
+ var value = array[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ if (isCommon && computed === computed) {
+ var seenIndex = seen.length;
+ while (seenIndex--) {
+ if (seen[seenIndex] === computed) {
+ continue outer;
+ }
+ }
+ if (iteratee) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ else if (!includes(seen, computed, comparator)) {
+ if (seen !== result) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.unset`.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+ */
+ function baseUnset(object, path) {
+ path = isKey(path, object) ? [path + ''] : baseToPath(path);
+ object = parent(object, path);
+ var key = last(path);
+ return (object != null && has(object, key)) ? delete object[key] : true;
+ }
+
+ /**
+ * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
+ * without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to query.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the slice of `array`.
+ */
+ function baseWhile(array, predicate, isDrop, fromRight) {
+ var length = array.length,
+ index = fromRight ? length : -1;
+
+ while ((fromRight ? index-- : ++index < length) &&
+ predicate(array[index], index, array)) {}
+
+ return isDrop
+ ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
+ : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
+ }
+
+ /**
+ * The base implementation of `wrapperValue` which returns the result of
+ * performing a sequence of actions on the unwrapped `value`, where each
+ * successive action is supplied the return value of the previous.
+ *
+ * @private
+ * @param {*} value The unwrapped value.
+ * @param {Array} actions Actions to perform to resolve the unwrapped value.
+ * @returns {*} Returns the resolved value.
+ */
+ function baseWrapperValue(value, actions) {
+ var result = value;
+ if (result instanceof LazyWrapper) {
+ result = result.value();
+ }
+ return arrayReduce(actions, function(result, action) {
+ return action.func.apply(action.thisArg, arrayPush([result], action.args));
+ }, result);
+ }
+
+ /**
+ * The base implementation of methods like `_.xor`, without support for
+ * iteratee shorthands, that accepts an array of arrays to inspect.
+ *
+ * @private
+ * @param {Array} arrays The arrays to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of values.
+ */
+ function baseXor(arrays, iteratee, comparator) {
+ var index = -1,
+ length = arrays.length;
+
+ while (++index < length) {
+ var result = result
+ ? arrayPush(
+ baseDifference(result, arrays[index], iteratee, comparator),
+ baseDifference(arrays[index], result, iteratee, comparator)
+ )
+ : arrays[index];
+ }
+ return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
+ }
+
+ /**
+ * Creates a clone of `buffer`.
*
* @private
* @param {ArrayBuffer} buffer The array buffer to clone.
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
- function bufferClone(buffer) {
- var result = new ArrayBuffer(buffer.byteLength),
+ function cloneBuffer(buffer) {
+ var Ctor = buffer.constructor,
+ result = new Ctor(buffer.byteLength),
view = new Uint8Array(result);
view.set(new Uint8Array(buffer));
return result;
}
+ /**
+ * Creates a clone of `map`.
+ *
+ * @private
+ * @param {Object} map The map to clone.
+ * @returns {Object} Returns the cloned map.
+ */
+ function cloneMap(map) {
+ var Ctor = map.constructor;
+ return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
+ }
+
+ /**
+ * Creates a clone of `regexp`.
+ *
+ * @private
+ * @param {Object} regexp The regexp to clone.
+ * @returns {Object} Returns the cloned regexp.
+ */
+ function cloneRegExp(regexp) {
+ var Ctor = regexp.constructor,
+ result = new Ctor(regexp.source, reFlags.exec(regexp));
+
+ result.lastIndex = regexp.lastIndex;
+ return result;
+ }
+
+ /**
+ * Creates a clone of `set`.
+ *
+ * @private
+ * @param {Object} set The set to clone.
+ * @returns {Object} Returns the cloned set.
+ */
+ function cloneSet(set) {
+ var Ctor = set.constructor;
+ return arrayReduce(setToArray(set), addSetEntry, new Ctor);
+ }
+
+ /**
+ * Creates a clone of the `symbol` object.
+ *
+ * @private
+ * @param {Object} symbol The symbol object to clone.
+ * @returns {Object} Returns the cloned symbol object.
+ */
+ function cloneSymbol(symbol) {
+ return _Symbol ? Object(symbolValueOf.call(symbol)) : {};
+ }
+
+ /**
+ * Creates a clone of `typedArray`.
+ *
+ * @private
+ * @param {Object} typedArray The typed array to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the cloned typed array.
+ */
+ function cloneTypedArray(typedArray, isDeep) {
+ var buffer = typedArray.buffer,
+ Ctor = typedArray.constructor;
+
+ return new Ctor(isDeep ? cloneBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
+ }
+
/**
* Creates an array that is the composition of partially applied arguments,
* placeholders, and provided arguments into a single array of arguments.
@@ -2960,7 +3745,77 @@
}
/**
- * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+ function copyArray(source, array) {
+ var index = -1,
+ length = source.length;
+
+ array || (array = Array(length));
+ while (++index < length) {
+ array[index] = source[index];
+ }
+ return array;
+ }
+
+ /**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @returns {Object} Returns `object`.
+ */
+ function copyObject(source, props, object) {
+ return copyObjectWith(source, props, object);
+ }
+
+ /**
+ * This function is like `copyObject` except that it accepts a function to
+ * customize copied values.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @param {Function} [customizer] The function to customize copied values.
+ * @returns {Object} Returns `object`.
+ */
+ function copyObjectWith(source, props, object, customizer) {
+ object || (object = {});
+
+ var index = -1,
+ length = props.length;
+
+ while (++index < length) {
+ var key = props[index],
+ newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
+
+ assignValue(object, key, newValue);
+ }
+ return object;
+ }
+
+ /**
+ * Copies own symbol properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy symbols from.
+ * @param {Object} [object={}] The object to copy symbols to.
+ * @returns {Object} Returns `object`.
+ */
+ function copySymbols(source, object) {
+ return copyObject(source, getSymbols(source), object);
+ }
+
+ /**
+ * Creates a function like `_.groupBy`.
*
* @private
* @param {Function} setter The function to set keys and values of the accumulator object.
@@ -2968,9 +3823,9 @@
* @returns {Function} Returns the new aggregator function.
*/
function createAggregator(setter, initializer) {
- return function(collection, iteratee, thisArg) {
+ return function(collection, iteratee) {
var result = initializer ? initializer() : {};
- iteratee = getCallback(iteratee, thisArg, 3);
+ iteratee = getIteratee(iteratee);
if (isArray(collection)) {
var index = -1,
@@ -2978,11 +3833,11 @@
while (++index < length) {
var value = collection[index];
- setter(result, value, iteratee(value, index, collection), collection);
+ setter(result, value, iteratee(value), collection);
}
} else {
baseEach(collection, function(value, key, collection) {
- setter(result, value, iteratee(value, key, collection), collection);
+ setter(result, value, iteratee(value), collection);
});
}
return result;
@@ -2990,31 +3845,25 @@
}
/**
- * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
+ * Creates a function like `_.assign`.
*
* @private
* @param {Function} assigner The function to assign values.
* @returns {Function} Returns the new assigner function.
*/
function createAssigner(assigner) {
- return restParam(function(object, sources) {
+ return rest(function(object, sources) {
var index = -1,
- length = object == null ? 0 : sources.length,
- customizer = length > 2 ? sources[length - 2] : undefined,
- guard = length > 2 ? sources[2] : undefined,
- thisArg = length > 1 ? sources[length - 1] : undefined;
+ length = sources.length,
+ customizer = length > 1 ? sources[length - 1] : undefined,
+ guard = length > 2 ? sources[2] : undefined;
- if (typeof customizer == 'function') {
- customizer = bindCallback(customizer, thisArg, 5);
- length -= 2;
- } else {
- customizer = typeof thisArg == 'function' ? thisArg : undefined;
- length -= (customizer ? 1 : 0);
- }
+ customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
customizer = length < 3 ? undefined : customizer;
length = 1;
}
+ object = Object(object);
while (++index < length) {
var source = sources[index];
if (source) {
@@ -3035,12 +3884,15 @@
*/
function createBaseEach(eachFunc, fromRight) {
return function(collection, iteratee) {
- var length = collection ? getLength(collection) : 0;
- if (!isLength(length)) {
+ if (collection == null) {
+ return collection;
+ }
+ if (!isArrayLike(collection)) {
return eachFunc(collection, iteratee);
}
- var index = fromRight ? length : -1,
- iterable = toObject(collection);
+ var length = collection.length,
+ index = fromRight ? length : -1,
+ iterable = Object(collection);
while ((fromRight ? index-- : ++index < length)) {
if (iteratee(iterable[index], index, iterable) === false) {
@@ -3052,7 +3904,7 @@
}
/**
- * Creates a base function for `_.forIn` or `_.forInRight`.
+ * Creates a base function for methods like `_.forIn`.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
@@ -3060,13 +3912,13 @@
*/
function createBaseFor(fromRight) {
return function(object, iteratee, keysFunc) {
- var iterable = toObject(object),
+ var index = -1,
+ iterable = Object(object),
props = keysFunc(object),
- length = props.length,
- index = fromRight ? length : -1;
+ length = props.length;
- while ((fromRight ? index-- : ++index < length)) {
- var key = props[index];
+ while (length--) {
+ var key = props[fromRight ? length : ++index];
if (iteratee(iterable[key], key, iterable) === false) {
break;
}
@@ -3076,38 +3928,47 @@
}
/**
- * Creates a function that wraps `func` and invokes it with the `this`
+ * Creates a function that wraps `func` to invoke it with the optional `this`
* binding of `thisArg`.
*
* @private
- * @param {Function} func The function to bind.
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
- * @returns {Function} Returns the new bound function.
+ * @returns {Function} Returns the new wrapped function.
*/
- function createBindWrapper(func, thisArg) {
- var Ctor = createCtorWrapper(func);
+ function createBaseWrapper(func, bitmask, thisArg) {
+ var isBind = bitmask & BIND_FLAG,
+ Ctor = createCtorWrapper(func);
function wrapper() {
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
- return fn.apply(thisArg, arguments);
+ return fn.apply(isBind ? thisArg : this, arguments);
}
return wrapper;
}
/**
- * Creates a `Set` cache object to optimize linear searches of large arrays.
+ * Creates a function like `_.lowerFirst`.
*
* @private
- * @param {Array} [values] The values to cache.
- * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.
+ * @param {string} methodName The name of the `String` case method to use.
+ * @returns {Function} Returns the new function.
*/
- function createCache(values) {
- return (nativeCreate && Set) ? new SetCache(values) : null;
+ function createCaseFirst(methodName) {
+ return function(string) {
+ string = toString(string);
+
+ var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined,
+ chr = strSymbols ? strSymbols[0] : string.charAt(0),
+ trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
+
+ return chr[methodName]() + trailing;
+ };
}
/**
- * Creates a function that produces compound words out of the words in a
- * given string.
+ * Creates a function like `_.camelCase`.
*
* @private
* @param {Function} callback The function to combine each word.
@@ -3115,15 +3976,7 @@
*/
function createCompounder(callback) {
return function(string) {
- var index = -1,
- array = words(deburr(string)),
- length = array.length,
- result = '';
-
- while (++index < length) {
- result = callback(result, array[index], index);
- }
- return result;
+ return arrayReduce(words(deburr(string)), callback, '');
};
}
@@ -3161,116 +4014,37 @@
}
/**
- * Creates a `_.curry` or `_.curryRight` function.
+ * Creates a function that wraps `func` to enable currying.
*
* @private
- * @param {boolean} flag The curry bit flag.
- * @returns {Function} Returns the new curry function.
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
+ * @param {number} arity The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
*/
- function createCurry(flag) {
- function curryFunc(func, arity, guard) {
- if (guard && isIterateeCall(func, arity, guard)) {
- arity = undefined;
+ function createCurryWrapper(func, bitmask, arity) {
+ var Ctor = createCtorWrapper(func);
+
+ function wrapper() {
+ var length = arguments.length,
+ index = length,
+ args = Array(length),
+ fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
+ placeholder = wrapper.placeholder;
+
+ while (index--) {
+ args[index] = arguments[index];
}
- var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);
- result.placeholder = curryFunc.placeholder;
- return result;
+ var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
+ ? []
+ : replaceHolders(args, placeholder);
+
+ length -= holders.length;
+ return length < arity
+ ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
+ : apply(fn, this, args);
}
- 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.
- *
- * @private
- * @param {Function} comparator The function used to compare values.
- * @param {*} exValue The initial extremum value.
- * @returns {Function} Returns the new extremum function.
- */
- function createExtremum(comparator, exValue) {
- return function(collection, iteratee, thisArg) {
- if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = undefined;
- }
- iteratee = getCallback(iteratee, thisArg, 3);
- if (iteratee.length == 1) {
- collection = isArray(collection) ? collection : toIterable(collection);
- var result = arrayExtremum(collection, iteratee, comparator, exValue);
- if (!(collection.length && result === exValue)) {
- return result;
- }
- }
- return baseExtremum(collection, iteratee, comparator, exValue);
- };
- }
-
- /**
- * Creates a `_.find` or `_.findLast` function.
- *
- * @private
- * @param {Function} eachFunc The function to iterate over a collection.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new find function.
- */
- function createFind(eachFunc, fromRight) {
- return function(collection, predicate, thisArg) {
- predicate = getCallback(predicate, thisArg, 3);
- if (isArray(collection)) {
- var index = baseFindIndex(collection, predicate, fromRight);
- return index > -1 ? collection[index] : undefined;
- }
- return baseFind(collection, predicate, eachFunc);
- };
- }
-
- /**
- * Creates a `_.findIndex` or `_.findLastIndex` function.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new find function.
- */
- function createFindIndex(fromRight) {
- return function(array, predicate, thisArg) {
- if (!(array && array.length)) {
- return -1;
- }
- predicate = getCallback(predicate, thisArg, 3);
- return baseFindIndex(array, predicate, fromRight);
- };
- }
-
- /**
- * Creates a `_.findKey` or `_.findLastKey` function.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new find function.
- */
- function createFindKey(objectFunc) {
- return function(object, predicate, thisArg) {
- predicate = getCallback(predicate, thisArg, 3);
- return baseFind(object, predicate, objectFunc, true);
- };
+ return wrapper;
}
/**
@@ -3281,23 +4055,26 @@
* @returns {Function} Returns the new flow function.
*/
function createFlow(fromRight) {
- return function() {
- var wrapper,
- length = arguments.length,
- index = fromRight ? length : -1,
- leftIndex = 0,
- funcs = Array(length);
+ return rest(function(funcs) {
+ funcs = baseFlatten(funcs);
- while ((fromRight ? index-- : ++index < length)) {
- var func = funcs[leftIndex++] = arguments[index];
+ var length = funcs.length,
+ index = length,
+ prereq = LodashWrapper.prototype.thru;
+
+ if (fromRight) {
+ funcs.reverse();
+ }
+ while (index--) {
+ var func = funcs[index];
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {
- wrapper = new LodashWrapper([], true);
+ if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
+ var wrapper = new LodashWrapper([], true);
}
}
- index = wrapper ? -1 : length;
+ index = wrapper ? index : length;
while (++index < length) {
func = funcs[index];
@@ -3325,132 +4102,16 @@
}
return result;
};
- };
- }
-
- /**
- * Creates a function for `_.forEach` or `_.forEachRight`.
- *
- * @private
- * @param {Function} arrayFunc The function to iterate over an array.
- * @param {Function} eachFunc The function to iterate over a collection.
- * @returns {Function} Returns the new each function.
- */
- function createForEach(arrayFunc, eachFunc) {
- return function(collection, iteratee, thisArg) {
- return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
- ? arrayFunc(collection, iteratee)
- : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
- };
- }
-
- /**
- * Creates a function for `_.forIn` or `_.forInRight`.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new each function.
- */
- function createForIn(objectFunc) {
- return function(object, iteratee, thisArg) {
- if (typeof iteratee != 'function' || thisArg !== undefined) {
- iteratee = bindCallback(iteratee, thisArg, 3);
- }
- return objectFunc(object, iteratee, keysIn);
- };
- }
-
- /**
- * Creates a function for `_.forOwn` or `_.forOwnRight`.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new each function.
- */
- function createForOwn(objectFunc) {
- return function(object, iteratee, thisArg) {
- if (typeof iteratee != 'function' || thisArg !== undefined) {
- iteratee = bindCallback(iteratee, thisArg, 3);
- }
- return objectFunc(object, iteratee);
- };
- }
-
- /**
- * Creates a function for `_.mapKeys` or `_.mapValues`.
- *
- * @private
- * @param {boolean} [isMapKeys] Specify mapping keys instead of values.
- * @returns {Function} Returns the new map function.
- */
- function createObjectMapper(isMapKeys) {
- return function(object, iteratee, thisArg) {
- var result = {};
- iteratee = getCallback(iteratee, thisArg, 3);
-
- baseForOwn(object, function(value, key, object) {
- var mapped = iteratee(value, key, object);
- key = isMapKeys ? mapped : key;
- value = isMapKeys ? value : mapped;
- result[key] = value;
- });
- return result;
- };
- }
-
- /**
- * Creates a function for `_.padLeft` or `_.padRight`.
- *
- * @private
- * @param {boolean} [fromRight] Specify padding from the right.
- * @returns {Function} Returns the new pad function.
- */
- function createPadDir(fromRight) {
- return function(string, length, chars) {
- string = baseToString(string);
- return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string);
- };
- }
-
- /**
- * Creates a `_.partial` or `_.partialRight` function.
- *
- * @private
- * @param {boolean} flag The partial bit flag.
- * @returns {Function} Returns the new partial function.
- */
- function createPartial(flag) {
- var partialFunc = restParam(function(func, partials) {
- var holders = replaceHolders(partials, partialFunc.placeholder);
- return createWrapper(func, flag, undefined, partials, holders);
});
- return partialFunc;
}
/**
- * Creates a function for `_.reduce` or `_.reduceRight`.
+ * Creates a function that wraps `func` to invoke it with optional `this`
+ * binding of `thisArg`, partial application, and currying.
*
* @private
- * @param {Function} arrayFunc The function to iterate over an array.
- * @param {Function} eachFunc The function to iterate over a collection.
- * @returns {Function} Returns the new each function.
- */
- function createReduce(arrayFunc, eachFunc) {
- return function(collection, iteratee, accumulator, thisArg) {
- var initFromArray = arguments.length < 3;
- return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
- ? arrayFunc(collection, iteratee, accumulator, initFromArray)
- : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);
- };
- }
-
- /**
- * Creates a function that wraps `func` and invokes it with optional `this`
- * binding of, partial application, and currying.
- *
- * @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
+ * @param {Function|string} func The function or method name to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to prepend to those provided to the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
@@ -3466,13 +4127,11 @@
isBind = bitmask & BIND_FLAG,
isBindKey = bitmask & BIND_KEY_FLAG,
isCurry = bitmask & CURRY_FLAG,
- isCurryBound = bitmask & CURRY_BOUND_FLAG,
isCurryRight = bitmask & CURRY_RIGHT_FLAG,
+ isFlip = bitmask & FLIP_FLAG,
Ctor = isBindKey ? undefined : createCtorWrapper(func);
function wrapper() {
- // Avoid `arguments` object use disqualifying optimizations by
- // converting it to an array before providing it to other functions.
var length = arguments.length,
index = length,
args = Array(length);
@@ -3492,27 +4151,7 @@
length -= argsHolders.length;
if (length < arity) {
- var newArgPos = argPos ? arrayCopy(argPos) : undefined,
- newArity = nativeMax(arity - length, 0),
- 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);
-
- if (!isCurryBound) {
- bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
- }
- var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
- result = createHybridWrapper.apply(undefined, newData);
-
- if (isLaziable(func)) {
- setData(result, newData);
- }
- result.placeholder = placeholder;
- return result;
+ return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
}
}
var thisBinding = isBind ? thisArg : this,
@@ -3520,12 +4159,14 @@
if (argPos) {
args = reorder(args, argPos);
+ } else if (isFlip && args.length > 1) {
+ args.reverse();
}
if (isAry && ary < args.length) {
args.length = ary;
}
if (this && this !== root && this instanceof wrapper) {
- fn = Ctor || createCtorWrapper(func);
+ fn = Ctor || createCtorWrapper(fn);
}
return fn.apply(thisBinding, args);
}
@@ -3533,51 +4174,73 @@
}
/**
- * Creates the padding required for `string` based on the given `length`.
- * The `chars` string is truncated if the number of characters exceeds `length`.
+ * Creates a function like `_.over`.
+ *
+ * @private
+ * @param {Function} arrayFunc The function to iterate over iteratees.
+ * @returns {Function} Returns the new invoker function.
+ */
+ function createOver(arrayFunc) {
+ return rest(function(iteratees) {
+ iteratees = arrayMap(baseFlatten(iteratees), getIteratee());
+ return rest(function(args) {
+ var thisArg = this;
+ return arrayFunc(iteratees, function(iteratee) {
+ return apply(iteratee, thisArg, args);
+ });
+ });
+ });
+ }
+
+ /**
+ * Creates the padding for `string` based on `length`. The `chars` string
+ * is truncated if the number of characters exceeds `length`.
*
* @private
* @param {string} string The string to create padding for.
* @param {number} [length=0] The padding length.
* @param {string} [chars=' '] The string used as padding.
- * @returns {string} Returns the pad for `string`.
+ * @returns {string} Returns the padding for `string`.
*/
function createPadding(string, length, chars) {
- var strLength = string.length;
- length = +length;
+ length = toInteger(length);
- if (strLength >= length || !nativeIsFinite(length)) {
+ var strLength = stringSize(string);
+ if (!length || strLength >= length) {
return '';
}
var padLength = length - strLength;
- chars = chars == null ? ' ' : (chars + '');
- return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);
+ chars = chars === undefined ? ' ' : (chars + '');
+
+ var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
+ return reHasComplexSymbol.test(chars)
+ ? stringToArray(result).slice(0, padLength).join('')
+ : result.slice(0, padLength);
}
/**
- * Creates a function that wraps `func` and invokes it with the optional `this`
+ * Creates a function that wraps `func` to invoke it with the optional `this`
* binding of `thisArg` and the `partials` prepended to those provided to
* the wrapper.
*
* @private
- * @param {Function} func The function to partially apply arguments to.
- * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} partials The arguments to prepend to those provided to the new function.
- * @returns {Function} Returns the new bound function.
+ * @returns {Function} Returns the new wrapped function.
*/
function createPartialWrapper(func, bitmask, thisArg, partials) {
var isBind = bitmask & BIND_FLAG,
Ctor = createCtorWrapper(func);
function wrapper() {
- // Avoid `arguments` object use disqualifying optimizations by
- // converting it to an array before providing it `func`.
var argsIndex = -1,
argsLength = arguments.length,
leftIndex = -1,
leftLength = partials.length,
- args = Array(leftLength + argsLength);
+ args = Array(leftLength + argsLength),
+ fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
while (++leftIndex < leftLength) {
args[leftIndex] = partials[leftIndex];
@@ -3585,14 +4248,79 @@
while (argsLength--) {
args[leftIndex++] = arguments[++argsIndex];
}
- var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
- return fn.apply(isBind ? thisArg : this, args);
+ return apply(fn, isBind ? thisArg : this, args);
}
return wrapper;
}
/**
- * Creates a `_.ceil`, `_.floor`, or `_.round` function.
+ * Creates a `_.range` or `_.rangeRight` function.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new range function.
+ */
+ function createRange(fromRight) {
+ return function(start, end, step) {
+ if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
+ end = step = undefined;
+ }
+ // Ensure the sign of `-0` is preserved.
+ start = toNumber(start);
+ start = start === start ? start : 0;
+ if (end === undefined) {
+ end = start;
+ start = 0;
+ } else {
+ end = toNumber(end) || 0;
+ }
+ step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
+ return baseRange(start, end, step, fromRight);
+ };
+ }
+
+ /**
+ * Creates a function that wraps `func` to continue currying.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
+ * @param {Function} wrapFunc The function to create the `func` wrapper.
+ * @param {*} placeholder The placeholder to replace.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to prepend to those provided to the new function.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
+ var isCurry = bitmask & CURRY_FLAG,
+ newArgPos = argPos ? copyArray(argPos) : undefined,
+ newsHolders = isCurry ? holders : undefined,
+ newHoldersRight = isCurry ? undefined : holders,
+ newPartials = isCurry ? partials : undefined,
+ newPartialsRight = isCurry ? undefined : partials;
+
+ bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
+ bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
+
+ if (!(bitmask & CURRY_BOUND_FLAG)) {
+ bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
+ }
+ var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity],
+ result = wrapFunc.apply(undefined, newData);
+
+ if (isLaziable(func)) {
+ setData(result, newData);
+ }
+ result.placeholder = placeholder;
+ return result;
+ }
+
+ /**
+ * Creates a function like `_.round`.
*
* @private
* @param {string} methodName The name of the `Math` method to use when rounding.
@@ -3601,38 +4329,39 @@
function createRound(methodName) {
var func = Math[methodName];
return function(number, precision) {
- precision = precision === undefined ? 0 : (+precision || 0);
+ number = toNumber(number);
+ precision = toInteger(precision);
if (precision) {
- precision = pow(10, precision);
- return func(number * precision) / precision;
+ // Shift with exponential notation to avoid floating-point issues.
+ // See [MDN](https://mdn.io/round#Examples) for more details.
+ var pair = (toString(number) + 'e').split('e'),
+ value = func(pair[0] + 'e' + (+pair[1] + precision));
+
+ pair = (toString(value) + 'e').split('e');
+ return +(pair[0] + 'e' + (+pair[1] - precision));
}
return func(number);
};
}
/**
- * Creates a `_.sortedIndex` or `_.sortedLastIndex` function.
+ * Creates a set of `values`.
*
* @private
- * @param {boolean} [retHighest] Specify returning the highest qualified index.
- * @returns {Function} Returns the new index function.
+ * @param {Array} values The values to add to the set.
+ * @returns {Object} Returns the new set.
*/
- function createSortedIndex(retHighest) {
- return function(array, value, iteratee, thisArg) {
- var callback = getCallback(iteratee);
- return (iteratee == null && callback === baseCallback)
- ? binaryIndex(array, value, retHighest)
- : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest);
- };
- }
+ var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
+ return new Set(values);
+ };
/**
* Creates a function that either curries or invokes `func` with optional
* `this` binding and partially applied arguments.
*
* @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of flags.
+ * @param {Function|string} func The function or method name to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags.
* The bitmask may be composed of the following flags:
* 1 - `_.bind`
* 2 - `_.bindKey`
@@ -3661,7 +4390,10 @@
bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
partials = holders = undefined;
}
- length -= (holders ? holders.length : 0);
+ ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
+ arity = arity === undefined ? arity : toInteger(arity);
+ length -= holders ? holders.length : 0;
+
if (bitmask & PARTIAL_RIGHT_FLAG) {
var partialsRight = partials,
holdersRight = holders;
@@ -3673,17 +4405,25 @@
if (data) {
mergeData(newData, data);
- bitmask = newData[1];
- arity = newData[9];
}
- newData[9] = arity == null
+ func = newData[0];
+ bitmask = newData[1];
+ thisArg = newData[2];
+ partials = newData[3];
+ holders = newData[4];
+ arity = newData[9] = newData[9] == null
? (isBindKey ? 0 : func.length)
- : (nativeMax(arity - length, 0) || 0);
+ : nativeMax(newData[9] - length, 0);
- if (bitmask == BIND_FLAG) {
- var result = createBindWrapper(newData[0], newData[2]);
- } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
- result = createPartialWrapper.apply(undefined, newData);
+ if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
+ bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
+ }
+ if (!bitmask || bitmask == BIND_FLAG) {
+ var result = createBaseWrapper(func, bitmask, thisArg);
+ } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
+ result = createCurryWrapper(func, bitmask, arity);
+ } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
+ result = createPartialWrapper(func, bitmask, thisArg, partials);
} else {
result = createHybridWrapper.apply(undefined, newData);
}
@@ -3699,44 +4439,61 @@
* @param {Array} array The array to compare.
* @param {Array} other The other array to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} [customizer] The function to customize comparing arrays.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
- * @param {Array} [stackA] Tracks traversed `value` objects.
- * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `array` and `other` objects.
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
*/
- function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
+ function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
var index = -1,
+ isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+ isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
arrLength = array.length,
othLength = other.length;
- if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
+ if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
return false;
}
+ // Assume cyclic values are equal.
+ var stacked = stack.get(array);
+ if (stacked) {
+ return stacked == other;
+ }
+ var result = true;
+ stack.set(array, other);
+
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
- othValue = other[index],
- result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
+ othValue = other[index];
- if (result !== undefined) {
- if (result) {
+ if (customizer) {
+ var compared = isPartial
+ ? customizer(othValue, arrValue, index, other, array, stack)
+ : customizer(arrValue, othValue, index, array, other, stack);
+ }
+ if (compared !== undefined) {
+ if (compared) {
continue;
}
- return false;
+ result = false;
+ break;
}
// Recursively compare arrays (susceptible to call stack limits).
- if (isLoose) {
+ if (isUnordered) {
if (!arraySome(other, function(othValue) {
- return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
+ return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
})) {
- return false;
+ result = false;
+ break;
}
- } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
- return false;
+ } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
+ result = false;
+ break;
}
}
- return true;
+ stack['delete'](array);
+ return result;
}
/**
@@ -3750,10 +4507,20 @@
* @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.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function equalByTag(object, other, tag) {
+ function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
switch (tag) {
+ case arrayBufferTag:
+ if ((object.byteLength != other.byteLength) ||
+ !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
+ return false;
+ }
+ return true;
+
case boolTag:
case dateTag:
// Coerce dates and booleans to numbers, dates to milliseconds and booleans
@@ -3765,15 +4532,27 @@
case numberTag:
// Treat `NaN` vs. `NaN` as equal.
- return (object != +object)
- ? other != +other
- : object == +other;
+ return (object != +object) ? other != +other : object == +other;
case regexpTag:
case stringTag:
// Coerce regexes to strings and treat strings primitives and string
// objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
return object == (other + '');
+
+ case mapTag:
+ var convert = mapToArray;
+
+ case setTag:
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
+ convert || (convert = setToArray);
+
+ // Recursively compare objects (susceptible to call stack limits).
+ return (isPartial || object.size == other.size) &&
+ equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
+
+ case symbolTag:
+ return !!_Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
}
return false;
}
@@ -3786,42 +4565,60 @@
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
- * @param {Function} [customizer] The function to customize comparing values.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
- * @param {Array} [stackA] Tracks traversed `value` objects.
- * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
- var objProps = keys(object),
+ function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+ isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
+ objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
- if (objLength != othLength && !isLoose) {
+ if (objLength != othLength && !isPartial) {
return false;
}
var index = objLength;
while (index--) {
var key = objProps[index];
- if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
+ if (!(isPartial ? key in other : baseHas(other, key)) ||
+ !(isUnordered || key == othProps[index])) {
return false;
}
}
- var skipCtor = isLoose;
+ // Assume cyclic values are equal.
+ var stacked = stack.get(object);
+ if (stacked) {
+ return stacked == other;
+ }
+ var result = true;
+ stack.set(object, other);
+
+ var skipCtor = isPartial;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
- othValue = other[key],
- result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;
+ othValue = other[key];
+ if (customizer) {
+ var compared = isPartial
+ ? customizer(othValue, objValue, key, other, object, stack)
+ : customizer(objValue, othValue, key, object, other, stack);
+ }
// Recursively compare objects (susceptible to call stack limits).
- if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
- return false;
+ if (!(compared === undefined
+ ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
+ : compared
+ )) {
+ result = false;
+ break;
}
skipCtor || (skipCtor = key == 'constructor');
}
- if (!skipCtor) {
+ if (result && !skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
@@ -3830,25 +4627,11 @@
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
- return false;
+ result = false;
}
}
- return true;
- }
-
- /**
- * Gets the appropriate "callback" function. If the `_.callback` method is
- * customized this function returns the custom method, otherwise it returns
- * the `baseCallback` function. If arguments are provided the chosen function
- * is invoked with them and its result is returned.
- *
- * @private
- * @returns {Function} Returns the chosen function or its result.
- */
- function getCallback(func, thisArg, argCount) {
- var result = lodash.callback || callback;
- result = result === callback ? baseCallback : result;
- return argCount ? result(func, thisArg, argCount) : result;
+ stack['delete'](object);
+ return result;
}
/**
@@ -3885,18 +4668,20 @@
}
/**
- * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
+ * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
* customized this function returns the custom method, otherwise it returns
- * the `baseIndexOf` function. If arguments are provided the chosen function
- * is invoked with them and its result is returned.
+ * `baseIteratee`. If arguments are provided the chosen function is invoked
+ * with them and its result is returned.
*
* @private
- * @returns {Function|number} Returns the chosen function or its result.
+ * @param {*} [value] The value to convert to an iteratee.
+ * @param {number} [arity] The arity of the created iteratee.
+ * @returns {Function} Returns the chosen function or its result.
*/
- function getIndexOf(collection, target, fromIndex) {
- var result = lodash.indexOf || indexOf;
- result = result === indexOf ? baseIndexOf : result;
- return collection ? result(collection, target, fromIndex) : result;
+ function getIteratee() {
+ var result = lodash.iteratee || iteratee;
+ result = result === iteratee ? baseIteratee : result;
+ return arguments.length ? result(arguments[0], arguments[1]) : result;
}
/**
@@ -3912,14 +4697,14 @@
var getLength = baseProperty('length');
/**
- * Gets the propery names, values, and compare flags of `object`.
+ * Gets the property names, values, and compare flags of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the match data of `object`.
*/
function getMatchData(object) {
- var result = pairs(object),
+ var result = toPairs(object),
length = result.length;
while (length--) {
@@ -3941,6 +4726,47 @@
return isNative(value) ? value : undefined;
}
+ /**
+ * Creates an array of the own symbol properties of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of symbols.
+ */
+ var getSymbols = getOwnPropertySymbols || function() {
+ return [];
+ };
+
+ /**
+ * Gets the `toStringTag` of `value`.
+ *
+ * @private
+ * @param {*} value The value to query.
+ * @returns {string} Returns the `toStringTag`.
+ */
+ function getTag(value) {
+ return objectToString.call(value);
+ }
+
+ // Fallback for IE 11 providing `toStringTag` values for maps and sets.
+ if ((Map && getTag(new Map) != mapTag) || (Set && getTag(new Set) != setTag)) {
+ getTag = function(value) {
+ var result = objectToString.call(value),
+ Ctor = result == objectTag ? value.constructor : null,
+ ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
+
+ if (ctorString) {
+ if (ctorString == mapCtorString) {
+ return mapTag;
+ }
+ if (ctorString == setCtorString) {
+ return setTag;
+ }
+ }
+ return result;
+ };
+ }
+
/**
* Gets the view, applying any `transforms` to the `start` and `end` positions.
*
@@ -3969,6 +4795,32 @@
return { 'start': start, 'end': end };
}
+ /**
+ * Checks if `path` exists on `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @param {Function} hasFunc The function to check properties.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ */
+ function hasPath(object, path, hasFunc) {
+ if (object == null) {
+ return false;
+ }
+ var result = hasFunc(object, path);
+ if (!result && !isKey(path)) {
+ path = baseToPath(path);
+ object = parent(object, path);
+ if (object != null) {
+ path = last(path);
+ result = hasFunc(object, path);
+ }
+ }
+ return result || (isLength(object && object.length) && isIndex(path, object.length) &&
+ (isArray(object) || isString(object) || isArguments(object)));
+ }
+
/**
* Initializes an array clone.
*
@@ -3978,9 +4830,9 @@
*/
function initCloneArray(array) {
var length = array.length,
- result = new array.constructor(length);
+ result = array.constructor(length);
- // Add array properties assigned by `RegExp#exec`.
+ // Add properties assigned by `RegExp#exec`.
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
result.index = array.index;
result.input = array.input;
@@ -3997,10 +4849,7 @@
*/
function initCloneObject(object) {
var Ctor = object.constructor;
- if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
- Ctor = Object;
- }
- return new Ctor;
+ return baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
}
/**
@@ -4019,7 +4868,7 @@
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
- return bufferClone(object);
+ return cloneBuffer(object);
case boolTag:
case dateTag:
@@ -4028,62 +4877,39 @@
case float32Tag: case float64Tag:
case int8Tag: case int16Tag: case int32Tag:
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
- var buffer = object.buffer;
- return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
+ return cloneTypedArray(object, isDeep);
+
+ case mapTag:
+ return cloneMap(object);
case numberTag:
case stringTag:
return new Ctor(object);
case regexpTag:
- var result = new Ctor(object.source, reFlags.exec(object));
- result.lastIndex = object.lastIndex;
+ return cloneRegExp(object);
+
+ case setTag:
+ return cloneSet(object);
+
+ case symbolTag:
+ return cloneSymbol(object);
}
- return result;
}
/**
- * Invokes the method at `path` on `object`.
+ * Creates an array of index keys for `object` values of arrays,
+ * `arguments` objects, and strings, otherwise `null` is returned.
*
* @private
* @param {Object} object The object to query.
- * @param {Array|string} path The path of the method to invoke.
- * @param {Array} args The arguments to invoke the method with.
- * @returns {*} Returns the result of the invoked method.
+ * @returns {Array|null} Returns index keys, else `null`.
*/
- function invokePath(object, path, args) {
- if (object != null && !isKey(path, object)) {
- path = toPath(path);
- object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
- path = last(path);
- }
- var func = object == null ? object : object[path];
- return func == null ? undefined : func.apply(object, args);
- }
-
- /**
- * Checks if `value` is array-like.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
- */
- function isArrayLike(value) {
- return value != null && isLength(getLength(value));
- }
-
- /**
- * Checks if `value` is a valid array-like index.
- *
- * @private
- * @param {*} value The value to check.
- * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
- * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
- */
- function isIndex(value, length) {
- value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
- length = length == null ? MAX_SAFE_INTEGER : length;
- return value > -1 && value % 1 == 0 && value < length;
+ function indexKeys(object) {
+ var length = object ? object.length : undefined;
+ return (isLength(length) && (isArray(object) || isString(object) || isArguments(object)))
+ ? baseTimes(length, String)
+ : null;
}
/**
@@ -4103,8 +4929,7 @@
if (type == 'number'
? (isArrayLike(object) && isIndex(index, object.length))
: (type == 'string' && index in object)) {
- var other = object[index];
- return value === value ? (value === other) : (other !== other);
+ return eq(object[index], value);
}
return false;
}
@@ -4118,15 +4943,25 @@
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
*/
function isKey(value, object) {
- var type = typeof value;
- if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
+ if (typeof value == 'number') {
return true;
}
- if (isArray(value)) {
- return false;
- }
- var result = !reIsDeepProp.test(value);
- return result || (object != null && value in toObject(object));
+ return !isArray(value) &&
+ (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+ (object != null && value in Object(object)));
+ }
+
+ /**
+ * Checks if `value` is suitable for use as unique object key.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+ */
+ function isKeyable(value) {
+ var type = typeof value;
+ return type == 'number' || type == 'boolean' ||
+ (type == 'string' && value !== '__proto__') || value == null;
}
/**
@@ -4151,16 +4986,17 @@
}
/**
- * Checks if `value` is a valid array-like length.
- *
- * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ * Checks if `value` is likely a prototype object.
*
* @private
* @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
*/
- function isLength(value) {
- return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+ function isPrototype(value) {
+ var Ctor = value && value.constructor,
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+
+ return value === proto;
}
/**
@@ -4178,12 +5014,12 @@
/**
* Merges the function metadata of `source` into `data`.
*
- * Merging metadata reduces the number of wrappers required to invoke a function.
+ * Merging metadata reduces the number of wrappers used to invoke a function.
* This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
* may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
- * augment function arguments, making the order in which they are executed important,
+ * modify function arguments, making the order in which they are executed important,
* preventing the merging of metadata. However, we make an exception for a safe
- * common case where curried functions have `_.ary` and or `_.rearg` applied.
+ * combined case where curried functions have `_.ary` and or `_.rearg` applied.
*
* @private
* @param {Array} data The destination metadata.
@@ -4194,12 +5030,12 @@
var bitmask = data[1],
srcBitmask = source[1],
newBitmask = bitmask | srcBitmask,
- isCommon = newBitmask < ARY_FLAG;
+ isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
var isCombo =
- (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
- (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
- (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
+ (srcBitmask == ARY_FLAG && (bitmask == CURRY_FLAG)) ||
+ (srcBitmask == ARY_FLAG && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
+ (srcBitmask == (ARY_FLAG | REARG_FLAG) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
// Exit early if metadata can't be merged.
if (!(isCommon || isCombo)) {
@@ -4215,20 +5051,20 @@
var value = source[3];
if (value) {
var partials = data[3];
- data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
- data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
+ data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
+ data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
}
// Compose partial right arguments.
value = source[5];
if (value) {
partials = data[5];
- data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
- data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
+ data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
+ data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
}
// Use source `argPos` if available.
value = source[7];
if (value) {
- data[7] = arrayCopy(value);
+ data[7] = copyArray(value);
}
// Use source `ary` if it's smaller.
if (srcBitmask & ARY_FLAG) {
@@ -4249,56 +5085,32 @@
* 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.
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to merge.
+ * @param {Object} object The parent object of `objValue`.
+ * @param {Object} source The parent object of `srcValue`.
+ * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
+ * @returns {*} Returns the value to assign.
*/
- function mergeDefaults(objectValue, sourceValue) {
- return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);
- }
-
- /**
- * A specialized version of `_.pick` which picks `object` properties specified
- * by `props`.
- *
- * @private
- * @param {Object} object The source object.
- * @param {string[]} props The property names to pick.
- * @returns {Object} Returns the new object.
- */
- function pickByArray(object, props) {
- object = toObject(object);
-
- var index = -1,
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index];
- if (key in object) {
- result[key] = object[key];
- }
+ function mergeDefaults(objValue, srcValue, key, object, source, stack) {
+ if (isObject(objValue) && isObject(srcValue)) {
+ stack.set(srcValue, objValue);
+ baseMerge(objValue, srcValue, mergeDefaults, stack);
}
- return result;
+ return objValue === undefined ? baseClone(srcValue) : objValue;
}
/**
- * A specialized version of `_.pick` which picks `object` properties `predicate`
- * returns truthy for.
+ * Gets the parent value at `path` of `object`.
*
* @private
- * @param {Object} object The source object.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {Object} Returns the new object.
+ * @param {Object} object The object to query.
+ * @param {Array} path The path to get the parent value of.
+ * @returns {*} Returns the parent value.
*/
- function pickByCallback(object, predicate) {
- var result = {};
- baseForIn(object, function(value, key, object) {
- if (predicate(value, key, object)) {
- result[key] = value;
- }
- });
- return result;
+ function parent(object, path) {
+ return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
}
/**
@@ -4314,7 +5126,7 @@
function reorder(array, indexes) {
var arrLength = array.length,
length = nativeMin(indexes.length, arrLength),
- oldArray = arrayCopy(array);
+ oldArray = copyArray(array);
while (length--) {
var index = indexes[length];
@@ -4357,30 +5169,17 @@
}());
/**
- * A fallback implementation of `Object.keys` which creates an array of the
- * own enumerable property names of `object`.
+ * Converts `string` to a property path array.
*
* @private
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the property path array.
*/
- function shimKeys(object) {
- var props = keysIn(object),
- propsLength = props.length,
- length = propsLength && object.length;
-
- var allowIndexes = !!length && isLength(length) &&
- (isArray(object) || isArguments(object));
-
- var index = -1,
- result = [];
-
- while (++index < propsLength) {
- var key = props[index];
- if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
- result.push(key);
- }
- }
+ function stringToPath(string) {
+ var result = [];
+ toString(string).replace(rePropName, function(match, number, quote, string) {
+ result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
+ });
return result;
}
@@ -4389,45 +5188,21 @@
*
* @private
* @param {*} value The value to process.
- * @returns {Array|Object} Returns the array-like object.
+ * @returns {Array} Returns the array-like object.
*/
- function toIterable(value) {
- if (value == null) {
- return [];
- }
- if (!isArrayLike(value)) {
- return values(value);
- }
- return isObject(value) ? value : Object(value);
+ function toArrayLikeObject(value) {
+ return isArrayLikeObject(value) ? value : [];
}
/**
- * Converts `value` to an object if it's not one.
+ * Converts `value` to a function if it's not one.
*
* @private
* @param {*} value The value to process.
- * @returns {Object} Returns the object.
+ * @returns {Function} Returns the function.
*/
- function toObject(value) {
- return isObject(value) ? value : Object(value);
- }
-
- /**
- * Converts `value` to property path array if it's not one.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {Array} Returns the property path array.
- */
- function toPath(value) {
- if (isArray(value)) {
- return value;
- }
- var result = [];
- baseToString(value).replace(rePropName, function(match, number, quote, string) {
- result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
- });
- return result;
+ function toFunction(value) {
+ return typeof value == 'function' ? value : identity;
}
/**
@@ -4438,24 +5213,28 @@
* @returns {Object} Returns the cloned wrapper.
*/
function wrapperClone(wrapper) {
- return wrapper instanceof LazyWrapper
- ? wrapper.clone()
- : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
+ if (wrapper instanceof LazyWrapper) {
+ return wrapper.clone();
+ }
+ var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
+ result.__actions__ = copyArray(wrapper.__actions__);
+ result.__index__ = wrapper.__index__;
+ result.__values__ = wrapper.__values__;
+ return result;
}
/*------------------------------------------------------------------------*/
/**
* Creates an array of elements split into groups the length of `size`.
- * If `collection` can't be split evenly, the final chunk will be the remaining
+ * If `array` can't be split evenly, the final chunk will be the remaining
* elements.
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to process.
- * @param {number} [size=1] The length of each chunk.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param {number} [size=0] The length of each chunk.
* @returns {Array} Returns the new array containing chunks.
* @example
*
@@ -4465,14 +5244,14 @@
* _.chunk(['a', 'b', 'c', 'd'], 3);
* // => [['a', 'b', 'c'], ['d']]
*/
- function chunk(array, size, guard) {
- if (guard ? isIterateeCall(array, size, guard) : size == null) {
- size = 1;
- } else {
- size = nativeMax(nativeFloor(size) || 1, 1);
+ function chunk(array, size) {
+ size = nativeMax(toInteger(size), 0);
+
+ var length = array ? array.length : 0;
+ if (!length || size < 1) {
+ return [];
}
var index = 0,
- length = array ? array.length : 0,
resIndex = -1,
result = Array(nativeCeil(length / size));
@@ -4511,6 +5290,32 @@
return result;
}
+ /**
+ * Creates a new array concatenating `array` with any additional arrays
+ * and/or values.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to concatenate.
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var other = _.concat(array, 2, [3], [[4]]);
+ *
+ * console.log(other);
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */
+ var concat = rest(function(array, values) {
+ values = baseFlatten(values);
+ return arrayConcat(isArray(array) ? array : [Object(array)], values);
+ });
+
/**
* Creates an array of unique `array` values not included in the other
* provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
@@ -4520,19 +5325,79 @@
* @memberOf _
* @category Array
* @param {Array} array The array to inspect.
- * @param {...Array} [values] The arrays of values to exclude.
+ * @param {...Array} [values] The values to exclude.
* @returns {Array} Returns the new array of filtered values.
* @example
*
- * _.difference([1, 2, 3], [4, 2]);
- * // => [1, 3]
+ * _.difference([3, 2, 1], [4, 2]);
+ * // => [3, 1]
*/
- var difference = restParam(function(array, values) {
- return (isObjectLike(array) && isArrayLike(array))
+ var difference = rest(function(array, values) {
+ return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, false, true))
: [];
});
+ /**
+ * This method is like `_.difference` except that it accepts `iteratee` which
+ * is invoked for each element of `array` and `values` to generate the criterion
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
+ * // => [3.1, 1.3]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+ * // => [{ 'x': 2 }]
+ */
+ var differenceBy = rest(function(array, values) {
+ var iteratee = last(values);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
+ }
+ return isArrayLikeObject(array)
+ ? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee))
+ : [];
+ });
+
+ /**
+ * This method is like `_.difference` except that it accepts `comparator`
+ * which is invoked to compare elements of `array` to `values`. The comparator
+ * is invoked with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {...Array} [values] The values to exclude.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ *
+ * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
+ * // => [{ 'x': 2, 'y': 1 }]
+ */
+ var differenceWith = rest(function(array, values) {
+ var comparator = last(values);
+ if (isArrayLikeObject(comparator)) {
+ comparator = undefined;
+ }
+ return isArrayLikeObject(array)
+ ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator)
+ : [];
+ });
+
/**
* Creates a slice of `array` with `n` elements dropped from the beginning.
*
@@ -4541,7 +5406,7 @@
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to drop.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
@@ -4562,10 +5427,8 @@
if (!length) {
return [];
}
- if (guard ? isIterateeCall(array, n, guard) : n == null) {
- n = 1;
- }
- return baseSlice(array, n < 0 ? 0 : n);
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ return baseSlice(array, n < 0 ? 0 : n, length);
}
/**
@@ -4576,7 +5439,7 @@
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to drop.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
@@ -4597,120 +5460,88 @@
if (!length) {
return [];
}
- if (guard ? isIterateeCall(array, n, guard) : n == null) {
- n = 1;
- }
- n = length - (+n || 0);
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ n = length - n;
return baseSlice(array, 0, n < 0 ? 0 : n);
}
/**
* Creates a slice of `array` excluding elements dropped from the end.
* Elements are dropped until `predicate` returns falsey. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that match the properties of the given
- * object, else `false`.
+ * invoked with three arguments: (value, index, array).
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to query.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
- * _.dropRightWhile([1, 2, 3], function(n) {
- * return n > 1;
- * });
- * // => [1]
- *
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': false }
* ];
*
- * // using the `_.matches` callback shorthand
- * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');
- * // => ['barney', 'fred']
+ * _.dropRightWhile(users, function(o) { return !o.active; });
+ * // => objects for ['barney']
*
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.dropRightWhile(users, 'active', false), 'user');
- * // => ['barney']
+ * // using the `_.matches` iteratee shorthand
+ * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
+ * // => objects for ['barney', 'fred']
*
- * // using the `_.property` callback shorthand
- * _.pluck(_.dropRightWhile(users, 'active'), 'user');
- * // => ['barney', 'fred', 'pebbles']
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.dropRightWhile(users, ['active', false]);
+ * // => objects for ['barney']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.dropRightWhile(users, 'active');
+ * // => objects for ['barney', 'fred', 'pebbles']
*/
- function dropRightWhile(array, predicate, thisArg) {
+ function dropRightWhile(array, predicate) {
return (array && array.length)
- ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true)
+ ? baseWhile(array, getIteratee(predicate, 3), true, true)
: [];
}
/**
* Creates a slice of `array` excluding elements dropped from the beginning.
* Elements are dropped until `predicate` returns falsey. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * invoked with three arguments: (value, index, array).
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to query.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
- * _.dropWhile([1, 2, 3], function(n) {
- * return n < 3;
- * });
- * // => [3]
- *
* var users = [
* { 'user': 'barney', 'active': false },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': true }
* ];
*
- * // using the `_.matches` callback shorthand
- * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user');
- * // => ['fred', 'pebbles']
+ * _.dropWhile(users, function(o) { return !o.active; });
+ * // => objects for ['pebbles']
*
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.dropWhile(users, 'active', false), 'user');
- * // => ['pebbles']
+ * // using the `_.matches` iteratee shorthand
+ * _.dropWhile(users, { 'user': 'barney', 'active': false });
+ * // => objects for ['fred', 'pebbles']
*
- * // using the `_.property` callback shorthand
- * _.pluck(_.dropWhile(users, 'active'), 'user');
- * // => ['barney', 'fred', 'pebbles']
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.dropWhile(users, ['active', false]);
+ * // => objects for ['pebbles']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.dropWhile(users, 'active');
+ * // => objects for ['barney', 'fred', 'pebbles']
*/
- function dropWhile(array, predicate, thisArg) {
+ function dropWhile(array, predicate) {
return (array && array.length)
- ? baseWhile(array, getCallback(predicate, thisArg, 3), true)
+ ? baseWhile(array, getIteratee(predicate, 3), true)
: [];
}
@@ -4739,8 +5570,8 @@
* _.fill(Array(3), 2);
* // => [2, 2, 2]
*
- * _.fill([4, 6, 8], '*', 1, 2);
- * // => [4, '*', 8]
+ * _.fill([4, 6, 8, 10], '*', 1, 3);
+ * // => [4, '*', '*', 10]
*/
function fill(array, value, start, end) {
var length = array ? array.length : 0;
@@ -4758,24 +5589,11 @@
* This method is like `_.find` except that it returns the index of the first
* element `predicate` returns truthy for instead of the element itself.
*
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {number} Returns the index of the found element, else `-1`.
* @example
*
@@ -4785,47 +5603,36 @@
* { 'user': 'pebbles', 'active': true }
* ];
*
- * _.findIndex(users, function(chr) {
- * return chr.user == 'barney';
- * });
+ * _.findIndex(users, function(o) { return o.user == 'barney'; });
* // => 0
*
- * // using the `_.matches` callback shorthand
+ * // using the `_.matches` iteratee shorthand
* _.findIndex(users, { 'user': 'fred', 'active': false });
* // => 1
*
- * // using the `_.matchesProperty` callback shorthand
- * _.findIndex(users, 'active', false);
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.findIndex(users, ['active', false]);
* // => 0
*
- * // using the `_.property` callback shorthand
+ * // using the `_.property` iteratee shorthand
* _.findIndex(users, 'active');
* // => 2
*/
- var findIndex = createFindIndex();
+ function findIndex(array, predicate) {
+ return (array && array.length)
+ ? baseFindIndex(array, getIteratee(predicate, 3))
+ : -1;
+ }
/**
* This method is like `_.findIndex` except that it iterates over elements
* of `collection` from right to left.
*
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {number} Returns the index of the found element, else `-1`.
* @example
*
@@ -4835,76 +5642,72 @@
* { 'user': 'pebbles', 'active': false }
* ];
*
- * _.findLastIndex(users, function(chr) {
- * return chr.user == 'pebbles';
- * });
+ * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
* // => 2
*
- * // using the `_.matches` callback shorthand
+ * // using the `_.matches` iteratee shorthand
* _.findLastIndex(users, { 'user': 'barney', 'active': true });
* // => 0
*
- * // using the `_.matchesProperty` callback shorthand
- * _.findLastIndex(users, 'active', false);
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.findLastIndex(users, ['active', false]);
* // => 2
*
- * // using the `_.property` callback shorthand
+ * // using the `_.property` iteratee shorthand
* _.findLastIndex(users, 'active');
* // => 0
*/
- var findLastIndex = createFindIndex(true);
-
- /**
- * Gets the first element of `array`.
- *
- * @static
- * @memberOf _
- * @alias head
- * @category Array
- * @param {Array} array The array to query.
- * @returns {*} Returns the first element of `array`.
- * @example
- *
- * _.first([1, 2, 3]);
- * // => 1
- *
- * _.first([]);
- * // => undefined
- */
- function first(array) {
- return array ? array[0] : undefined;
+ function findLastIndex(array, predicate) {
+ return (array && array.length)
+ ? baseFindIndex(array, getIteratee(predicate, 3), true)
+ : -1;
}
/**
- * Flattens a nested array. If `isDeep` is `true` the array is recursively
- * flattened, otherwise it's only flattened a single level.
+ * Creates an array of flattened values by running each element in `array`
+ * through `iteratee` and concating its result to the other mapped values.
+ * The iteratee is invoked with three arguments: (value, index|key, array).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new array.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [n, n];
+ * }
+ *
+ * _.flatMap([1, 2], duplicate);
+ * // => [1, 1, 2, 2]
+ */
+ function flatMap(array, iteratee) {
+ var length = array ? array.length : 0;
+ return length ? baseFlatten(arrayMap(array, getIteratee(iteratee, 3))) : [];
+ }
+
+ /**
+ * Flattens `array` a single level.
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to flatten.
- * @param {boolean} [isDeep] Specify a deep flatten.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
* @returns {Array} Returns the new flattened array.
* @example
*
* _.flatten([1, [2, 3, [4]]]);
* // => [1, 2, 3, [4]]
- *
- * // using `isDeep`
- * _.flatten([1, [2, 3, [4]]], true);
- * // => [1, 2, 3, 4]
*/
- function flatten(array, isDeep, guard) {
+ function flatten(array) {
var length = array ? array.length : 0;
- if (guard && isIterateeCall(array, isDeep, guard)) {
- isDeep = false;
- }
- return length ? baseFlatten(array, isDeep) : [];
+ return length ? baseFlatten(array) : [];
}
/**
- * Recursively flattens a nested array.
+ * This method is like `_.flatten` except that it recursively flattens `array`.
*
* @static
* @memberOf _
@@ -4921,6 +5724,53 @@
return length ? baseFlatten(array, true) : [];
}
+ /**
+ * The inverse of `_.toPairs`; this method returns an object composed
+ * from key-value `pairs`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} pairs The key-value pairs.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.fromPairs([['fred', 30], ['barney', 40]]);
+ * // => { 'fred': 30, 'barney': 40 }
+ */
+ function fromPairs(pairs) {
+ var index = -1,
+ length = pairs ? pairs.length : 0,
+ result = {};
+
+ while (++index < length) {
+ var pair = pairs[index];
+ baseSet(result, pair[0], pair[1]);
+ }
+ return result;
+ }
+
+ /**
+ * Gets the first element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @alias first
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the first element of `array`.
+ * @example
+ *
+ * _.head([1, 2, 3]);
+ * // => 1
+ *
+ * _.head([]);
+ * // => undefined
+ */
+ function head(array) {
+ return array ? array[0] : undefined;
+ }
+
/**
* Gets the index at which the first occurrence of `value` is found in `array`
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
@@ -4933,8 +5783,7 @@
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=0] The index to search from or `true`
- * to perform a binary search on a sorted array.
+ * @param {number} [fromIndex=0] The index to search from.
* @returns {number} Returns the index of the matched value, else `-1`.
* @example
*
@@ -4944,27 +5793,17 @@
* // using `fromIndex`
* _.indexOf([1, 2, 1, 2], 2, 2);
* // => 3
- *
- * // performing a binary search
- * _.indexOf([1, 1, 2, 2], 2, true);
- * // => 2
*/
function indexOf(array, value, fromIndex) {
var length = array ? array.length : 0;
if (!length) {
return -1;
}
- if (typeof fromIndex == 'number') {
- fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
- } else if (fromIndex) {
- var index = binaryIndex(array, value);
- if (index < length &&
- (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
- return index;
- }
- return -1;
+ fromIndex = toInteger(fromIndex);
+ if (fromIndex < 0) {
+ fromIndex = nativeMax(length + fromIndex, 0);
}
- return baseIndexOf(array, value, fromIndex || 0);
+ return baseIndexOf(array, value, fromIndex);
}
/**
@@ -4995,46 +5834,101 @@
* @param {...Array} [arrays] The arrays to inspect.
* @returns {Array} Returns the new array of shared values.
* @example
- * _.intersection([1, 2], [4, 2], [2, 1]);
+ * _.intersection([2, 1], [4, 2], [1, 2]);
* // => [2]
*/
- var intersection = restParam(function(arrays) {
- var othLength = arrays.length,
- othIndex = othLength,
- caches = Array(length),
- indexOf = getIndexOf(),
- isCommon = indexOf === baseIndexOf,
- result = [];
-
- while (othIndex--) {
- var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : [];
- caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null;
- }
- var array = arrays[0],
- index = -1,
- length = array ? array.length : 0,
- seen = caches[0];
-
- outer:
- while (++index < length) {
- value = array[index];
- if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) {
- var othIndex = othLength;
- while (--othIndex) {
- var cache = caches[othIndex];
- if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) {
- continue outer;
- }
- }
- if (seen) {
- seen.push(value);
- }
- result.push(value);
- }
- }
- return result;
+ var intersection = rest(function(arrays) {
+ var mapped = arrayMap(arrays, toArrayLikeObject);
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped)
+ : [];
});
+ /**
+ * This method is like `_.intersection` except that it accepts `iteratee`
+ * which is invoked for each element of each `arrays` to generate the criterion
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ * @example
+ *
+ * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+ * // => [2.1]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }]
+ */
+ var intersectionBy = rest(function(arrays) {
+ var iteratee = last(arrays),
+ mapped = arrayMap(arrays, toArrayLikeObject);
+
+ if (iteratee === last(mapped)) {
+ iteratee = undefined;
+ } else {
+ mapped.pop();
+ }
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped, getIteratee(iteratee))
+ : [];
+ });
+
+ /**
+ * This method is like `_.intersection` except that it accepts `comparator`
+ * which is invoked to compare elements of `arrays`. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of shared values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.intersectionWith(objects, others, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }]
+ */
+ var intersectionWith = rest(function(arrays) {
+ var comparator = last(arrays),
+ mapped = arrayMap(arrays, toArrayLikeObject);
+
+ if (comparator === last(mapped)) {
+ comparator = undefined;
+ } else {
+ mapped.pop();
+ }
+ return (mapped.length && mapped[0] === arrays[0])
+ ? baseIntersection(mapped, undefined, comparator)
+ : [];
+ });
+
+ /**
+ * Converts all elements in `array` into a string separated by `separator`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to convert.
+ * @param {string} [separator=','] The element separator.
+ * @returns {string} Returns the joined string.
+ * @example
+ *
+ * _.join(['a', 'b', 'c'], '~');
+ * // => 'a~b~c'
+ */
+ function join(array, separator) {
+ return array ? nativeJoin.call(array, separator) : '';
+ }
+
/**
* Gets the last element of `array`.
*
@@ -5062,8 +5956,7 @@
* @category Array
* @param {Array} array The array to search.
* @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=array.length-1] The index to search from
- * or `true` to perform a binary search on a sorted array.
+ * @param {number} [fromIndex=array.length-1] The index to search from.
* @returns {number} Returns the index of the matched value, else `-1`.
* @example
*
@@ -5073,10 +5966,6 @@
* // using `fromIndex`
* _.lastIndexOf([1, 2, 1, 2], 2, 2);
* // => 1
- *
- * // performing a binary search
- * _.lastIndexOf([1, 1, 2, 2], 2, true);
- * // => 3
*/
function lastIndexOf(array, value, fromIndex) {
var length = array ? array.length : 0;
@@ -5084,15 +5973,9 @@
return -1;
}
var index = length;
- if (typeof fromIndex == 'number') {
- index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1;
- } else if (fromIndex) {
- index = binaryIndex(array, value, true) - 1;
- var other = array[index];
- if (value === value ? (value === other) : (other !== other)) {
- return index;
- }
- return -1;
+ if (fromIndex !== undefined) {
+ index = toInteger(fromIndex);
+ index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
}
if (value !== value) {
return indexOfNaN(array, index, true);
@@ -5126,32 +6009,64 @@
* console.log(array);
* // => [1, 1]
*/
- function pull() {
- var args = arguments,
- array = args[0];
+ var pull = rest(pullAll);
- if (!(array && array.length)) {
- return array;
- }
- var index = 0,
- indexOf = getIndexOf(),
- length = args.length;
-
- while (++index < length) {
- var fromIndex = 0,
- value = args[index];
-
- while ((fromIndex = indexOf(array, value, fromIndex)) > -1) {
- splice.call(array, fromIndex, 1);
- }
- }
- return array;
+ /**
+ * This method is like `_.pull` except that it accepts an array of values to remove.
+ *
+ * **Note:** Unlike `_.difference`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [1, 2, 3, 1, 2, 3];
+ *
+ * _.pull(array, [2, 3]);
+ * console.log(array);
+ * // => [1, 1]
+ */
+ function pullAll(array, values) {
+ return (array && array.length && values && values.length)
+ ? basePullAll(array, values)
+ : array;
}
/**
- * Removes elements from `array` corresponding to the given indexes and returns
- * an array of the removed elements. Indexes may be specified as an array of
- * indexes or as individual arguments.
+ * This method is like `_.pullAll` except that it accepts `iteratee` which is
+ * invoked for each element of `array` and `values` to to generate the criterion
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
+ *
+ * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
+ * console.log(array);
+ * // => [{ 'x': 2 }]
+ */
+ function pullAllBy(array, values, iteratee) {
+ return (array && array.length && values && values.length)
+ ? basePullAllBy(array, values, getIteratee(iteratee))
+ : array;
+ }
+
+ /**
+ * Removes elements from `array` corresponding to `indexes` and returns an
+ * array of removed elements.
*
* **Note:** Unlike `_.at`, this method mutates `array`.
*
@@ -5160,7 +6075,7 @@
* @category Array
* @param {Array} array The array to modify.
* @param {...(number|number[])} [indexes] The indexes of elements to remove,
- * specified as individual indexes or arrays of indexes.
+ * specified individually or in arrays.
* @returns {Array} Returns the new array of removed elements.
* @example
*
@@ -5173,29 +6088,18 @@
* console.log(evens);
* // => [10, 20]
*/
- var pullAt = restParam(function(array, indexes) {
- indexes = baseFlatten(indexes);
+ var pullAt = rest(function(array, indexes) {
+ indexes = arrayMap(baseFlatten(indexes), String);
var result = baseAt(array, indexes);
- basePullAt(array, indexes.sort(baseCompareAscending));
+ basePullAt(array, indexes.sort(compareAscending));
return result;
});
/**
* Removes all elements from `array` that `predicate` returns truthy for
- * and returns an array of the removed elements. The predicate is bound to
- * `thisArg` and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * and returns an array of the removed elements. The predicate is invoked with
+ * three arguments: (value, index, array).
*
* **Note:** Unlike `_.filter`, this method mutates `array`.
*
@@ -5203,9 +6107,7 @@
* @memberOf _
* @category Array
* @param {Array} array The array to modify.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new array of removed elements.
* @example
*
@@ -5220,7 +6122,7 @@
* console.log(evens);
* // => [2, 4]
*/
- function remove(array, predicate, thisArg) {
+ function remove(array, predicate) {
var result = [];
if (!(array && array.length)) {
return result;
@@ -5229,7 +6131,7 @@
indexes = [],
length = array.length;
- predicate = getCallback(predicate, thisArg, 3);
+ predicate = getIteratee(predicate, 3);
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
@@ -5242,28 +6144,34 @@
}
/**
- * Gets all but the first element of `array`.
+ * Reverses `array` so that the first element becomes the last, the second
+ * element becomes the second to last, and so on.
+ *
+ * **Note:** This method mutates `array` and is based on
+ * [`Array#reverse`](https://mdn.io/Array/reverse).
*
- * @static
* @memberOf _
- * @alias tail
* @category Array
- * @param {Array} array The array to query.
- * @returns {Array} Returns the slice of `array`.
+ * @returns {Array} Returns `array`.
* @example
*
- * _.rest([1, 2, 3]);
- * // => [2, 3]
+ * var array = [1, 2, 3];
+ *
+ * _.reverse(array);
+ * // => [3, 2, 1]
+ *
+ * console.log(array);
+ * // => [3, 2, 1]
*/
- function rest(array) {
- return drop(array, 1);
+ function reverse(array) {
+ return array ? nativeReverse.call(array) : array;
}
/**
* Creates a slice of `array` from `start` up to, but not including, `end`.
*
- * **Note:** This method is used instead of `Array#slice` to support node
- * lists in IE < 9 and to ensure dense arrays are returned.
+ * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
+ * to ensure dense arrays are returned.
*
* @static
* @memberOf _
@@ -5282,58 +6190,87 @@
start = 0;
end = length;
}
+ else {
+ start = start == null ? 0 : toInteger(start);
+ end = end === undefined ? length : toInteger(end);
+ }
return baseSlice(array, start, end);
}
/**
* Uses a binary search to determine the lowest index at which `value` should
- * be inserted into `array` in order to maintain its sort order. If an iteratee
- * function is provided it's invoked for `value` and each element of `array`
- * to compute their sort ranking. The iteratee is bound to `thisArg` and
- * invoked with one argument; (value).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * be inserted into `array` in order to maintain its sort order.
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
* @example
*
* _.sortedIndex([30, 50], 40);
* // => 1
*
- * _.sortedIndex([4, 4, 5, 5], 5);
- * // => 2
- *
- * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } };
- *
- * // using an iteratee function
- * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) {
- * return this.data[word];
- * }, dict);
- * // => 1
- *
- * // using the `_.property` callback shorthand
- * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
- * // => 1
+ * _.sortedIndex([4, 5], 4);
+ * // => 0
*/
- var sortedIndex = createSortedIndex();
+ function sortedIndex(array, value) {
+ return baseSortedIndex(array, value);
+ }
+
+ /**
+ * This method is like `_.sortedIndex` except that it accepts `iteratee`
+ * which is invoked for `value` and each element of `array` to compute their
+ * sort ranking. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
+ * @example
+ *
+ * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
+ *
+ * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
+ * // => 1
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+ * // => 0
+ */
+ function sortedIndexBy(array, value, iteratee) {
+ return baseSortedIndexBy(array, value, getIteratee(iteratee));
+ }
+
+ /**
+ * This method is like `_.indexOf` except that it performs a binary
+ * search on a sorted `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.sortedIndexOf([1, 1, 2, 2], 2);
+ * // => 2
+ */
+ function sortedIndexOf(array, value) {
+ var length = array ? array.length : 0;
+ if (length) {
+ var index = baseSortedIndex(array, value);
+ if (index < length && eq(array[index], value)) {
+ return index;
+ }
+ }
+ return -1;
+ }
/**
* This method is like `_.sortedIndex` except that it returns the highest
@@ -5345,17 +6282,121 @@
* @category Array
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
* @example
*
- * _.sortedLastIndex([4, 4, 5, 5], 5);
- * // => 4
+ * _.sortedLastIndex([4, 5], 4);
+ * // => 1
*/
- var sortedLastIndex = createSortedIndex(true);
+ function sortedLastIndex(array, value) {
+ return baseSortedIndex(array, value, true);
+ }
+
+ /**
+ * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
+ * which is invoked for `value` and each element of `array` to compute their
+ * sort ranking. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
+ * @example
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+ * // => 1
+ */
+ function sortedLastIndexBy(array, value, iteratee) {
+ return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
+ }
+
+ /**
+ * This method is like `_.lastIndexOf` except that it performs a binary
+ * search on a sorted `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.sortedLastIndexOf([1, 1, 2, 2], 2);
+ * // => 3
+ */
+ function sortedLastIndexOf(array, value) {
+ var length = array ? array.length : 0;
+ if (length) {
+ var index = baseSortedIndex(array, value, true) - 1;
+ if (eq(array[index], value)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * This method is like `_.uniq` except that it's designed and optimized
+ * for sorted arrays.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.sortedUniq([1, 1, 2]);
+ * // => [1, 2]
+ */
+ function sortedUniq(array) {
+ return (array && array.length)
+ ? baseSortedUniq(array)
+ : [];
+ }
+
+ /**
+ * This method is like `_.uniqBy` except that it's designed and optimized
+ * for sorted arrays.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
+ * // => [1.1, 2.2]
+ */
+ function sortedUniqBy(array, iteratee) {
+ return (array && array.length)
+ ? baseSortedUniqBy(array, getIteratee(iteratee))
+ : [];
+ }
+
+ /**
+ * Gets all but the first element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * _.tail([1, 2, 3]);
+ * // => [2, 3]
+ */
+ function tail(array) {
+ return drop(array, 1);
+ }
/**
* Creates a slice of `array` with `n` elements taken from the beginning.
@@ -5365,7 +6406,7 @@
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to take.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
@@ -5382,13 +6423,10 @@
* // => []
*/
function take(array, n, guard) {
- var length = array ? array.length : 0;
- if (!length) {
+ if (!(array && array.length)) {
return [];
}
- if (guard ? isIterateeCall(array, n, guard) : n == null) {
- n = 1;
- }
+ n = (guard || n === undefined) ? 1 : toInteger(n);
return baseSlice(array, 0, n < 0 ? 0 : n);
}
@@ -5400,7 +6438,7 @@
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to take.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
@@ -5421,120 +6459,88 @@
if (!length) {
return [];
}
- if (guard ? isIterateeCall(array, n, guard) : n == null) {
- n = 1;
- }
- n = length - (+n || 0);
- return baseSlice(array, n < 0 ? 0 : n);
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ n = length - n;
+ return baseSlice(array, n < 0 ? 0 : n, length);
}
/**
* Creates a slice of `array` with elements taken from the end. Elements are
- * taken until `predicate` returns falsey. The predicate is bound to `thisArg`
- * and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * taken until `predicate` returns falsey. The predicate is invoked with three
+ * arguments: (value, index, array).
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to query.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
- * _.takeRightWhile([1, 2, 3], function(n) {
- * return n > 1;
- * });
- * // => [2, 3]
- *
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': false }
* ];
*
- * // using the `_.matches` callback shorthand
- * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');
- * // => ['pebbles']
+ * _.takeRightWhile(users, function(o) { return !o.active; });
+ * // => objects for ['fred', 'pebbles']
*
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.takeRightWhile(users, 'active', false), 'user');
- * // => ['fred', 'pebbles']
+ * // using the `_.matches` iteratee shorthand
+ * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
+ * // => objects for ['pebbles']
*
- * // using the `_.property` callback shorthand
- * _.pluck(_.takeRightWhile(users, 'active'), 'user');
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.takeRightWhile(users, ['active', false]);
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.takeRightWhile(users, 'active');
* // => []
*/
- function takeRightWhile(array, predicate, thisArg) {
+ function takeRightWhile(array, predicate) {
return (array && array.length)
- ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true)
+ ? baseWhile(array, getIteratee(predicate, 3), false, true)
: [];
}
/**
* Creates a slice of `array` with elements taken from the beginning. Elements
- * are taken until `predicate` returns falsey. The predicate is bound to
- * `thisArg` and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * are taken until `predicate` returns falsey. The predicate is invoked with
+ * three arguments: (value, index, array).
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array to query.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
- * _.takeWhile([1, 2, 3], function(n) {
- * return n < 3;
- * });
- * // => [1, 2]
- *
* var users = [
* { 'user': 'barney', 'active': false },
* { 'user': 'fred', 'active': false},
* { 'user': 'pebbles', 'active': true }
* ];
*
- * // using the `_.matches` callback shorthand
- * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user');
- * // => ['barney']
+ * _.takeWhile(users, function(o) { return !o.active; });
+ * // => objects for ['barney', 'fred']
*
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.takeWhile(users, 'active', false), 'user');
- * // => ['barney', 'fred']
+ * // using the `_.matches` iteratee shorthand
+ * _.takeWhile(users, { 'user': 'barney', 'active': false });
+ * // => objects for ['barney']
*
- * // using the `_.property` callback shorthand
- * _.pluck(_.takeWhile(users, 'active'), 'user');
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.takeWhile(users, ['active', false]);
+ * // => objects for ['barney', 'fred']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.takeWhile(users, 'active');
* // => []
*/
- function takeWhile(array, predicate, thisArg) {
+ function takeWhile(array, predicate) {
return (array && array.length)
- ? baseWhile(array, getCallback(predicate, thisArg, 3))
+ ? baseWhile(array, getIteratee(predicate, 3))
: [];
}
@@ -5550,79 +6556,138 @@
* @returns {Array} Returns the new array of combined values.
* @example
*
- * _.union([1, 2], [4, 2], [2, 1]);
- * // => [1, 2, 4]
+ * _.union([2, 1], [4, 2], [1, 2]);
+ * // => [2, 1, 4]
*/
- var union = restParam(function(arrays) {
+ var union = rest(function(arrays) {
return baseUniq(baseFlatten(arrays, false, true));
});
+ /**
+ * This method is like `_.union` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+ * // => [2.1, 1.2, 4.3]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }, { 'x': 2 }]
+ */
+ var unionBy = rest(function(arrays) {
+ var iteratee = last(arrays);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
+ }
+ return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee));
+ });
+
+ /**
+ * This method is like `_.union` except that it accepts `comparator` which
+ * is invoked to compare elements of `arrays`. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.unionWith(objects, others, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+ */
+ var unionWith = rest(function(arrays) {
+ var comparator = last(arrays);
+ if (isArrayLikeObject(comparator)) {
+ comparator = undefined;
+ }
+ return baseUniq(baseFlatten(arrays, false, true), undefined, comparator);
+ });
+
/**
* Creates a duplicate-free version of an array, using
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons, in which only the first 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's invoked for
- * each element in the array to generate the criterion by which uniqueness
- * is computed. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index, array).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * for equality comparisons, in which only the first occurrence of each element
+ * is kept.
*
* @static
* @memberOf _
- * @alias unique
* @category Array
* @param {Array} array The array to inspect.
- * @param {boolean} [isSorted] Specify the array is sorted.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the new duplicate-value-free array.
+ * @returns {Array} Returns the new duplicate free array.
* @example
*
* _.uniq([2, 1, 2]);
* // => [2, 1]
+ */
+ function uniq(array) {
+ return (array && array.length)
+ ? baseUniq(array)
+ : [];
+ }
+
+ /**
+ * This method is like `_.uniq` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
*
- * // using `isSorted`
- * _.uniq([1, 1, 2], true);
- * // => [1, 2]
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
*
- * // using an iteratee function
- * _.uniq([1, 2.5, 1.5, 2], function(n) {
- * return this.floor(n);
- * }, Math);
- * // => [1, 2.5]
+ * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
+ * // => [2.1, 1.2]
*
- * // using the `_.property` callback shorthand
- * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
+ * // using the `_.property` iteratee shorthand
+ * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 1 }, { 'x': 2 }]
*/
- function uniq(array, isSorted, iteratee, thisArg) {
- var length = array ? array.length : 0;
- if (!length) {
- return [];
- }
- if (isSorted != null && typeof isSorted != 'boolean') {
- thisArg = iteratee;
- iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;
- isSorted = false;
- }
- var callback = getCallback();
- if (!(iteratee == null && callback === baseCallback)) {
- iteratee = callback(iteratee, thisArg, 3);
- }
- return (isSorted && getIndexOf() === baseIndexOf)
- ? sortedUniq(array, iteratee)
- : baseUniq(array, iteratee);
+ function uniqBy(array, iteratee) {
+ return (array && array.length)
+ ? baseUniq(array, getIteratee(iteratee))
+ : [];
+ }
+
+ /**
+ * This method is like `_.uniq` except that it accepts `comparator` which
+ * is invoked to compare elements of `array`. The comparator is invoked with
+ * two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.uniqWith(objects, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
+ */
+ function uniqWith(array, comparator) {
+ return (array && array.length)
+ ? baseUniq(array, undefined, comparator)
+ : [];
}
/**
@@ -5647,33 +6712,28 @@
if (!(array && array.length)) {
return [];
}
- var index = -1,
- length = 0;
-
+ var length = 0;
array = arrayFilter(array, function(group) {
- if (isArrayLike(group)) {
+ if (isArrayLikeObject(group)) {
length = nativeMax(group.length, length);
return true;
}
});
- var result = Array(length);
- while (++index < length) {
- result[index] = arrayMap(array, baseProperty(index));
- }
- return result;
+ return baseTimes(length, function(index) {
+ return arrayMap(array, baseProperty(index));
+ });
}
/**
- * This method is like `_.unzip` except that it accepts an iteratee to specify
- * how regrouped values should be combined. The `iteratee` is bound to `thisArg`
- * and invoked with four arguments: (accumulator, value, index, group).
+ * This method is like `_.unzip` except that it accepts `iteratee` to specify
+ * how regrouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
*
* @static
* @memberOf _
* @category Array
* @param {Array} array The array of grouped elements to process.
- * @param {Function} [iteratee] The function to combine regrouped values.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
* @returns {Array} Returns the new array of regrouped elements.
* @example
*
@@ -5683,18 +6743,16 @@
* _.unzipWith(zipped, _.add);
* // => [3, 30, 300]
*/
- function unzipWith(array, iteratee, thisArg) {
- var length = array ? array.length : 0;
- if (!length) {
+ function unzipWith(array, iteratee) {
+ if (!(array && array.length)) {
return [];
}
var result = unzip(array);
if (iteratee == null) {
return result;
}
- iteratee = bindCallback(iteratee, thisArg, 4);
return arrayMap(result, function(group) {
- return arrayReduce(group, iteratee, undefined, true);
+ return apply(iteratee, undefined, group);
});
}
@@ -5714,8 +6772,8 @@
* _.without([1, 2, 1, 3], 1, 2);
* // => [3]
*/
- var without = restParam(function(array, values) {
- return isArrayLike(array)
+ var without = rest(function(array, values) {
+ return isArrayLikeObject(array)
? baseDifference(array, values)
: [];
});
@@ -5731,23 +6789,67 @@
* @returns {Array} Returns the new array of values.
* @example
*
- * _.xor([1, 2], [4, 2]);
+ * _.xor([2, 1], [4, 2]);
* // => [1, 4]
*/
- function xor() {
- var index = -1,
- length = arguments.length;
+ var xor = rest(function(arrays) {
+ return baseXor(arrayFilter(arrays, isArrayLikeObject));
+ });
- while (++index < length) {
- var array = arguments[index];
- if (isArrayLike(array)) {
- var result = result
- ? arrayPush(baseDifference(result, array), baseDifference(array, result))
- : array;
- }
+ /**
+ * This method is like `_.xor` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of values.
+ * @example
+ *
+ * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+ * // => [1.2, 4.3]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 2 }]
+ */
+ var xorBy = rest(function(arrays) {
+ var iteratee = last(arrays);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
}
- return result ? baseUniq(result) : [];
- }
+ return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
+ });
+
+ /**
+ * This method is like `_.xor` except that it accepts `comparator` which is
+ * invoked to compare elements of `arrays`. The comparator is invoked with
+ * two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.xorWith(objects, others, _.isEqual);
+ * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+ */
+ var xorWith = rest(function(arrays) {
+ var comparator = last(arrays);
+ if (isArrayLikeObject(comparator)) {
+ comparator = undefined;
+ }
+ return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
+ });
/**
* Creates an array of grouped elements, the first of which contains the first
@@ -5764,89 +6866,70 @@
* _.zip(['fred', 'barney'], [30, 40], [true, false]);
* // => [['fred', 30, true], ['barney', 40, false]]
*/
- var zip = restParam(unzip);
+ var zip = rest(unzip);
/**
- * The inverse of `_.pairs`; this method returns an object composed from arrays
- * of property names and values. Provide either a single two dimensional array,
- * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names
- * and one of corresponding values.
+ * This method is like `_.fromPairs` except that it accepts two arrays,
+ * one of property names and one of corresponding values.
*
* @static
* @memberOf _
- * @alias object
* @category Array
- * @param {Array} props The property names.
+ * @param {Array} [props=[]] The property names.
* @param {Array} [values=[]] The property values.
* @returns {Object} Returns the new object.
* @example
*
- * _.zipObject([['fred', 30], ['barney', 40]]);
- * // => { 'fred': 30, 'barney': 40 }
- *
* _.zipObject(['fred', 'barney'], [30, 40]);
* // => { 'fred': 30, 'barney': 40 }
*/
function zipObject(props, values) {
var index = -1,
length = props ? props.length : 0,
+ valsLength = values ? values.length : 0,
result = {};
- if (length && !values && !isArray(props[0])) {
- values = [];
- }
while (++index < length) {
- var key = props[index];
- if (values) {
- result[key] = values[index];
- } else if (key) {
- result[key[0]] = key[1];
- }
+ baseSet(result, props[index], index < valsLength ? values[index] : undefined);
}
return result;
}
/**
- * This method is like `_.zip` except that it accepts an iteratee to specify
- * how grouped values should be combined. The `iteratee` is bound to `thisArg`
- * and invoked with four arguments: (accumulator, value, index, group).
+ * This method is like `_.zip` except that it accepts `iteratee` to specify
+ * how grouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
*
* @static
* @memberOf _
* @category Array
* @param {...Array} [arrays] The arrays to process.
- * @param {Function} [iteratee] The function to combine grouped values.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Function} [iteratee=_.identity] The function to combine grouped values.
* @returns {Array} Returns the new array of grouped elements.
* @example
*
- * _.zipWith([1, 2], [10, 20], [100, 200], _.add);
+ * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
+ * return a + b + c;
+ * });
* // => [111, 222]
*/
- var zipWith = restParam(function(arrays) {
+ var zipWith = rest(function(arrays) {
var length = arrays.length,
- iteratee = length > 2 ? arrays[length - 2] : undefined,
- thisArg = length > 1 ? arrays[length - 1] : undefined;
+ iteratee = length > 1 ? arrays[length - 1] : undefined;
- if (length > 2 && typeof iteratee == 'function') {
- length -= 2;
- } else {
- iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined;
- thisArg = undefined;
- }
- arrays.length = length;
- return unzipWith(arrays, iteratee, thisArg);
+ iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
+ return unzipWith(arrays, iteratee);
});
/*------------------------------------------------------------------------*/
/**
- * Creates a `lodash` object that wraps `value` with explicit method
- * chaining enabled.
+ * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
+ * The result of such method chaining must be unwrapped with `_#value`.
*
* @static
* @memberOf _
- * @category Chain
+ * @category Seq
* @param {*} value The value to wrap.
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
@@ -5857,12 +6940,13 @@
* { 'user': 'pebbles', 'age': 1 }
* ];
*
- * var youngest = _.chain(users)
+ * var youngest = _
+ * .chain(users)
* .sortBy('age')
- * .map(function(chr) {
- * return chr.user + ' is ' + chr.age;
+ * .map(function(o) {
+ * return o.user + ' is ' + o.age;
* })
- * .first()
+ * .head()
* .value();
* // => 'pebbles is 1'
*/
@@ -5874,16 +6958,15 @@
/**
* This method invokes `interceptor` and returns `value`. The interceptor is
- * bound to `thisArg` and invoked with one argument; (value). The purpose of
- * this method is to "tap into" a method chain in order to perform operations
- * on intermediate results within the chain.
+ * invoked with one argument; (value). The purpose of this method is to "tap into"
+ * a method chain in order to perform operations on intermediate results within
+ * the chain.
*
* @static
* @memberOf _
- * @category Chain
+ * @category Seq
* @param {*} value The value to provide to `interceptor`.
* @param {Function} interceptor The function to invoke.
- * @param {*} [thisArg] The `this` binding of `interceptor`.
* @returns {*} Returns `value`.
* @example
*
@@ -5895,8 +6978,8 @@
* .value();
* // => [2, 1]
*/
- function tap(value, interceptor, thisArg) {
- interceptor.call(thisArg, value);
+ function tap(value, interceptor) {
+ interceptor(value);
return value;
}
@@ -5905,10 +6988,9 @@
*
* @static
* @memberOf _
- * @category Chain
+ * @category Seq
* @param {*} value The value to provide to `interceptor`.
* @param {Function} interceptor The function to invoke.
- * @param {*} [thisArg] The `this` binding of `interceptor`.
* @returns {*} Returns the result of `interceptor`.
* @example
*
@@ -5921,16 +7003,55 @@
* .value();
* // => ['abc']
*/
- function thru(value, interceptor, thisArg) {
- return interceptor.call(thisArg, value);
+ function thru(value, interceptor) {
+ return interceptor(value);
}
+ /**
+ * This method is the wrapper version of `_.at`.
+ *
+ * @name at
+ * @memberOf _
+ * @category Seq
+ * @param {...(string|string[])} [paths] The property paths of elements to pick,
+ * specified individually or in arrays.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+ *
+ * _(object).at(['a[0].b.c', 'a[1]']).value();
+ * // => [3, 4]
+ *
+ * _(['a', 'b', 'c']).at(0, 2).value();
+ * // => ['a', 'c']
+ */
+ var wrapperAt = rest(function(paths) {
+ paths = baseFlatten(paths);
+ var length = paths.length,
+ start = length ? paths[0] : 0,
+ value = this.__wrapped__,
+ interceptor = function(object) { return baseAt(object, paths); };
+
+ if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) {
+ return this.thru(interceptor);
+ }
+ value = value.slice(start, +start + (length ? 1 : 0));
+ value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
+ return new LodashWrapper(value, this.__chain__).thru(function(array) {
+ if (length && !array.length) {
+ array.push(undefined);
+ }
+ return array;
+ });
+ });
+
/**
* Enables explicit method chaining on the wrapper object.
*
* @name chain
* @memberOf _
- * @category Chain
+ * @category Seq
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
@@ -5940,12 +7061,13 @@
* ];
*
* // without explicit chaining
- * _(users).first();
+ * _(users).head();
* // => { 'user': 'barney', 'age': 36 }
*
* // with explicit chaining
- * _(users).chain()
- * .first()
+ * _(users)
+ * .chain()
+ * .head()
* .pick('user')
* .value();
* // => { 'user': 'barney' }
@@ -5959,7 +7081,7 @@
*
* @name commit
* @memberOf _
- * @category Chain
+ * @category Seq
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
@@ -5984,50 +7106,96 @@
}
/**
- * Creates a new array joining a wrapped array with any additional arrays
- * and/or values.
+ * This method is the wrapper version of `_.flatMap`.
*
- * @name concat
+ * @static
* @memberOf _
- * @category Chain
- * @param {...*} [values] The values to concatenate.
- * @returns {Array} Returns the new concatenated array.
+ * @category Seq
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
- * var array = [1];
- * var wrapped = _(array).concat(2, [3], [[4]]);
+ * function duplicate(n) {
+ * return [n, n];
+ * }
*
- * console.log(wrapped.value());
- * // => [1, 2, 3, [4]]
- *
- * console.log(array);
- * // => [1]
+ * _([1, 2]).flatMap(duplicate).value();
+ * // => [1, 1, 2, 2]
*/
- var wrapperConcat = restParam(function(values) {
- values = baseFlatten(values);
- return this.thru(function(array) {
- return arrayConcat(isArray(array) ? array : [toObject(array)], values);
- });
- });
+ function wrapperFlatMap(iteratee) {
+ return this.map(iteratee).flatten();
+ }
+
+ /**
+ * Gets the next value on a wrapped object following the
+ * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
+ *
+ * @name next
+ * @memberOf _
+ * @category Seq
+ * @returns {Object} Returns the next iterator value.
+ * @example
+ *
+ * var wrapped = _([1, 2]);
+ *
+ * wrapped.next();
+ * // => { 'done': false, 'value': 1 }
+ *
+ * wrapped.next();
+ * // => { 'done': false, 'value': 2 }
+ *
+ * wrapped.next();
+ * // => { 'done': true, 'value': undefined }
+ */
+ function wrapperNext() {
+ if (this.__values__ === undefined) {
+ this.__values__ = toArray(this.value());
+ }
+ var done = this.__index__ >= this.__values__.length,
+ value = done ? undefined : this.__values__[this.__index__++];
+
+ return { 'done': done, 'value': value };
+ }
+
+ /**
+ * Enables the wrapper to be iterable.
+ *
+ * @name Symbol.iterator
+ * @memberOf _
+ * @category Seq
+ * @returns {Object} Returns the wrapper object.
+ * @example
+ *
+ * var wrapped = _([1, 2]);
+ *
+ * wrapped[Symbol.iterator]() === wrapped;
+ * // => true
+ *
+ * Array.from(wrapped);
+ * // => [1, 2]
+ */
+ function wrapperToIterator() {
+ return this;
+ }
/**
* Creates a clone of the chained sequence planting `value` as the wrapped value.
*
* @name plant
* @memberOf _
- * @category Chain
+ * @category Seq
+ * @param {*} value The value to plant.
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
- * var array = [1, 2];
- * var wrapped = _(array).map(function(value) {
- * return Math.pow(value, 2);
- * });
+ * function square(n) {
+ * return n * n;
+ * }
*
- * var other = [3, 4];
- * var otherWrapped = wrapped.plant(other);
+ * var wrapped = _([1, 2]).map(square);
+ * var other = wrapped.plant([3, 4]);
*
- * otherWrapped.value();
+ * other.value();
* // => [9, 16]
*
* wrapped.value();
@@ -6039,6 +7207,8 @@
while (parent instanceof baseLodash) {
var clone = wrapperClone(parent);
+ clone.__index__ = 0;
+ clone.__values__ = undefined;
if (result) {
previous.__wrapped__ = clone;
} else {
@@ -6052,15 +7222,14 @@
}
/**
- * Reverses the wrapped array so the first element becomes the last, the
- * second element becomes the second to last, and so on.
+ * This method is the wrapper version of `_.reverse`.
*
* **Note:** This method mutates the wrapped array.
*
* @name reverse
* @memberOf _
- * @category Chain
- * @returns {Object} Returns the new reversed `lodash` wrapper instance.
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
* var array = [1, 2, 3];
@@ -6073,36 +7242,16 @@
*/
function wrapperReverse() {
var value = this.__wrapped__;
-
- var interceptor = function(value) {
- return value.reverse();
- };
if (value instanceof LazyWrapper) {
var wrapped = value;
if (this.__actions__.length) {
wrapped = new LazyWrapper(this);
}
wrapped = wrapped.reverse();
- wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
+ wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined });
return new LodashWrapper(wrapped, this.__chain__);
}
- return this.thru(interceptor);
- }
-
- /**
- * Produces the result of coercing the unwrapped value to a string.
- *
- * @name toString
- * @memberOf _
- * @category Chain
- * @returns {string} Returns the coerced string value.
- * @example
- *
- * _([1, 2, 3]).toString();
- * // => '1,2,3'
- */
- function wrapperToString() {
- return (this.value() + '');
+ return this.thru(reverse);
}
/**
@@ -6111,7 +7260,7 @@
* @name value
* @memberOf _
* @alias run, toJSON, valueOf
- * @category Chain
+ * @category Seq
* @returns {*} Returns the resolved unwrapped value.
* @example
*
@@ -6124,66 +7273,21 @@
/*------------------------------------------------------------------------*/
- /**
- * Creates an array of elements corresponding to the given keys, or indexes,
- * of `collection`. Keys may be specified as individual arguments or as arrays
- * of keys.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(number|number[]|string|string[])} [props] The property names
- * or indexes of elements to pick, specified individually or in arrays.
- * @returns {Array} Returns the new array of picked elements.
- * @example
- *
- * _.at(['a', 'b', 'c'], [0, 2]);
- * // => ['a', 'c']
- *
- * _.at(['barney', 'fred', 'pebbles'], 0, 2);
- * // => ['barney', 'pebbles']
- */
- var at = restParam(function(collection, props) {
- return baseAt(collection, baseFlatten(props));
- });
-
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` through `iteratee`. The corresponding value
* of each key is the number of times the key was returned by `iteratee`.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Object} Returns the composed aggregate object.
* @example
*
- * _.countBy([4.3, 6.1, 6.4], function(n) {
- * return Math.floor(n);
- * });
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy([4.3, 6.1, 6.4], function(n) {
- * return this.floor(n);
- * }, Math);
+ * _.countBy([6.1, 4.2, 6.3], Math.floor);
* // => { '4': 1, '6': 2 }
*
* _.countBy(['one', 'two', 'three'], 'length');
@@ -6195,30 +7299,16 @@
/**
* Checks if `predicate` returns truthy for **all** elements of `collection`.
- * The predicate is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * Iteration is stopped once `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
*
* @static
* @memberOf _
- * @alias all
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {boolean} Returns `true` if all elements pass the predicate check,
- * else `false`.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
* @example
*
* _.every([true, 1, null, 'yes'], Boolean);
@@ -6229,108 +7319,74 @@
* { 'user': 'fred', 'active': false }
* ];
*
- * // using the `_.matches` callback shorthand
+ * // using the `_.matches` iteratee shorthand
* _.every(users, { 'user': 'barney', 'active': false });
* // => false
*
- * // using the `_.matchesProperty` callback shorthand
- * _.every(users, 'active', false);
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.every(users, ['active', false]);
* // => true
*
- * // using the `_.property` callback shorthand
+ * // using the `_.property` iteratee shorthand
* _.every(users, 'active');
* // => false
*/
- function every(collection, predicate, thisArg) {
+ function every(collection, predicate, guard) {
var func = isArray(collection) ? arrayEvery : baseEvery;
- if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
+ if (guard && isIterateeCall(collection, predicate, guard)) {
predicate = undefined;
}
- if (typeof predicate != 'function' || thisArg !== undefined) {
- predicate = getCallback(predicate, thisArg, 3);
- }
- return func(collection, predicate);
+ return func(collection, getIteratee(predicate, 3));
}
/**
* Iterates over elements of `collection`, returning an array of all elements
- * `predicate` returns truthy for. The predicate is bound to `thisArg` and
- * invoked with three arguments: (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * `predicate` returns truthy for. The predicate is invoked with three arguments:
+ * (value, index|key, collection).
*
* @static
* @memberOf _
- * @alias select
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
* @example
*
- * _.filter([4, 5, 6], function(n) {
- * return n % 2 == 0;
- * });
- * // => [4, 6]
- *
* var users = [
* { 'user': 'barney', 'age': 36, 'active': true },
* { 'user': 'fred', 'age': 40, 'active': false }
* ];
*
- * // using the `_.matches` callback shorthand
- * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user');
- * // => ['barney']
+ * _.filter(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
*
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.filter(users, 'active', false), 'user');
- * // => ['fred']
+ * // using the `_.matches` iteratee shorthand
+ * _.filter(users, { 'age': 36, 'active': true });
+ * // => objects for ['barney']
*
- * // using the `_.property` callback shorthand
- * _.pluck(_.filter(users, 'active'), 'user');
- * // => ['barney']
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.filter(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.filter(users, 'active');
+ * // => objects for ['barney']
*/
- function filter(collection, predicate, thisArg) {
+ function filter(collection, predicate) {
var func = isArray(collection) ? arrayFilter : baseFilter;
- predicate = getCallback(predicate, thisArg, 3);
- return func(collection, predicate);
+ return func(collection, getIteratee(predicate, 3));
}
/**
* Iterates over elements of `collection`, returning the first element
- * `predicate` returns truthy for. The predicate is bound to `thisArg` and
- * invoked with three arguments: (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * `predicate` returns truthy for. The predicate is invoked with three arguments:
+ * (value, index|key, collection).
*
* @static
* @memberOf _
- * @alias detect
* @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Array|Object} collection The collection to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {*} Returns the matched element, else `undefined`.
* @example
*
@@ -6340,24 +7396,29 @@
* { 'user': 'pebbles', 'age': 1, 'active': true }
* ];
*
- * _.result(_.find(users, function(chr) {
- * return chr.age < 40;
- * }), 'user');
- * // => 'barney'
+ * _.find(users, function(o) { return o.age < 40; });
+ * // => object for 'barney'
*
- * // using the `_.matches` callback shorthand
- * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');
- * // => 'pebbles'
+ * // using the `_.matches` iteratee shorthand
+ * _.find(users, { 'age': 1, 'active': true });
+ * // => object for 'pebbles'
*
- * // using the `_.matchesProperty` callback shorthand
- * _.result(_.find(users, 'active', false), 'user');
- * // => 'fred'
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.find(users, ['active', false]);
+ * // => object for 'fred'
*
- * // using the `_.property` callback shorthand
- * _.result(_.find(users, 'active'), 'user');
- * // => 'barney'
+ * // using the `_.property` iteratee shorthand
+ * _.find(users, 'active');
+ * // => object for 'barney'
*/
- var find = createFind(baseEach);
+ function find(collection, predicate) {
+ predicate = getIteratee(predicate, 3);
+ if (isArray(collection)) {
+ var index = baseFindIndex(collection, predicate);
+ return index > -1 ? collection[index] : undefined;
+ }
+ return baseFind(collection, predicate, baseEach);
+ }
/**
* This method is like `_.find` except that it iterates over elements of
@@ -6366,10 +7427,8 @@
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Array|Object} collection The collection to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {*} Returns the matched element, else `undefined`.
* @example
*
@@ -6378,72 +7437,48 @@
* });
* // => 3
*/
- var findLast = createFind(baseEachRight, true);
-
- /**
- * Performs a deep comparison between each element in `collection` and the
- * source object, returning the first element that has equivalent property
- * values.
- *
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties. For comparing a single
- * own or inherited property value see `_.matchesProperty`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {Object} source The object of property values to match.
- * @returns {*} Returns the matched element, else `undefined`.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': true },
- * { 'user': 'fred', 'age': 40, 'active': false }
- * ];
- *
- * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user');
- * // => 'barney'
- *
- * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user');
- * // => 'fred'
- */
- function findWhere(collection, source) {
- return find(collection, baseMatches(source));
+ function findLast(collection, predicate) {
+ predicate = getIteratee(predicate, 3);
+ if (isArray(collection)) {
+ var index = baseFindIndex(collection, predicate, true);
+ return index > -1 ? collection[index] : undefined;
+ }
+ return baseFind(collection, predicate, baseEachRight);
}
/**
* Iterates over elements of `collection` invoking `iteratee` for each element.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection). Iteratee functions may exit iteration early
- * by explicitly returning `false`.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
*
* **Note:** As with other "Collections" methods, objects with a "length" property
- * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
- * may be used for object iteration.
+ * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
+ * for object iteration.
*
* @static
* @memberOf _
* @alias each
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array|Object|string} Returns `collection`.
+ * @returns {Array|Object} Returns `collection`.
* @example
*
- * _([1, 2]).forEach(function(n) {
- * console.log(n);
- * }).value();
- * // => logs each value from left to right and returns the array
- *
- * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
- * console.log(n, key);
+ * _([1, 2]).forEach(function(value) {
+ * console.log(value);
* });
- * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
+ * // => logs `1` then `2`
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
+ * console.log(key);
+ * });
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
*/
- var forEach = createForEach(arrayEach, baseEach);
+ function forEach(collection, iteratee) {
+ return (typeof iteratee == 'function' && isArray(collection))
+ ? arrayEach(collection, iteratee)
+ : baseEach(collection, toFunction(iteratee));
+ }
/**
* This method is like `_.forEach` except that it iterates over elements of
@@ -6453,58 +7488,40 @@
* @memberOf _
* @alias eachRight
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array|Object|string} Returns `collection`.
+ * @returns {Array|Object} Returns `collection`.
* @example
*
- * _([1, 2]).forEachRight(function(n) {
- * console.log(n);
- * }).value();
- * // => logs each value from right to left and returns the array
+ * _.forEachRight([1, 2], function(value) {
+ * console.log(value);
+ * });
+ * // => logs `2` then `1`
*/
- var forEachRight = createForEach(arrayEachRight, baseEachRight);
+ function forEachRight(collection, iteratee) {
+ return (typeof iteratee == 'function' && isArray(collection))
+ ? arrayEachRight(collection, iteratee)
+ : baseEachRight(collection, toFunction(iteratee));
+ }
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` through `iteratee`. The corresponding value
* of each key is an array of the elements responsible for generating the key.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Object} Returns the composed aggregate object.
* @example
*
- * _.groupBy([4.2, 6.1, 6.4], function(n) {
- * return Math.floor(n);
- * });
- * // => { '4': [4.2], '6': [6.1, 6.4] }
+ * _.groupBy([6.1, 4.2, 6.3], Math.floor);
+ * // => { '4': [4.2], '6': [6.1, 6.3] }
*
- * _.groupBy([4.2, 6.1, 6.4], function(n) {
- * return this.floor(n);
- * }, Math);
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * // using the `_.property` callback shorthand
+ * // using the `_.property` iteratee shorthand
* _.groupBy(['one', 'two', 'three'], 'length');
* // => { '3': ['one', 'two'], '5': ['three'] }
*/
@@ -6517,20 +7534,19 @@
});
/**
- * Checks if `target` is in `collection` using
- * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons. If `fromIndex` is negative, it's used as the offset
- * from the end of `collection`.
+ * Checks if `value` is in `collection`. If `collection` is a string it's checked
+ * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * is used for equality comparisons. If `fromIndex` is negative, it's used as
+ * the offset from the end of `collection`.
*
* @static
* @memberOf _
- * @alias contains, include
* @category Collection
* @param {Array|Object|string} collection The collection to search.
- * @param {*} target The value to search for.
+ * @param {*} value The value to search for.
* @param {number} [fromIndex=0] The index to search from.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
- * @returns {boolean} Returns `true` if a matching element is found, else `false`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
+ * @returns {boolean} Returns `true` if `value` is found, else `false`.
* @example
*
* _.includes([1, 2, 3], 1);
@@ -6545,71 +7561,18 @@
* _.includes('pebbles', 'eb');
* // => true
*/
- function includes(collection, target, fromIndex, guard) {
- var length = collection ? getLength(collection) : 0;
- if (!isLength(length)) {
- collection = values(collection);
- length = collection.length;
- }
- 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)
- : (!!length && getIndexOf(collection, target, fromIndex) > -1);
- }
+ function includes(collection, value, fromIndex, guard) {
+ collection = isArrayLike(collection) ? collection : values(collection);
+ fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through `iteratee`. The corresponding value
- * of each key is the last element responsible for generating the key. The
- * iteratee function is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * var keyData = [
- * { 'dir': 'left', 'code': 97 },
- * { 'dir': 'right', 'code': 100 }
- * ];
- *
- * _.indexBy(keyData, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(keyData, function(object) {
- * return String.fromCharCode(object.code);
- * });
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(keyData, function(object) {
- * return this.fromCharCode(object.code);
- * }, String);
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- */
- var indexBy = createAggregator(function(result, value, key) {
- result[key] = value;
- });
+ var length = collection.length;
+ if (fromIndex < 0) {
+ fromIndex = nativeMax(length + fromIndex, 0);
+ }
+ return isString(collection)
+ ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
+ : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
+ }
/**
* Invokes the method at `path` of each element in `collection`, returning
@@ -6620,20 +7583,20 @@
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Array|Function|string} path The path of the method to invoke or
* the function invoked per iteration.
- * @param {...*} [args] The arguments to invoke the method with.
+ * @param {...*} [args] The arguments to invoke each method with.
* @returns {Array} Returns the array of results.
* @example
*
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
+ * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
* // => [[1, 5, 7], [1, 2, 3]]
*
- * _.invoke([123, 456], String.prototype.split, '');
+ * _.invokeMap([123, 456], String.prototype.split, '');
* // => [['1', '2', '3'], ['4', '5', '6']]
*/
- var invoke = restParam(function(collection, path, args) {
+ var invokeMap = rest(function(collection, path, args) {
var index = -1,
isFunc = typeof path == 'function',
isProp = isKey(path),
@@ -6641,56 +7604,72 @@
baseEach(collection, function(value) {
var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
- result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);
+ result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
});
return result;
});
+ /**
+ * Creates an object composed of keys generated from the results of running
+ * each element of `collection` through `iteratee`. The corresponding value
+ * of each key is the last element responsible for generating the key. The
+ * iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Object} Returns the composed aggregate object.
+ * @example
+ *
+ * var keyData = [
+ * { 'dir': 'left', 'code': 97 },
+ * { 'dir': 'right', 'code': 100 }
+ * ];
+ *
+ * _.keyBy(keyData, 'dir');
+ * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
+ *
+ * _.keyBy(keyData, function(o) {
+ * return String.fromCharCode(o.code);
+ * });
+ * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+ */
+ var keyBy = createAggregator(function(result, value, key) {
+ result[key] = value;
+ });
+
/**
* Creates an array of values by running each element in `collection` through
- * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * `iteratee`. The iteratee is invoked with three arguments:
+ * (value, index|key, collection).
*
* Many lodash methods are guarded to work as iteratees for methods like
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
*
* The guarded methods are:
- * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
- * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
- * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
- * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
- * `sum`, `uniq`, and `words`
+ * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
+ * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
+ * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
+ * and `words`
*
* @static
* @memberOf _
- * @alias collect
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
* @example
*
- * function timesThree(n) {
- * return n * 3;
+ * function square(n) {
+ * return n * n;
* }
*
- * _.map([1, 2], timesThree);
+ * _.map([1, 2], square);
* // => [3, 6]
*
- * _.map({ 'a': 1, 'b': 2 }, timesThree);
+ * _.map({ 'a': 1, 'b': 2 }, square);
* // => [3, 6] (iteration order is not guaranteed)
*
* var users = [
@@ -6698,144 +7677,136 @@
* { 'user': 'fred' }
* ];
*
- * // using the `_.property` callback shorthand
+ * // using the `_.property` iteratee shorthand
* _.map(users, 'user');
* // => ['barney', 'fred']
*/
- function map(collection, iteratee, thisArg) {
+ function map(collection, iteratee) {
var func = isArray(collection) ? arrayMap : baseMap;
- iteratee = getCallback(iteratee, thisArg, 3);
- return func(collection, iteratee);
+ return func(collection, getIteratee(iteratee, 3));
+ }
+
+ /**
+ * This method is like `_.sortBy` except that it allows specifying the sort
+ * orders of the iteratees to sort by. If `orders` is unspecified, all values
+ * are sorted in ascending order. Otherwise, specify an order of "desc" for
+ * descending or "asc" for ascending sort order of corresponding values.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
+ * @param {string[]} [orders] The sort orders of `iteratees`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'fred', 'age': 48 },
+ * { 'user': 'barney', 'age': 34 },
+ * { 'user': 'fred', 'age': 42 },
+ * { 'user': 'barney', 'age': 36 }
+ * ];
+ *
+ * // sort by `user` in ascending order and by `age` in descending order
+ * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
+ */
+ function orderBy(collection, iteratees, orders, guard) {
+ if (collection == null) {
+ return [];
+ }
+ if (!isArray(iteratees)) {
+ iteratees = iteratees == null ? [] : [iteratees];
+ }
+ orders = guard ? undefined : orders;
+ if (!isArray(orders)) {
+ orders = orders == null ? [] : [orders];
+ }
+ return baseOrderBy(collection, iteratees, orders);
}
/**
* Creates an array of elements split into two groups, the first of which
* contains elements `predicate` returns truthy for, while the second of which
- * contains elements `predicate` returns falsey for. The predicate is bound
- * to `thisArg` and invoked with three arguments: (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * contains elements `predicate` returns falsey for. The predicate is invoked
+ * with three arguments: (value, index|key, collection).
*
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the array of grouped elements.
* @example
*
- * _.partition([1, 2, 3], function(n) {
- * return n % 2;
- * });
- * // => [[1, 3], [2]]
- *
- * _.partition([1.2, 2.3, 3.4], function(n) {
- * return this.floor(n) % 2;
- * }, Math);
- * // => [[1.2, 3.4], [2.3]]
- *
* var users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': true },
* { 'user': 'pebbles', 'age': 1, 'active': false }
* ];
*
- * var mapper = function(array) {
- * return _.pluck(array, 'user');
- * };
+ * _.partition(users, function(o) { return o.active; });
+ * // => objects for [['fred'], ['barney', 'pebbles']]
*
- * // using the `_.matches` callback shorthand
- * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper);
- * // => [['pebbles'], ['barney', 'fred']]
+ * // using the `_.matches` iteratee shorthand
+ * _.partition(users, { 'age': 1, 'active': false });
+ * // => objects for [['pebbles'], ['barney', 'fred']]
*
- * // using the `_.matchesProperty` callback shorthand
- * _.map(_.partition(users, 'active', false), mapper);
- * // => [['barney', 'pebbles'], ['fred']]
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.partition(users, ['active', false]);
+ * // => objects for [['barney', 'pebbles'], ['fred']]
*
- * // using the `_.property` callback shorthand
- * _.map(_.partition(users, 'active'), mapper);
- * // => [['fred'], ['barney', 'pebbles']]
+ * // using the `_.property` iteratee shorthand
+ * _.partition(users, 'active');
+ * // => objects for [['fred'], ['barney', 'pebbles']]
*/
var partition = createAggregator(function(result, value, key) {
result[key ? 0 : 1].push(value);
}, function() { return [[], []]; });
- /**
- * Gets the property value of `path` from all elements in `collection`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Array|string} path The path of the property to pluck.
- * @returns {Array} Returns the property values.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 }
- * ];
- *
- * _.pluck(users, 'user');
- * // => ['barney', 'fred']
- *
- * var userIndex = _.indexBy(users, 'user');
- * _.pluck(userIndex, 'age');
- * // => [36, 40] (iteration order is not guaranteed)
- */
- function pluck(collection, path) {
- return map(collection, property(path));
- }
-
/**
* Reduces `collection` to a value which is the accumulated result of running
* each element in `collection` through `iteratee`, where each successive
* invocation is supplied the return value of the previous. If `accumulator`
* is not provided the first element of `collection` is used as the initial
- * value. The `iteratee` is bound to `thisArg` and invoked with four arguments:
+ * value. The iteratee is invoked with four arguments:
* (accumulator, value, index|key, collection).
*
* Many lodash methods are guarded to work as iteratees for methods like
* `_.reduce`, `_.reduceRight`, and `_.transform`.
*
* The guarded methods are:
- * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`,
- * and `sortByOrder`
+ * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
+ * and `sortBy`
*
* @static
* @memberOf _
- * @alias foldl, inject
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {*} Returns the accumulated value.
* @example
*
- * _.reduce([1, 2], function(total, n) {
- * return total + n;
+ * _.reduce([1, 2], function(sum, n) {
+ * return sum + n;
* });
* // => 3
*
- * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) {
- * result[key] = n * 3;
+ * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
* return result;
* }, {});
- * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)
+ * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
*/
- var reduce = createReduce(arrayReduce, baseEach);
+ function reduce(collection, iteratee, accumulator) {
+ var func = isArray(collection) ? arrayReduce : baseReduce,
+ initFromCollection = arguments.length < 3;
+
+ return func(collection, getIteratee(iteratee, 4), accumulator, initFromCollection, baseEach);
+ }
/**
* This method is like `_.reduce` except that it iterates over elements of
@@ -6843,12 +7814,10 @@
*
* @static
* @memberOf _
- * @alias foldr
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {*} Returns the accumulated value.
* @example
*
@@ -6859,7 +7828,12 @@
* }, []);
* // => [4, 5, 2, 3, 0, 1]
*/
- var reduceRight = createReduce(arrayReduceRight, baseEachRight);
+ function reduceRight(collection, iteratee, accumulator) {
+ var func = isArray(collection) ? arrayReduceRight : baseReduce,
+ initFromCollection = arguments.length < 3;
+
+ return func(collection, getIteratee(iteratee, 4), accumulator, initFromCollection, baseEachRight);
+ }
/**
* The opposite of `_.filter`; this method returns the elements of `collection`
@@ -6868,73 +7842,80 @@
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
* @example
*
- * _.reject([1, 2, 3, 4], function(n) {
- * return n % 2 == 0;
- * });
- * // => [1, 3]
- *
* var users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': true }
* ];
*
- * // using the `_.matches` callback shorthand
- * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user');
- * // => ['barney']
+ * _.reject(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
*
- * // using the `_.matchesProperty` callback shorthand
- * _.pluck(_.reject(users, 'active', false), 'user');
- * // => ['fred']
+ * // using the `_.matches` iteratee shorthand
+ * _.reject(users, { 'age': 40, 'active': true });
+ * // => objects for ['barney']
*
- * // using the `_.property` callback shorthand
- * _.pluck(_.reject(users, 'active'), 'user');
- * // => ['barney']
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.reject(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.reject(users, 'active');
+ * // => objects for ['barney']
*/
- function reject(collection, predicate, thisArg) {
+ function reject(collection, predicate) {
var func = isArray(collection) ? arrayFilter : baseFilter;
- predicate = getCallback(predicate, thisArg, 3);
+ predicate = getIteratee(predicate, 3);
return func(collection, function(value, index, collection) {
return !predicate(value, index, collection);
});
}
/**
- * Gets a random element or `n` random elements from a collection.
+ * Gets a random element from `collection`.
*
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to sample.
- * @param {number} [n] The number of elements to sample.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {*} Returns the random sample(s).
+ * @param {Array|Object} collection The collection to sample.
+ * @returns {*} Returns the random element.
* @example
*
* _.sample([1, 2, 3, 4]);
* // => 2
+ */
+ function sample(collection) {
+ var array = isArrayLike(collection) ? collection : values(collection),
+ length = array.length;
+
+ return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
+ }
+
+ /**
+ * Gets `n` random elements from `collection`.
*
- * _.sample([1, 2, 3, 4], 2);
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to sample.
+ * @param {number} [n=0] The number of elements to sample.
+ * @returns {Array} Returns the random elements.
+ * @example
+ *
+ * _.sampleSize([1, 2, 3, 4], 2);
* // => [3, 1]
*/
- function sample(collection, n, guard) {
- if (guard ? isIterateeCall(collection, n, guard) : n == null) {
- collection = toIterable(collection);
- var length = collection.length;
- return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;
- }
+ function sampleSize(collection, n) {
var index = -1,
result = toArray(collection),
length = result.length,
lastIndex = length - 1;
- n = nativeMin(n < 0 ? 0 : (+n || 0), length);
+ n = baseClamp(toInteger(n), 0, length);
while (++index < n) {
var rand = baseRandom(index, lastIndex),
value = result[rand];
@@ -6953,7 +7934,7 @@
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to shuffle.
+ * @param {Array|Object} collection The collection to shuffle.
* @returns {Array} Returns the new shuffled array.
* @example
*
@@ -6961,7 +7942,7 @@
* // => [4, 1, 3, 2]
*/
function shuffle(collection) {
- return sample(collection, POSITIVE_INFINITY);
+ return sampleSize(collection, MAX_ARRAY_LENGTH);
}
/**
@@ -6971,8 +7952,8 @@
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to inspect.
- * @returns {number} Returns the size of `collection`.
+ * @param {Array|Object} collection The collection to inspect.
+ * @returns {number} Returns the collection size.
* @example
*
* _.size([1, 2, 3]);
@@ -6985,37 +7966,28 @@
* // => 7
*/
function size(collection) {
- var length = collection ? getLength(collection) : 0;
- return isLength(length) ? length : keys(collection).length;
+ if (collection == null) {
+ return 0;
+ }
+ if (isArrayLike(collection)) {
+ var result = collection.length;
+ return (result && isString(collection)) ? stringSize(collection) : result;
+ }
+ return keys(collection).length;
}
/**
* Checks if `predicate` returns truthy for **any** element of `collection`.
- * The function returns as soon as it finds a passing value and does not iterate
- * over the entire collection. The predicate is bound to `thisArg` and invoked
- * with three arguments: (value, index|key, collection).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * Iteration is stopped once `predicate` returns truthy. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
*
* @static
* @memberOf _
- * @alias any
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {boolean} Returns `true` if any element passes the predicate check,
- * else `false`.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
* @example
*
* _.some([null, 0, 'yes', false], Boolean);
@@ -7026,110 +7998,38 @@
* { 'user': 'fred', 'active': false }
* ];
*
- * // using the `_.matches` callback shorthand
+ * // using the `_.matches` iteratee shorthand
* _.some(users, { 'user': 'barney', 'active': false });
* // => false
*
- * // using the `_.matchesProperty` callback shorthand
- * _.some(users, 'active', false);
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.some(users, ['active', false]);
* // => true
*
- * // using the `_.property` callback shorthand
+ * // using the `_.property` iteratee shorthand
* _.some(users, 'active');
* // => true
*/
- function some(collection, predicate, thisArg) {
+ function some(collection, predicate, guard) {
var func = isArray(collection) ? arraySome : baseSome;
- if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
+ if (guard && isIterateeCall(collection, predicate, guard)) {
predicate = undefined;
}
- if (typeof predicate != 'function' || thisArg !== undefined) {
- predicate = getCallback(predicate, thisArg, 3);
- }
- return func(collection, predicate);
+ return func(collection, getIteratee(predicate, 3));
}
/**
* Creates an array of elements, sorted in ascending order by the results of
- * running each element in a collection through `iteratee`. This method performs
- * a stable sort, that is, it preserves the original sort order of equal elements.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
- * (value, index|key, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * running each element in a collection through each iteratee. This method
+ * performs a stable sort, that is, it preserves the original sort order of
+ * equal elements. The iteratees are invoked with one argument: (value).
*
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the new sorted array.
- * @example
- *
- * _.sortBy([1, 2, 3], function(n) {
- * return Math.sin(n);
- * });
- * // => [3, 1, 2]
- *
- * _.sortBy([1, 2, 3], function(n) {
- * return this.sin(n);
- * }, Math);
- * // => [3, 1, 2]
- *
- * var users = [
- * { 'user': 'fred' },
- * { 'user': 'pebbles' },
- * { 'user': 'barney' }
- * ];
- *
- * // using the `_.property` callback shorthand
- * _.pluck(_.sortBy(users, 'user'), 'user');
- * // => ['barney', 'fred', 'pebbles']
- */
- function sortBy(collection, iteratee, thisArg) {
- if (collection == null) {
- return [];
- }
- if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = undefined;
- }
- var index = -1;
- iteratee = getCallback(iteratee, thisArg, 3);
-
- var result = baseMap(collection, function(value, key, collection) {
- return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value };
- });
- return baseSortBy(result, compareAscending);
- }
-
- /**
- * This method is like `_.sortBy` except that it can sort by multiple iteratees
- * or property names.
- *
- * If a property name is provided for an iteratee the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If an object is provided for an iteratee the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees
- * The iteratees to sort by, specified as individual values or arrays of values.
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
+ * The iteratees to sort by, specified individually or in arrays.
* @returns {Array} Returns the new sorted array.
* @example
*
@@ -7140,117 +8040,41 @@
* { 'user': 'barney', 'age': 34 }
* ];
*
- * _.map(_.sortByAll(users, ['user', 'age']), _.values);
- * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
+ * _.sortBy(users, function(o) { return o.user; });
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
*
- * _.map(_.sortByAll(users, 'user', function(chr) {
- * return Math.floor(chr.age / 10);
- * }), _.values);
- * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
+ * _.sortBy(users, ['user', 'age']);
+ * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
+ *
+ * _.sortBy(users, 'user', function(o) {
+ * return Math.floor(o.age / 10);
+ * });
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
*/
- var sortByAll = restParam(function(collection, iteratees) {
+ var sortBy = rest(function(collection, iteratees) {
if (collection == null) {
return [];
}
- var guard = iteratees[2];
- if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) {
+ var length = iteratees.length;
+ if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
+ iteratees = [];
+ } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
iteratees.length = 1;
}
- return baseSortByOrder(collection, baseFlatten(iteratees), []);
+ return baseOrderBy(collection, baseFlatten(iteratees), []);
});
- /**
- * This method is like `_.sortByAll` except that it allows specifying the
- * 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.
- *
- * If an object is provided for an iteratee the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @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- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
- * @returns {Array} Returns the new sorted array.
- * @example
- *
- * var users = [
- * { 'user': 'fred', 'age': 48 },
- * { 'user': 'barney', 'age': 34 },
- * { 'user': 'fred', 'age': 42 },
- * { 'user': 'barney', 'age': 36 }
- * ];
- *
- * // sort by `user` in ascending order and by `age` in descending order
- * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values);
- * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
- */
- function sortByOrder(collection, iteratees, orders, guard) {
- if (collection == null) {
- return [];
- }
- if (guard && isIterateeCall(iteratees, orders, guard)) {
- orders = undefined;
- }
- if (!isArray(iteratees)) {
- iteratees = iteratees == null ? [] : [iteratees];
- }
- if (!isArray(orders)) {
- orders = orders == null ? [] : [orders];
- }
- return baseSortByOrder(collection, iteratees, orders);
- }
-
- /**
- * Performs a deep comparison between each element in `collection` and the
- * source object, returning an array of all elements that have equivalent
- * property values.
- *
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties. For comparing a single
- * own or inherited property value see `_.matchesProperty`.
- *
- * @static
- * @memberOf _
- * @category Collection
- * @param {Array|Object|string} collection The collection to search.
- * @param {Object} source The object of property values to match.
- * @returns {Array} Returns the new filtered array.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] },
- * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user');
- * // => ['barney']
- *
- * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user');
- * // => ['fred']
- */
- function where(collection, source) {
- return filter(collection, baseMatches(source));
- }
-
/*------------------------------------------------------------------------*/
/**
- * Gets the number of milliseconds that have elapsed since the Unix epoch
- * (1 January 1970 00:00:00 UTC).
+ * Gets the timestamp of the number of milliseconds that have elapsed since
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
+ * @type Function
* @category Date
+ * @returns {number} Returns the timestamp.
* @example
*
* _.defer(function(stamp) {
@@ -7258,9 +8082,7 @@
* }, _.now());
* // => logs the number of milliseconds it took for the deferred function to be invoked
*/
- var now = nativeNow || function() {
- return new Date().getTime();
- };
+ var now = Date.now;
/*------------------------------------------------------------------------*/
@@ -7289,15 +8111,9 @@
*/
function after(n, func) {
if (typeof func != 'function') {
- if (typeof n == 'function') {
- var temp = n;
- n = func;
- func = temp;
- } else {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
+ throw new TypeError(FUNC_ERROR_TEXT);
}
- n = nativeIsFinite(n = +n) ? n : 0;
+ n = toInteger(n);
return function() {
if (--n < 1) {
return func.apply(this, arguments);
@@ -7306,7 +8122,7 @@
}
/**
- * Creates a function that accepts up to `n` arguments ignoring any
+ * Creates a function that accepts up to `n` arguments, ignoring any
* additional arguments.
*
* @static
@@ -7314,7 +8130,7 @@
* @category Function
* @param {Function} func The function to cap arguments for.
* @param {number} [n=func.length] The arity cap.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the new function.
* @example
*
@@ -7322,10 +8138,8 @@
* // => [6, 8, 10]
*/
function ary(func, n, guard) {
- if (guard && isIterateeCall(func, n, guard)) {
- n = undefined;
- }
- n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);
+ n = guard ? undefined : n;
+ n = (func && n == null) ? func.length : n;
return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
}
@@ -7342,20 +8156,15 @@
* @returns {Function} Returns the new restricted function.
* @example
*
- * jQuery('#add').on('click', _.before(5, addContactToList));
+ * jQuery(element).on('click', _.before(5, addContactToList));
* // => allows adding up to 4 contacts to the list
*/
function before(n, func) {
var result;
if (typeof func != 'function') {
- if (typeof n == 'function') {
- var temp = n;
- n = func;
- func = temp;
- } else {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
+ throw new TypeError(FUNC_ERROR_TEXT);
}
+ n = toInteger(n);
return function() {
if (--n > 0) {
result = func.apply(this, arguments);
@@ -7375,7 +8184,7 @@
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for partially applied arguments.
*
- * **Note:** Unlike native `Function#bind` this method does not set the "length"
+ * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
* property of bound functions.
*
* @static
@@ -7402,7 +8211,7 @@
* bound('hi');
* // => 'hi fred!'
*/
- var bind = restParam(function(func, thisArg, partials) {
+ var bind = rest(function(func, thisArg, partials) {
var bitmask = BIND_FLAG;
if (partials.length) {
var holders = replaceHolders(partials, bind.placeholder);
@@ -7411,47 +8220,6 @@
return createWrapper(func, bitmask, thisArg, partials, holders);
});
- /**
- * Binds methods of an object to the object itself, overwriting the existing
- * method. Method names may be specified as individual arguments or as arrays
- * of method names. If no method names are provided all enumerable function
- * properties, own and inherited, of `object` are bound.
- *
- * **Note:** This method does not set the "length" property of bound functions.
- *
- * @static
- * @memberOf _
- * @category Function
- * @param {Object} object The object to bind and assign the bound methods to.
- * @param {...(string|string[])} [methodNames] The object method names to bind,
- * specified as individual method names or arrays of method names.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var view = {
- * 'label': 'docs',
- * 'onClick': function() {
- * console.log('clicked ' + this.label);
- * }
- * };
- *
- * _.bindAll(view);
- * jQuery('#docs').on('click', view.onClick);
- * // => logs 'clicked docs' when the element is clicked
- */
- var bindAll = restParam(function(object, methodNames) {
- methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object);
-
- var index = -1,
- length = methodNames.length;
-
- while (++index < length) {
- var key = methodNames[index];
- object[key] = createWrapper(object[key], BIND_FLAG, object);
- }
- return object;
- });
-
/**
* Creates a function that invokes the method at `object[key]` and prepends
* any additional `_.bindKey` arguments to those provided to the bound function.
@@ -7467,7 +8235,7 @@
* @static
* @memberOf _
* @category Function
- * @param {Object} object The object the method belongs to.
+ * @param {Object} object The object to invoke the method on.
* @param {string} key The key of the method.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
@@ -7496,7 +8264,7 @@
* bound('hi');
* // => 'hiya fred!'
*/
- var bindKey = restParam(function(object, key, partials) {
+ var bindKey = rest(function(object, key, partials) {
var bitmask = BIND_FLAG | BIND_KEY_FLAG;
if (partials.length) {
var holders = replaceHolders(partials, bindKey.placeholder);
@@ -7506,23 +8274,23 @@
});
/**
- * Creates a function that accepts one or more arguments of `func` that when
- * called either invokes `func` returning its result, if all `func` arguments
- * have been provided, or returns a function that accepts one or more of the
- * remaining `func` arguments, and so on. The arity of `func` may be specified
- * if `func.length` is not sufficient.
+ * Creates a function that accepts arguments of `func` and either invokes
+ * `func` returning its result, if at least `arity` number of arguments have
+ * been provided, or returns a function that accepts the remaining `func`
+ * arguments, and so on. The arity of `func` may be specified if `func.length`
+ * is not sufficient.
*
* The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for provided arguments.
*
- * **Note:** This method does not set the "length" property of curried functions.
+ * **Note:** This method doesn't set the "length" property of curried functions.
*
* @static
* @memberOf _
* @category Function
* @param {Function} func The function to curry.
* @param {number} [arity=func.length] The arity of `func`.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the new curried function.
* @example
*
@@ -7545,7 +8313,12 @@
* curried(1)(_, 3)(2);
* // => [1, 2, 3]
*/
- var curry = createCurry(CURRY_FLAG);
+ function curry(func, arity, guard) {
+ arity = guard ? undefined : arity;
+ var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
+ result.placeholder = curry.placeholder;
+ return result;
+ }
/**
* This method is like `_.curry` except that arguments are applied to `func`
@@ -7554,14 +8327,14 @@
* The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for provided arguments.
*
- * **Note:** This method does not set the "length" property of curried functions.
+ * **Note:** This method doesn't set the "length" property of curried functions.
*
* @static
* @memberOf _
* @category Function
* @param {Function} func The function to curry.
* @param {number} [arity=func.length] The arity of `func`.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the new curried function.
* @example
*
@@ -7584,16 +8357,22 @@
* curried(3)(1, _)(2);
* // => [1, 2, 3]
*/
- var curryRight = createCurry(CURRY_RIGHT_FLAG);
+ function curryRight(func, arity, guard) {
+ arity = guard ? undefined : arity;
+ var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
+ result.placeholder = curryRight.placeholder;
+ return result;
+ }
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
- * delayed invocations. Provide an options object to indicate that `func`
- * should be invoked on the leading and/or trailing edge of the `wait` timeout.
- * Subsequent calls to the debounced function return the result of the last
- * `func` invocation.
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
+ * Provide an options object to indicate whether `func` should be invoked on
+ * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
+ * with the last arguments provided to the debounced function. Subsequent calls
+ * to the debounced function return the result of the last `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
* on the trailing edge of the timeout only if the the debounced function is
@@ -7620,34 +8399,19 @@
* // avoid costly calculations while the window size is in flux
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
*
- * // invoke `sendMail` when the click event is fired, debouncing subsequent calls
- * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
+ * // invoke `sendMail` when clicked, debouncing subsequent calls
+ * jQuery(element).on('click', _.debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // ensure `batchLog` is invoked once after 1 second of debounced calls
+ * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
- * jQuery(source).on('message', _.debounce(batchLog, 250, {
- * 'maxWait': 1000
- * }));
+ * jQuery(source).on('message', debounced);
*
- * // cancel a debounced call
- * var todoChanges = _.debounce(batchLog, 1000);
- * Object.observe(models.todo, todoChanges);
- *
- * Object.observe(models, function(changes) {
- * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {
- * todoChanges.cancel();
- * }
- * }, ['delete']);
- *
- * // ...at some point `models.todo` is changed
- * models.todo.completed = true;
- *
- * // ...before 1 second has passed `models.todo` is deleted
- * // which cancels the debounced `todoChanges` call
- * delete models.todo;
+ * // cancel a trailing debounced invocation
+ * jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var args,
@@ -7658,19 +8422,17 @@
timeoutId,
trailingCall,
lastCalled = 0,
+ leading = false,
maxWait = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- wait = wait < 0 ? 0 : (+wait || 0);
- if (options === true) {
- var leading = true;
- trailing = false;
- } else if (isObject(options)) {
+ wait = toNumber(wait) || 0;
+ if (isObject(options)) {
leading = !!options.leading;
- maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
+ maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
@@ -7682,7 +8444,7 @@
clearTimeout(maxTimeoutId);
}
lastCalled = 0;
- maxTimeoutId = timeoutId = trailingCall = undefined;
+ args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
}
function complete(isCalled, id) {
@@ -7708,6 +8470,14 @@
}
}
+ function flush() {
+ if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
+ result = func.apply(thisArg, args);
+ }
+ cancel();
+ return result;
+ }
+
function maxDelayed() {
complete(trailing, timeoutId);
}
@@ -7754,6 +8524,7 @@
return result;
}
debounced.cancel = cancel;
+ debounced.flush = flush;
return debounced;
}
@@ -7765,7 +8536,7 @@
* @memberOf _
* @category Function
* @param {Function} func The function to defer.
- * @param {...*} [args] The arguments to invoke the function with.
+ * @param {...*} [args] The arguments to invoke `func` with.
* @returns {number} Returns the timer id.
* @example
*
@@ -7774,7 +8545,7 @@
* }, 'deferred');
* // logs 'deferred' after one or more milliseconds
*/
- var defer = restParam(function(func, args) {
+ var defer = rest(function(func, args) {
return baseDelay(func, 1, args);
});
@@ -7787,7 +8558,7 @@
* @category Function
* @param {Function} func The function to delay.
* @param {number} wait The number of milliseconds to delay invocation.
- * @param {...*} [args] The arguments to invoke the function with.
+ * @param {...*} [args] The arguments to invoke `func` with.
* @returns {number} Returns the timer id.
* @example
*
@@ -7796,66 +8567,42 @@
* }, 1000, 'later');
* // => logs 'later' after one second
*/
- var delay = restParam(function(func, wait, args) {
- return baseDelay(func, wait, args);
+ var delay = rest(function(func, wait, args) {
+ return baseDelay(func, toNumber(wait) || 0, args);
});
/**
- * Creates a function that returns the result of invoking the provided
- * functions with the `this` binding of the created function, where each
- * successive invocation is supplied the return value of the previous.
+ * Creates a function that invokes `func` with arguments reversed.
*
* @static
* @memberOf _
* @category Function
- * @param {...Function} [funcs] Functions to invoke.
+ * @param {Function} func The function to flip arguments for.
* @returns {Function} Returns the new function.
* @example
*
- * function square(n) {
- * return n * n;
- * }
+ * var flipped = _.flip(function() {
+ * return _.toArray(arguments);
+ * });
*
- * var addSquare = _.flow(_.add, square);
- * addSquare(1, 2);
- * // => 9
+ * flipped('a', 'b', 'c', 'd');
+ * // => ['d', 'c', 'b', 'a']
*/
- var flow = createFlow();
-
- /**
- * This method is like `_.flow` except that it creates a function that
- * invokes the provided functions from right to left.
- *
- * @static
- * @memberOf _
- * @alias backflow, compose
- * @category Function
- * @param {...Function} [funcs] Functions to invoke.
- * @returns {Function} Returns the new function.
- * @example
- *
- * function square(n) {
- * return n * n;
- * }
- *
- * var addSquare = _.flowRight(square, _.add);
- * addSquare(1, 2);
- * // => 9
- */
- var flowRight = createFlow(true);
+ function flip(func) {
+ return createWrapper(func, FLIP_FLAG);
+ }
/**
* Creates a function that memoizes the result of `func`. If `resolver` is
* provided it determines the cache key for storing the result based on the
* arguments provided to the memoized function. By default, the first argument
- * provided to the memoized function is coerced to a string and used as the
- * cache key. The `func` is invoked with the `this` binding of the memoized
- * function.
+ * provided to the memoized function is used as the map cache key. The `func`
+ * is invoked with the `this` binding of the memoized function.
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
* constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
- * method interface of `get`, `has`, and `set`.
+ * method interface of `delete`, `get`, `has`, and `set`.
*
* @static
* @memberOf _
@@ -7865,35 +8612,27 @@
* @returns {Function} Returns the new memoizing function.
* @example
*
- * var upperCase = _.memoize(function(string) {
- * return string.toUpperCase();
- * });
+ * var object = { 'a': 1, 'b': 2 };
+ * var other = { 'c': 3, 'd': 4 };
*
- * upperCase('fred');
- * // => 'FRED'
+ * var values = _.memoize(_.values);
+ * values(object);
+ * // => [1, 2]
+ *
+ * values(other);
+ * // => [3, 4]
+ *
+ * object.a = 2;
+ * values(object);
+ * // => [1, 2]
*
* // modifying the result cache
- * upperCase.cache.set('fred', 'BARNEY');
- * upperCase('fred');
- * // => 'BARNEY'
+ * values.cache.set(object, ['a', 'b']);
+ * values(object);
+ * // => ['a', 'b']
*
* // replacing `_.memoize.Cache`
- * var object = { 'user': 'fred' };
- * var other = { 'user': 'barney' };
- * var identity = _.memoize(_.identity);
- *
- * identity(object);
- * // => { 'user': 'fred' }
- * identity(other);
- * // => { 'user': 'fred' }
- *
* _.memoize.Cache = WeakMap;
- * var identity = _.memoize(_.identity);
- *
- * identity(object);
- * // => { 'user': 'fred' }
- * identity(other);
- * // => { 'user': 'barney' }
*/
function memoize(func, resolver) {
if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
@@ -7915,52 +8654,6 @@
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
@@ -7991,8 +8684,8 @@
/**
* Creates a function that is restricted to invoking `func` once. Repeat calls
- * to the function return the value of the first call. The `func` is invoked
- * with the `this` binding and arguments of the created function.
+ * to the function return the value of the first invocation. The `func` is
+ * invoked with the `this` binding and arguments of the created function.
*
* @static
* @memberOf _
@@ -8010,6 +8703,52 @@
return before(2, func);
}
+ /**
+ * Creates a function that invokes `func` with arguments transformed by
+ * corresponding `transforms`.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to wrap.
+ * @param {...(Function|Function[])} [transforms] The functions to transform
+ * arguments, specified individually or in arrays.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function doubled(n) {
+ * return n * 2;
+ * }
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var func = _.overArgs(function(x, y) {
+ * return [x, y];
+ * }, square, doubled);
+ *
+ * func(9, 3);
+ * // => [81, 6]
+ *
+ * func(10, 5);
+ * // => [100, 10]
+ */
+ var overArgs = rest(function(func, transforms) {
+ transforms = arrayMap(baseFlatten(transforms), getIteratee());
+
+ var funcsLength = transforms.length;
+ return rest(function(args) {
+ var index = -1,
+ length = nativeMin(args.length, funcsLength);
+
+ while (++index < length) {
+ args[index] = transforms[index].call(this, args[index]);
+ }
+ return apply(func, this, args);
+ });
+ });
+
/**
* Creates a function that invokes `func` with `partial` arguments prepended
* to those provided to the new function. This method is like `_.bind` except
@@ -8018,7 +8757,7 @@
* The `_.partial.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
- * **Note:** This method does not set the "length" property of partially
+ * **Note:** This method doesn't set the "length" property of partially
* applied functions.
*
* @static
@@ -8042,7 +8781,10 @@
* greetFred('hi');
* // => 'hi fred'
*/
- var partial = createPartial(PARTIAL_FLAG);
+ var partial = rest(function(func, partials) {
+ var holders = replaceHolders(partials, partial.placeholder);
+ return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
+ });
/**
* This method is like `_.partial` except that partially applied arguments
@@ -8051,7 +8793,7 @@
* The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
- * **Note:** This method does not set the "length" property of partially
+ * **Note:** This method doesn't set the "length" property of partially
* applied functions.
*
* @static
@@ -8075,7 +8817,10 @@
* sayHelloTo('fred');
* // => 'hello fred'
*/
- var partialRight = createPartial(PARTIAL_RIGHT_FLAG);
+ var partialRight = rest(function(func, partials) {
+ var holders = replaceHolders(partials, partialRight.placeholder);
+ return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
+ });
/**
* Creates a function that invokes `func` with arguments arranged according
@@ -8088,7 +8833,7 @@
* @category Function
* @param {Function} func The function to rearrange arguments for.
* @param {...(number|number[])} indexes The arranged argument indexes,
- * specified as individual indexes or arrays of indexes.
+ * specified individually or in arrays.
* @returns {Function} Returns the new function.
* @example
*
@@ -8098,14 +8843,8 @@
*
* rearged('b', 'c', 'a')
* // => ['a', 'b', 'c']
- *
- * var map = _.rearg(_.map, [1, 0]);
- * map(function(n) {
- * return n * 3;
- * }, [1, 2, 3]);
- * // => [3, 6, 9]
*/
- var rearg = restParam(function(func, indexes) {
+ var rearg = rest(function(func, indexes) {
return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
});
@@ -8113,7 +8852,7 @@
* Creates a function that invokes `func` with the `this` binding of the
* created function and arguments from `start` and beyond provided as an array.
*
- * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
+ * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
*
* @static
* @memberOf _
@@ -8123,7 +8862,7 @@
* @returns {Function} Returns the new function.
* @example
*
- * var say = _.restParam(function(what, names) {
+ * var say = _.rest(function(what, names) {
* return what + ' ' + _.initial(names).join(', ') +
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
* });
@@ -8131,32 +8870,32 @@
* say('hello', 'fred', 'barney', 'pebbles');
* // => 'hello fred, barney, & pebbles'
*/
- function restParam(func, start) {
+ function rest(func, start) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
+ start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
- rest = Array(length);
+ array = Array(length);
while (++index < length) {
- rest[index] = args[start + index];
+ array[index] = args[start + index];
}
switch (start) {
- case 0: return func.call(this, rest);
- case 1: return func.call(this, args[0], rest);
- case 2: return func.call(this, args[0], args[1], rest);
+ case 0: return func.call(this, array);
+ case 1: return func.call(this, args[0], array);
+ case 2: return func.call(this, args[0], args[1], array);
}
var otherArgs = Array(start + 1);
index = -1;
while (++index < start) {
otherArgs[index] = args[index];
}
- otherArgs[start] = rest;
- return func.apply(this, otherArgs);
+ otherArgs[start] = array;
+ return apply(func, this, otherArgs);
};
}
@@ -8164,7 +8903,7 @@
* Creates a function that invokes `func` with the `this` binding of the created
* function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
*
- * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/Web/JavaScript/Reference/Operators/Spread_operator).
+ * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
*
* @static
* @memberOf _
@@ -8196,17 +8935,19 @@
throw new TypeError(FUNC_ERROR_TEXT);
}
return function(array) {
- return func.apply(this, array);
+ return apply(func, this, array);
};
}
/**
* Creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds. The throttled function comes with a `cancel`
- * method to cancel delayed invocations. Provide an options object to indicate
- * that `func` should be invoked on the leading and/or trailing edge of the
- * `wait` timeout. Subsequent calls to the throttled function return the
- * result of the last `func` call.
+ * method to cancel delayed `func` invocations and a `flush` method to
+ * immediately invoke them. Provide an options object to indicate whether
+ * `func` should be invoked on the leading and/or trailing edge of the `wait`
+ * timeout. The `func` is invoked with the last arguments provided to the
+ * throttled function. Subsequent calls to the throttled function return the
+ * result of the last `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
* on the trailing edge of the timeout only if the the throttled function is
@@ -8232,11 +8973,10 @@
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
*
* // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
- * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
- * 'trailing': false
- * }));
+ * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
+ * jQuery(element).on('click', throttled);
*
- * // cancel a trailing throttled call
+ * // cancel a trailing throttled invocation
* jQuery(window).on('popstate', throttled.cancel);
*/
function throttle(func, wait, options) {
@@ -8246,13 +8986,29 @@
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- if (options === false) {
- leading = false;
- } else if (isObject(options)) {
+ if (isObject(options)) {
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
- return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
+ return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing });
+ }
+
+ /**
+ * Creates a function that accepts up to one argument, ignoring any
+ * additional arguments.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * _.map(['6', '8', '10'], _.unary(parseInt));
+ * // => [6, 8, 10]
+ */
+ function unary(func) {
+ return ary(func, 1);
}
/**
@@ -8278,125 +9034,154 @@
*/
function wrap(value, wrapper) {
wrapper = wrapper == null ? identity : wrapper;
- return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);
+ return partial(wrapper, value);
}
/*------------------------------------------------------------------------*/
/**
- * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned,
- * otherwise they are assigned by reference. If `customizer` is provided it's
- * invoked to produce the cloned values. If `customizer` returns `undefined`
- * cloning is handled by the method instead. The `customizer` is bound to
- * `thisArg` and invoked with up to three argument; (value [, index|key, object]).
+ * Creates a shallow clone of `value`.
*
* **Note:** This method is loosely based on the
- * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
- * The enumerable properties of `arguments` objects and objects created by
- * constructors other than `Object` are cloned to plain `Object` objects. An
- * empty object is returned for uncloneable values such as functions, DOM nodes,
- * Maps, Sets, and WeakMaps.
+ * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
+ * and supports cloning arrays, array buffers, booleans, date objects, maps,
+ * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
+ * arrays. The own enumerable properties of `arguments` objects are cloned
+ * as plain objects. An empty object is returned for uncloneable values such
+ * as error objects, functions, DOM nodes, and WeakMaps.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to clone.
- * @param {boolean} [isDeep] Specify a deep clone.
- * @param {Function} [customizer] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `customizer`.
* @returns {*} Returns the cloned value.
* @example
*
- * var users = [
- * { 'user': 'barney' },
- * { 'user': 'fred' }
- * ];
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
*
- * var shallow = _.clone(users);
- * shallow[0] === users[0];
+ * var shallow = _.clone(objects);
+ * console.log(shallow[0] === objects[0]);
* // => true
- *
- * var deep = _.clone(users, true);
- * deep[0] === users[0];
- * // => false
- *
- * // using a customizer callback
- * var el = _.clone(document.body, function(value) {
- * if (_.isElement(value)) {
- * return value.cloneNode(false);
- * }
- * });
- *
- * el === document.body
- * // => false
- * el.nodeName
- * // => BODY
- * el.childNodes.length;
- * // => 0
*/
- function clone(value, isDeep, customizer, thisArg) {
- if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {
- isDeep = false;
- }
- else if (typeof isDeep == 'function') {
- thisArg = customizer;
- customizer = isDeep;
- isDeep = false;
- }
- return typeof customizer == 'function'
- ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 3))
- : baseClone(value, isDeep);
+ function clone(value) {
+ return baseClone(value);
}
/**
- * Creates a deep clone of `value`. If `customizer` is provided it's invoked
- * to produce the cloned values. If `customizer` returns `undefined` cloning
- * is handled by the method instead. The `customizer` is bound to `thisArg`
- * and invoked with up to three argument; (value [, index|key, object]).
- *
- * **Note:** This method is loosely based on the
- * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
- * The enumerable properties of `arguments` objects and objects created by
- * constructors other than `Object` are cloned to plain `Object` objects. An
- * empty object is returned for uncloneable values such as functions, DOM nodes,
- * Maps, Sets, and WeakMaps.
+ * This method is like `_.clone` except that it accepts `customizer` which
+ * is invoked to produce the cloned value. If `customizer` returns `undefined`
+ * cloning is handled by the method instead. The `customizer` is invoked with
+ * up to five arguments; (value [, index|key, object, stack]).
*
* @static
* @memberOf _
* @category Lang
- * @param {*} value The value to deep clone.
- * @param {Function} [customizer] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `customizer`.
+ * @param {*} value The value to clone.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @returns {*} Returns the cloned value.
+ * @example
+ *
+ * function customizer(value) {
+ * if (_.isElement(value)) {
+ * return value.cloneNode(false);
+ * }
+ * }
+ *
+ * var el = _.clone(document.body, customizer);
+ *
+ * console.log(el === document.body);
+ * // => false
+ * console.log(el.nodeName);
+ * // => 'BODY'
+ * console.log(el.childNodes.length);
+ * // => 0
+ */
+ function cloneWith(value, customizer) {
+ return baseClone(value, false, customizer);
+ }
+
+ /**
+ * This method is like `_.clone` except that it recursively clones `value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to recursively clone.
* @returns {*} Returns the deep cloned value.
* @example
*
- * var users = [
- * { 'user': 'barney' },
- * { 'user': 'fred' }
- * ];
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
*
- * var deep = _.cloneDeep(users);
- * deep[0] === users[0];
+ * var deep = _.cloneDeep(objects);
+ * console.log(deep[0] === objects[0]);
* // => false
+ */
+ function cloneDeep(value) {
+ return baseClone(value, true);
+ }
+
+ /**
+ * This method is like `_.cloneWith` except that it recursively clones `value`.
*
- * // using a customizer callback
- * var el = _.cloneDeep(document.body, function(value) {
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to recursively clone.
+ * @param {Function} [customizer] The function to customize cloning.
+ * @returns {*} Returns the deep cloned value.
+ * @example
+ *
+ * function customizer(value) {
* if (_.isElement(value)) {
* return value.cloneNode(true);
* }
- * });
+ * }
*
- * el === document.body
+ * var el = _.cloneDeep(document.body, customizer);
+ *
+ * console.log(el === document.body);
* // => false
- * el.nodeName
- * // => BODY
- * el.childNodes.length;
+ * console.log(el.nodeName);
+ * // => 'BODY'
+ * console.log(el.childNodes.length);
* // => 20
*/
- function cloneDeep(value, customizer, thisArg) {
- return typeof customizer == 'function'
- ? baseClone(value, true, bindCallback(customizer, thisArg, 3))
- : baseClone(value, true);
+ function cloneDeepWith(value, customizer) {
+ return baseClone(value, true, customizer);
+ }
+
+ /**
+ * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * comparison between two values to determine if they are equivalent.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var other = { 'user': 'fred' };
+ *
+ * _.eq(object, object);
+ * // => true
+ *
+ * _.eq(object, other);
+ * // => false
+ *
+ * _.eq('a', 'a');
+ * // => true
+ *
+ * _.eq('a', Object('a'));
+ * // => false
+ *
+ * _.eq(NaN, NaN);
+ * // => true
+ */
+ function eq(value, other) {
+ return value === other || (value !== value && other !== other);
}
/**
@@ -8448,7 +9233,7 @@
}
/**
- * Checks if `value` is classified as an `arguments` object.
+ * Checks if `value` is likely an `arguments` object.
*
* @static
* @memberOf _
@@ -8464,8 +9249,9 @@
* // => false
*/
function isArguments(value) {
- return isObjectLike(value) && isArrayLike(value) &&
- hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
+ // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+ return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
+ (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
}
/**
@@ -8473,6 +9259,7 @@
*
* @static
* @memberOf _
+ * @type Function
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
@@ -8481,12 +9268,74 @@
* _.isArray([1, 2, 3]);
* // => true
*
- * _.isArray(function() { return arguments; }());
+ * _.isArray(document.body.children);
+ * // => false
+ *
+ * _.isArray('abc');
+ * // => false
+ *
+ * _.isArray(_.noop);
* // => false
*/
- var isArray = nativeIsArray || function(value) {
- return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
- };
+ var isArray = Array.isArray;
+
+ /**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+ function isArrayLike(value) {
+ return value != null &&
+ !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
+ }
+
+ /**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+ function isArrayLikeObject(value) {
+ return isObjectLike(value) && isArrayLike(value);
+ }
/**
* Checks if `value` is classified as a boolean primitive or object.
@@ -8505,7 +9354,8 @@
* // => false
*/
function isBoolean(value) {
- return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag);
+ return value === true || value === false ||
+ (isObjectLike(value) && objectToString.call(value) == boolTag);
}
/**
@@ -8525,11 +9375,11 @@
* // => false
*/
function isDate(value) {
- return isObjectLike(value) && objToString.call(value) == dateTag;
+ return isObjectLike(value) && objectToString.call(value) == dateTag;
}
/**
- * Checks if `value` is a DOM element.
+ * Checks if `value` is likely a DOM element.
*
* @static
* @memberOf _
@@ -8576,64 +9426,77 @@
* // => false
*/
function isEmpty(value) {
- if (value == null) {
- return true;
- }
- if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
- (isObjectLike(value) && isFunction(value.splice)))) {
- return !value.length;
- }
- return !keys(value).length;
+ return (!isObjectLike(value) || isFunction(value.splice))
+ ? !size(value)
+ : !keys(value).length;
}
/**
* Performs a deep comparison between two values to determine if they are
- * equivalent. If `customizer` is provided it's invoked to compare values.
- * If `customizer` returns `undefined` comparisons are handled by the method
- * instead. The `customizer` is bound to `thisArg` and invoked with up to
- * three arguments: (value, other [, index|key]).
+ * equivalent.
*
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties. Functions and DOM nodes
- * are **not** supported. Provide a customizer function to extend support
- * for comparing other values.
+ * **Note:** This method supports comparing arrays, array buffers, booleans,
+ * date objects, error objects, maps, numbers, `Object` objects, regexes,
+ * sets, strings, symbols, and typed arrays. `Object` objects are compared
+ * by their own, not inherited, enumerable properties. Functions and DOM
+ * nodes are **not** supported.
*
* @static
* @memberOf _
- * @alias eq
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
- * @param {Function} [customizer] The function to customize value comparisons.
- * @param {*} [thisArg] The `this` binding of `customizer`.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'user': 'fred' };
* var other = { 'user': 'fred' };
*
- * object == other;
- * // => false
- *
* _.isEqual(object, other);
* // => true
*
- * // using a customizer callback
+ * object === other;
+ * // => false
+ */
+ function isEqual(value, other) {
+ return baseIsEqual(value, other);
+ }
+
+ /**
+ * This method is like `_.isEqual` except that it accepts `customizer` which is
+ * invoked to compare values. If `customizer` returns `undefined` comparisons are
+ * handled by the method instead. The `customizer` is invoked with up to seven arguments:
+ * (objValue, othValue [, index|key, object, other, stack]).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * function isGreeting(value) {
+ * return /^h(?:i|ello)$/.test(value);
+ * }
+ *
+ * function customizer(objValue, othValue) {
+ * if (isGreeting(objValue) && isGreeting(othValue)) {
+ * return true;
+ * }
+ * }
+ *
* var array = ['hello', 'goodbye'];
* var other = ['hi', 'goodbye'];
*
- * _.isEqual(array, other, function(value, other) {
- * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) {
- * return true;
- * }
- * });
+ * _.isEqualWith(array, other, customizer);
* // => true
*/
- function isEqual(value, other, customizer, thisArg) {
- customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
+ function isEqualWith(value, other, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
var result = customizer ? customizer(value, other) : undefined;
- return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
+ return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
}
/**
@@ -8654,13 +9517,14 @@
* // => false
*/
function isError(value) {
- return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag;
+ return isObjectLike(value) &&
+ typeof value.message == 'string' && objectToString.call(value) == errorTag;
}
/**
* Checks if `value` is a finite primitive number.
*
- * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).
+ * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
*
* @static
* @memberOf _
@@ -8669,17 +9533,14 @@
* @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
* @example
*
- * _.isFinite(10);
+ * _.isFinite(3);
* // => true
*
- * _.isFinite('10');
- * // => false
+ * _.isFinite(Number.MAX_VALUE);
+ * // => true
*
- * _.isFinite(true);
- * // => false
- *
- * _.isFinite(Object(10));
- * // => false
+ * _.isFinite(3.14);
+ * // => true
*
* _.isFinite(Infinity);
* // => false
@@ -8706,9 +9567,66 @@
*/
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 which returns 'object' for typed array constructors.
- return isObject(value) && objToString.call(value) == funcTag;
+ // in Safari 8 which returns 'object' for typed array constructors, and
+ // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+ var tag = isObject(value) ? objectToString.call(value) : '';
+ return tag == funcTag || tag == genTag;
+ }
+
+ /**
+ * Checks if `value` is an integer.
+ *
+ * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
+ * @example
+ *
+ * _.isInteger(3);
+ * // => true
+ *
+ * _.isInteger(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isInteger(Infinity);
+ * // => false
+ *
+ * _.isInteger('3');
+ * // => false
+ */
+ function isInteger(value) {
+ return typeof value == 'number' && value == toInteger(value);
+ }
+
+ /**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+ function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
/**
@@ -8728,7 +9646,10 @@
* _.isObject([1, 2, 3]);
* // => true
*
- * _.isObject(1);
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
* // => false
*/
function isObject(value) {
@@ -8739,24 +9660,43 @@
}
/**
- * Performs a deep comparison between `object` and `source` to determine if
- * `object` contains equivalent property values. If `customizer` is provided
- * it's invoked to compare values. If `customizer` returns `undefined`
- * comparisons are handled by the method instead. The `customizer` is bound
- * to `thisArg` and invoked with three arguments: (value, other, index|key).
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
*
- * **Note:** This method supports comparing properties of arrays, booleans,
- * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions
- * and DOM nodes are **not** supported. Provide a customizer function to extend
- * support for comparing other values.
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+ function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+ }
+
+ /**
+ * Performs a deep comparison between `object` and `source` to determine if
+ * `object` contains equivalent property values.
+ *
+ * **Note:** This method supports comparing the same values as `_.isEqual`.
*
* @static
* @memberOf _
* @category Lang
* @param {Object} object The object to inspect.
* @param {Object} source The object of property values to match.
- * @param {Function} [customizer] The function to customize value comparisons.
- * @param {*} [thisArg] The `this` binding of `customizer`.
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
* @example
*
@@ -8767,19 +9707,45 @@
*
* _.isMatch(object, { 'age': 36 });
* // => false
+ */
+ function isMatch(object, source) {
+ return object === source || baseIsMatch(object, source, getMatchData(source));
+ }
+
+ /**
+ * This method is like `_.isMatch` except that it accepts `customizer` which
+ * is invoked to compare values. If `customizer` returns `undefined` comparisons
+ * are handled by the method instead. The `customizer` is invoked with three
+ * arguments: (objValue, srcValue, index|key, object, source).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {Object} object The object to inspect.
+ * @param {Object} source The object of property values to match.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ * @example
+ *
+ * function isGreeting(value) {
+ * return /^h(?:i|ello)$/.test(value);
+ * }
+ *
+ * function customizer(objValue, srcValue) {
+ * if (isGreeting(objValue) && isGreeting(srcValue)) {
+ * return true;
+ * }
+ * }
*
- * // using a customizer callback
* var object = { 'greeting': 'hello' };
* var source = { 'greeting': 'hi' };
*
- * _.isMatch(object, source, function(value, other) {
- * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined;
- * });
+ * _.isMatchWith(object, source, customizer);
* // => true
*/
- function isMatch(object, source, customizer, thisArg) {
- customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
- return baseIsMatch(object, getMatchData(source), customizer);
+ function isMatchWith(object, source, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return baseIsMatch(object, source, getMatchData(source), customizer);
}
/**
@@ -8809,7 +9775,7 @@
*/
function isNaN(value) {
// An `NaN` primitive is the only value that is not equal to itself.
- // Perform the `toStringTag` check first to avoid errors with some host objects in IE.
+ // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
return isNumber(value) && value != +value;
}
@@ -8834,9 +9800,10 @@
return false;
}
if (isFunction(value)) {
- return reIsNative.test(fnToString.call(value));
+ return reIsNative.test(funcToString.call(value));
}
- return isObjectLike(value) && reIsHostCtor.test(value);
+ return isObjectLike(value) &&
+ (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
}
/**
@@ -8859,6 +9826,29 @@
return value === null;
}
+ /**
+ * Checks if `value` is `null` or `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
+ * @example
+ *
+ * _.isNil(null);
+ * // => true
+ *
+ * _.isNil(void 0);
+ * // => true
+ *
+ * _.isNil(NaN);
+ * // => false
+ */
+ function isNil(value) {
+ return value == null;
+ }
+
/**
* Checks if `value` is classified as a `Number` primitive or object.
*
@@ -8872,26 +9862,27 @@
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
- * _.isNumber(8.4);
+ * _.isNumber(3);
* // => true
*
- * _.isNumber(NaN);
+ * _.isNumber(Number.MIN_VALUE);
* // => true
*
- * _.isNumber('8.4');
+ * _.isNumber(Infinity);
+ * // => true
+ *
+ * _.isNumber('3');
* // => false
*/
function isNumber(value) {
- return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
+ return typeof value == 'number' ||
+ (isObjectLike(value) && objectToString.call(value) == numberTag);
}
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
*
- * **Note:** This method assumes objects created by the `Object` constructor
- * have no inherited enumerable properties.
- *
* @static
* @memberOf _
* @category Lang
@@ -8916,24 +9907,19 @@
* // => true
*/
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)))) {
+ if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
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);
+ var proto = objectProto;
+ if (typeof value.constructor == 'function') {
+ proto = getPrototypeOf(value);
+ }
+ if (proto === null) {
+ return true;
+ }
+ var Ctor = proto.constructor;
+ return (typeof Ctor == 'function' &&
+ Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
}
/**
@@ -8953,7 +9939,36 @@
* // => false
*/
function isRegExp(value) {
- return isObject(value) && objToString.call(value) == regexpTag;
+ return isObject(value) && objectToString.call(value) == regexpTag;
+ }
+
+ /**
+ * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
+ * double precision number which isn't the result of a rounded unsafe integer.
+ *
+ * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
+ * @example
+ *
+ * _.isSafeInteger(3);
+ * // => true
+ *
+ * _.isSafeInteger(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isSafeInteger(Infinity);
+ * // => false
+ *
+ * _.isSafeInteger('3');
+ * // => false
+ */
+ function isSafeInteger(value) {
+ return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
}
/**
@@ -8973,7 +9988,29 @@
* // => false
*/
function isString(value) {
- return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
+ return typeof value == 'string' ||
+ (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
+ }
+
+ /**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */
+ function isSymbol(value) {
+ return typeof value == 'symbol' ||
+ (isObjectLike(value) && objectToString.call(value) == symbolTag);
}
/**
@@ -8993,7 +10030,7 @@
* // => false
*/
function isTypedArray(value) {
- return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
+ return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
}
/**
@@ -9074,20 +10111,135 @@
* @returns {Array} Returns the converted array.
* @example
*
- * (function() {
- * return _.toArray(arguments).slice(1);
- * }(1, 2, 3));
- * // => [2, 3]
+ * _.toArray({ 'a': 1, 'b': 2 });
+ * // => [1, 2]
+ *
+ * _.toArray('abc');
+ * // => ['a', 'b', 'c']
+ *
+ * _.toArray(1);
+ * // => []
+ *
+ * _.toArray(null);
+ * // => []
*/
function toArray(value) {
- var length = value ? getLength(value) : 0;
- if (!isLength(length)) {
- return values(value);
- }
- if (!length) {
+ if (!value) {
return [];
}
- return arrayCopy(value);
+ if (isArrayLike(value)) {
+ return isString(value) ? stringToArray(value) : copyArray(value);
+ }
+ if (iteratorSymbol && value[iteratorSymbol]) {
+ return iteratorToArray(value[iteratorSymbol]());
+ }
+ var tag = getTag(value),
+ func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
+
+ return func(value);
+ }
+
+ /**
+ * Converts `value` to an integer.
+ *
+ * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toInteger(3);
+ * // => 3
+ *
+ * _.toInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toInteger(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toInteger('3');
+ * // => 3
+ */
+ function toInteger(value) {
+ if (!value) {
+ return value === 0 ? value : 0;
+ }
+ value = toNumber(value);
+ if (value === INFINITY || value === -INFINITY) {
+ var sign = (value < 0 ? -1 : 1);
+ return sign * MAX_INTEGER;
+ }
+ var remainder = value % 1;
+ return value === value ? (remainder ? value - remainder : value) : 0;
+ }
+
+ /**
+ * Converts `value` to an integer suitable for use as the length of an
+ * array-like object.
+ *
+ * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @return {number} Returns the converted integer.
+ * @example
+ *
+ * _.toLength(3);
+ * // => 3
+ *
+ * _.toLength(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toLength(Infinity);
+ * // => 4294967295
+ *
+ * _.toLength('3');
+ * // => 3
+ */
+ function toLength(value) {
+ return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
+ }
+
+ /**
+ * Converts `value` to a number.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ * @example
+ *
+ * _.toNumber(3);
+ * // => 3
+ *
+ * _.toNumber(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toNumber(Infinity);
+ * // => Infinity
+ *
+ * _.toNumber('3');
+ * // => 3
+ */
+ function toNumber(value) {
+ if (isObject(value)) {
+ var other = isFunction(value.valueOf) ? value.valueOf() : value;
+ value = isObject(other) ? (other + '') : other;
+ }
+ if (typeof value != 'string') {
+ return value === 0 ? value : +value;
+ }
+ value = value.replace(reTrim, '');
+ var isBinary = reIsBinary.test(value);
+ return (isBinary || reIsOctal.test(value))
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
+ : (reIsBadHex.test(value) ? NAN : +value);
}
/**
@@ -9114,70 +10266,112 @@
* // => { 'a': 1, 'b': 2, 'c': 3 }
*/
function toPlainObject(value) {
- return baseCopy(value, keysIn(value));
+ return copyObject(value, keysIn(value));
+ }
+
+ /**
+ * Converts `value` to a safe integer. A safe integer can be compared and
+ * represented correctly.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toSafeInteger(3);
+ * // => 3
+ *
+ * _.toSafeInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toSafeInteger(Infinity);
+ * // => 9007199254740991
+ *
+ * _.toSafeInteger('3');
+ * // => 3
+ */
+ function toSafeInteger(value) {
+ return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
+ }
+
+ /**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+ function toString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
+ }
+ if (value == null) {
+ return '';
+ }
+ if (isSymbol(value)) {
+ return _Symbol ? symbolToString.call(value) : '';
+ }
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
/*------------------------------------------------------------------------*/
/**
- * 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's 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).
+ * Assigns own enumerable properties of source objects to the destination
+ * object. Source objects are applied from left to right. Subsequent sources
+ * overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object` and is loosely based on
+ * [`Object.assign`](https://mdn.io/Object/assign).
*
* @static
* @memberOf _
* @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' }]
- * };
+ * function Foo() {
+ * this.c = 3;
+ * }
*
- * var ages = {
- * 'data': [{ 'age': 36 }, { 'age': 40 }]
- * };
+ * function Bar() {
+ * this.e = 5;
+ * }
*
- * _.merge(users, ages);
- * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
+ * Foo.prototype.d = 4;
+ * Bar.prototype.f = 6;
*
- * // 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'] }
+ * _.assign({ 'a': 1 }, new Foo, new Bar);
+ * // => { 'a': 1, 'c': 3, 'e': 5 }
*/
- var merge = createAssigner(baseMerge);
+ var assign = createAssigner(function(object, source) {
+ copyObject(source, keys(source), object);
+ });
/**
- * Assigns own enumerable properties of source object(s) to the destination
- * object. Subsequent sources overwrite property assignments of previous sources.
- * If `customizer` is provided it's invoked to produce the assigned values.
- * The `customizer` is bound to `thisArg` and invoked with five arguments:
- * (objectValue, sourceValue, key, object, source).
+ * This method is like `_.assign` except that it iterates over own and
+ * inherited source properties.
*
- * **Note:** This method mutates `object` and is based on
- * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
+ * **Note:** This method mutates `object`.
*
* @static
* @memberOf _
@@ -9185,39 +10379,121 @@
* @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
*
- * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
- * // => { 'user': 'fred', 'age': 40 }
+ * function Foo() {
+ * this.b = 2;
+ * }
*
- * // using a customizer callback
- * var defaults = _.partialRight(_.assign, function(value, other) {
- * return _.isUndefined(value) ? other : value;
- * });
+ * function Bar() {
+ * this.d = 4;
+ * }
*
- * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
- * // => { 'user': 'barney', 'age': 36 }
+ * Foo.prototype.c = 3;
+ * Bar.prototype.e = 5;
+ *
+ * _.assignIn({ 'a': 1 }, new Foo, new Bar);
+ * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
*/
- var assign = createAssigner(function(object, source, customizer) {
- return customizer
- ? assignWith(object, source, customizer)
- : baseAssign(object, source);
+ var assignIn = createAssigner(function(object, source) {
+ copyObject(source, keysIn(source), object);
});
/**
- * Creates an object that inherits from the given `prototype` object. If a
- * `properties` object is provided its own enumerable properties are assigned
- * to the created object.
+ * This method is like `_.assignIn` except that it accepts `customizer` which
+ * is invoked to produce the assigned values. If `customizer` returns `undefined`
+ * assignment is handled by the method instead. The `customizer` is invoked
+ * with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @alias extendWith
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignInWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */
+ var assignInWith = createAssigner(function(object, source, customizer) {
+ copyObjectWith(source, keysIn(source), object, customizer);
+ });
+
+ /**
+ * This method is like `_.assign` except that it accepts `customizer` which
+ * is invoked to produce the assigned values. If `customizer` returns `undefined`
+ * assignment is handled by the method instead. The `customizer` is invoked
+ * with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @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.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */
+ var assignWith = createAssigner(function(object, source, customizer) {
+ copyObjectWith(source, keys(source), object, customizer);
+ });
+
+ /**
+ * Creates an array of values corresponding to `paths` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {...(string|string[])} [paths] The property paths of elements to pick,
+ * specified individually or in arrays.
+ * @returns {Array} Returns the new array of picked elements.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+ *
+ * _.at(object, ['a[0].b.c', 'a[1]']);
+ * // => [3, 4]
+ *
+ * _.at(['a', 'b', 'c'], 0, 2);
+ * // => ['a', 'c']
+ */
+ var at = rest(function(object, paths) {
+ return baseAt(object, baseFlatten(paths));
+ });
+
+ /**
+ * Creates an object that inherits from the `prototype` object. If a `properties`
+ * object is provided its own enumerable properties are assigned to the created object.
*
* @static
* @memberOf _
* @category Object
* @param {Object} prototype The object to inherit from.
* @param {Object} [properties] The properties to assign to the object.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
* @returns {Object} Returns the new object.
* @example
*
@@ -9241,18 +10517,16 @@
* circle instanceof Shape;
* // => true
*/
- function create(prototype, properties, guard) {
+ function create(prototype, properties) {
var result = baseCreate(prototype);
- if (guard && isIterateeCall(prototype, properties, guard)) {
- properties = undefined;
- }
return properties ? baseAssign(result, properties) : result;
}
/**
- * Assigns own enumerable properties of source object(s) to the destination
- * object for all destination properties that resolve to `undefined`. Once a
- * property is set, additional values of the same property are ignored.
+ * Assigns own and inherited enumerable properties of source objects to the
+ * destination object for all destination properties that resolve to `undefined`.
+ * Source objects are applied from left to right. Once a property is set,
+ * additional values of the same property are ignored.
*
* **Note:** This method mutates `object`.
*
@@ -9267,7 +10541,10 @@
* _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
* // => { 'user': 'barney', 'age': 36 }
*/
- var defaults = createDefaults(assign, assignDefaults);
+ var defaults = rest(function(args) {
+ args.push(undefined, assignInDefaults);
+ return apply(assignInWith, undefined, args);
+ });
/**
* This method is like `_.defaults` except that it recursively assigns
@@ -9287,30 +10564,20 @@
* // => { 'user': { 'name': 'barney', 'age': 36 } }
*
*/
- var defaultsDeep = createDefaults(merge, mergeDefaults);
+ var defaultsDeep = rest(function(args) {
+ args.push(undefined, mergeDefaults);
+ return apply(mergeWith, undefined, args);
+ });
/**
* This method is like `_.find` except that it returns the key of the first
* element `predicate` returns truthy for instead of the element itself.
*
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {string|undefined} Returns the key of the matched element, else `undefined`.
* @example
*
@@ -9320,47 +10587,34 @@
* 'pebbles': { 'age': 1, 'active': true }
* };
*
- * _.findKey(users, function(chr) {
- * return chr.age < 40;
- * });
+ * _.findKey(users, function(o) { return o.age < 40; });
* // => 'barney' (iteration order is not guaranteed)
*
- * // using the `_.matches` callback shorthand
+ * // using the `_.matches` iteratee shorthand
* _.findKey(users, { 'age': 1, 'active': true });
* // => 'pebbles'
*
- * // using the `_.matchesProperty` callback shorthand
- * _.findKey(users, 'active', false);
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.findKey(users, ['active', false]);
* // => 'fred'
*
- * // using the `_.property` callback shorthand
+ * // using the `_.property` iteratee shorthand
* _.findKey(users, 'active');
* // => 'barney'
*/
- var findKey = createFindKey(baseForOwn);
+ function findKey(object, predicate) {
+ return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
+ }
/**
* This method is like `_.findKey` except that it iterates over elements of
* a collection in the opposite order.
*
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {string|undefined} Returns the key of the matched element, else `undefined`.
* @example
*
@@ -9370,37 +10624,36 @@
* 'pebbles': { 'age': 1, 'active': true }
* };
*
- * _.findLastKey(users, function(chr) {
- * return chr.age < 40;
- * });
- * // => returns `pebbles` assuming `_.findKey` returns `barney`
+ * _.findLastKey(users, function(o) { return o.age < 40; });
+ * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
*
- * // using the `_.matches` callback shorthand
+ * // using the `_.matches` iteratee shorthand
* _.findLastKey(users, { 'age': 36, 'active': true });
* // => 'barney'
*
- * // using the `_.matchesProperty` callback shorthand
- * _.findLastKey(users, 'active', false);
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.findLastKey(users, ['active', false]);
* // => 'fred'
*
- * // using the `_.property` callback shorthand
+ * // using the `_.property` iteratee shorthand
* _.findLastKey(users, 'active');
* // => 'pebbles'
*/
- var findLastKey = createFindKey(baseForOwnRight);
+ function findLastKey(object, predicate) {
+ return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
+ }
/**
* Iterates over own and inherited enumerable properties of an object invoking
- * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked
- * with three arguments: (value, key, object). Iteratee functions may exit
- * iteration early by explicitly returning `false`.
+ * `iteratee` for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Object} Returns `object`.
* @example
*
@@ -9414,9 +10667,11 @@
* _.forIn(new Foo, function(value, key) {
* console.log(key);
* });
- * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed)
+ * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
*/
- var forIn = createForIn(baseFor);
+ function forIn(object, iteratee) {
+ return object == null ? object : baseFor(object, toFunction(iteratee), keysIn);
+ }
/**
* This method is like `_.forIn` except that it iterates over properties of
@@ -9427,7 +10682,6 @@
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Object} Returns `object`.
* @example
*
@@ -9441,22 +10695,23 @@
* _.forInRight(new Foo, function(value, key) {
* console.log(key);
* });
- * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'
+ * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
*/
- var forInRight = createForIn(baseForRight);
+ function forInRight(object, iteratee) {
+ return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn);
+ }
/**
* Iterates over own enumerable properties of an object invoking `iteratee`
- * for each property. The `iteratee` is bound to `thisArg` and invoked with
- * three arguments: (value, key, object). Iteratee functions may exit iteration
- * early by explicitly returning `false`.
+ * for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by
+ * explicitly returning `false`.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Object} Returns `object`.
* @example
*
@@ -9470,9 +10725,11 @@
* _.forOwn(new Foo, function(value, key) {
* console.log(key);
* });
- * // => logs 'a' and 'b' (iteration order is not guaranteed)
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
*/
- var forOwn = createForOwn(baseForOwn);
+ function forOwn(object, iteratee) {
+ return object && baseForOwn(object, toFunction(iteratee));
+ }
/**
* This method is like `_.forOwn` except that it iterates over properties of
@@ -9483,7 +10740,6 @@
* @category Object
* @param {Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {Object} Returns `object`.
* @example
*
@@ -9497,31 +10753,64 @@
* _.forOwnRight(new Foo, function(value, key) {
* console.log(key);
* });
- * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'
+ * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
*/
- var forOwnRight = createForOwn(baseForOwnRight);
+ function forOwnRight(object, iteratee) {
+ return object && baseForOwnRight(object, toFunction(iteratee));
+ }
/**
- * Creates an array of function property names from all enumerable properties,
- * own and inherited, of `object`.
+ * Creates an array of function property names from own enumerable properties
+ * of `object`.
*
* @static
* @memberOf _
- * @alias methods
* @category Object
* @param {Object} object The object to inspect.
* @returns {Array} Returns the new array of property names.
* @example
*
- * _.functions(_);
- * // => ['after', 'ary', 'assign', ...]
+ * function Foo() {
+ * this.a = _.constant('a');
+ * this.b = _.constant('b');
+ * }
+ *
+ * Foo.prototype.c = _.constant('c');
+ *
+ * _.functions(new Foo);
+ * // => ['a', 'b']
*/
function functions(object) {
- return baseFunctions(object, keysIn(object));
+ return object == null ? [] : baseFunctions(object, keys(object));
}
/**
- * Gets the property value at `path` of `object`. If the resolved value is
+ * Creates an array of function property names from own and inherited
+ * enumerable properties of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to inspect.
+ * @returns {Array} Returns the new array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = _.constant('a');
+ * this.b = _.constant('b');
+ * }
+ *
+ * Foo.prototype.c = _.constant('c');
+ *
+ * _.functionsIn(new Foo);
+ * // => ['a', 'b', 'c']
+ */
+ function functionsIn(object) {
+ return object == null ? [] : baseFunctions(object, keysIn(object));
+ }
+
+ /**
+ * Gets the value at `path` of `object`. If the resolved value is
* `undefined` the `defaultValue` is used in its place.
*
* @static
@@ -9545,22 +10834,23 @@
* // => 'default'
*/
function get(object, path, defaultValue) {
- var result = object == null ? undefined : baseGet(object, toPath(path), (path + ''));
+ var result = object == null ? undefined : baseGet(object, path);
return result === undefined ? defaultValue : result;
}
/**
- * Checks if `path` is a direct property.
+ * Checks if `path` is a direct property of `object`.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path to check.
- * @returns {boolean} Returns `true` if `path` is a direct property, else `false`.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
* @example
*
* var object = { 'a': { 'b': { 'c': 3 } } };
+ * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
*
* _.has(object, 'a');
* // => true
@@ -9570,36 +10860,54 @@
*
* _.has(object, ['a', 'b', 'c']);
* // => true
+ *
+ * _.has(other, 'a');
+ * // => false
*/
function has(object, path) {
- if (object == null) {
- return false;
- }
- var result = hasOwnProperty.call(object, path);
- if (!result && !isKey(path)) {
- path = toPath(path);
- object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
- if (object == null) {
- return false;
- }
- path = last(path);
- result = hasOwnProperty.call(object, path);
- }
- return result || (isLength(object.length) && isIndex(path, object.length) &&
- (isArray(object) || isArguments(object)));
+ return hasPath(object, path, baseHas);
+ }
+
+ /**
+ * Checks if `path` is a direct or inherited property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
+ *
+ * _.hasIn(object, 'a');
+ * // => true
+ *
+ * _.hasIn(object, 'a.b.c');
+ * // => true
+ *
+ * _.hasIn(object, ['a', 'b', 'c']);
+ * // => true
+ *
+ * _.hasIn(object, 'b');
+ * // => false
+ */
+ function hasIn(object, path) {
+ return hasPath(object, path, baseHasIn);
}
/**
* Creates an object composed of the inverted keys and values of `object`.
* If `object` contains duplicate values, subsequent values overwrite property
- * assignments of previous values unless `multiValue` is `true`.
+ * assignments of previous values unless `multiVal` is `true`.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to invert.
- * @param {boolean} [multiValue] Allow multiple values per key.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param {boolean} [multiVal] Allow multiple values per key.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Object} Returns the new inverted object.
* @example
*
@@ -9608,24 +10916,14 @@
* _.invert(object);
* // => { '1': 'c', '2': 'b' }
*
- * // with `multiValue`
+ * // with `multiVal`
* _.invert(object, true);
* // => { '1': ['a', 'c'], '2': ['b'] }
*/
- function invert(object, multiValue, guard) {
- if (guard && isIterateeCall(object, multiValue, guard)) {
- multiValue = undefined;
- }
- var index = -1,
- props = keys(object),
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index],
- value = object[key];
-
- if (multiValue) {
+ function invert(object, multiVal, guard) {
+ return arrayReduce(keys(object), function(result, key) {
+ var value = object[key];
+ if (multiVal && !guard) {
if (hasOwnProperty.call(result, value)) {
result[value].push(key);
} else {
@@ -9635,10 +10933,29 @@
else {
result[value] = key;
}
- }
- return result;
+ return result;
+ }, {});
}
+ /**
+ * Invokes the method at `path` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the method to invoke.
+ * @param {...*} [args] The arguments to invoke the method with.
+ * @returns {*} Returns the result of the invoked method.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
+ *
+ * _.invoke(object, 'a[0].b.c.slice', 1, 3);
+ * // => [2, 3]
+ */
+ var invoke = rest(baseInvoke);
+
/**
* Creates an array of the own enumerable property names of `object`.
*
@@ -9666,14 +10983,25 @@
* _.keys('hi');
* // => ['0', '1']
*/
- var keys = !nativeKeys ? shimKeys : function(object) {
- var Ctor = object == null ? undefined : object.constructor;
- if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
- (typeof object != 'function' && isArrayLike(object))) {
- return shimKeys(object);
+ function keys(object) {
+ var isProto = isPrototype(object);
+ if (!(isProto || isArrayLike(object))) {
+ return baseKeys(object);
}
- return isObject(object) ? nativeKeys(object) : [];
- };
+ var indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.length;
+
+ for (var key in object) {
+ if (baseHas(object, key) &&
+ !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+ !(isProto && key == 'constructor')) {
+ result.push(key);
+ }
+ }
+ return result;
+ }
/**
* Creates an array of the own and inherited enumerable property names of `object`.
@@ -9698,27 +11026,18 @@
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
*/
function keysIn(object) {
- if (object == null) {
- return [];
- }
- if (!isObject(object)) {
- object = Object(object);
- }
- var length = object.length;
- length = (length && isLength(length) &&
- (isArray(object) || isArguments(object)) && length) || 0;
+ var index = -1,
+ isProto = isPrototype(object),
+ props = baseKeysIn(object),
+ propsLength = props.length,
+ indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.length;
- var Ctor = object.constructor,
- index = -1,
- isProto = typeof Ctor == 'function' && Ctor.prototype === object,
- result = Array(length),
- skipIndexes = length > 0;
-
- while (++index < length) {
- result[index] = (index + '');
- }
- for (var key in object) {
- if (!(skipIndexes && isIndex(key, length)) &&
+ while (++index < propsLength) {
+ var key = props[index];
+ if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
result.push(key);
}
@@ -9735,9 +11054,7 @@
* @memberOf _
* @category Object
* @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns the new mapped object.
* @example
*
@@ -9746,50 +11063,122 @@
* });
* // => { 'a1': 1, 'b2': 2 }
*/
- var mapKeys = createObjectMapper(true);
+ function mapKeys(object, iteratee) {
+ var result = {};
+ iteratee = getIteratee(iteratee, 3);
+
+ baseForOwn(object, function(value, key, object) {
+ result[iteratee(value, key, object)] = value;
+ });
+ return result;
+ }
/**
* Creates an object with the same keys as `object` and values generated by
* running each own enumerable property of `object` through `iteratee`. The
- * iteratee function is bound to `thisArg` and invoked with three arguments:
- * (value, key, object).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * iteratee function is invoked with three arguments: (value, key, object).
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns the new mapped object.
* @example
*
- * _.mapValues({ 'a': 1, 'b': 2 }, function(n) {
- * return n * 3;
- * });
- * // => { 'a': 3, 'b': 6 }
- *
* var users = {
* 'fred': { 'user': 'fred', 'age': 40 },
* 'pebbles': { 'user': 'pebbles', 'age': 1 }
* };
*
- * // using the `_.property` callback shorthand
+ * _.mapValues(users, function(o) { return o.age; });
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+ *
+ * // using the `_.property` iteratee shorthand
* _.mapValues(users, 'age');
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
*/
- var mapValues = createObjectMapper();
+ function mapValues(object, iteratee) {
+ var result = {};
+ iteratee = getIteratee(iteratee, 3);
+
+ baseForOwn(object, function(value, key, object) {
+ result[key] = iteratee(value, key, object);
+ });
+ return result;
+ }
+
+ /**
+ * Recursively merges own and inherited enumerable properties of source
+ * objects into the destination object, skipping source properties that resolve
+ * to `undefined`. Array and plain object properties are merged recursively.
+ * Other objects and value types are overridden by assignment. Source objects
+ * are applied from left to right. Subsequent sources overwrite property
+ * assignments of previous sources.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @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 }] }
+ */
+ var merge = createAssigner(function(object, source) {
+ baseMerge(object, source);
+ });
+
+ /**
+ * This method is like `_.merge` except that it accepts `customizer` which
+ * is invoked to produce the merged values of the destination and source
+ * properties. If `customizer` returns `undefined` merging is handled by the
+ * method instead. The `customizer` is invoked with seven arguments:
+ * (objValue, srcValue, key, object, source, stack).
+ *
+ * @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.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * if (_.isArray(objValue)) {
+ * return objValue.concat(srcValue);
+ * }
+ * }
+ *
+ * var object = {
+ * 'fruits': ['apple'],
+ * 'vegetables': ['beet']
+ * };
+ *
+ * var other = {
+ * 'fruits': ['banana'],
+ * 'vegetables': ['carrot']
+ * };
+ *
+ * _.mergeWith(object, other, customizer);
+ * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
+ */
+ var mergeWith = createAssigner(function(object, source, customizer) {
+ baseMerge(object, source, customizer);
+ });
/**
* The opposite of `_.pick`; this method creates an object composed of the
@@ -9799,99 +11188,91 @@
* @memberOf _
* @category Object
* @param {Object} object The source object.
- * @param {Function|...(string|string[])} [predicate] The function invoked per
- * iteration or property names to omit, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {...(string|string[])} [props] The property names to omit, specified
+ * individually or in arrays..
* @returns {Object} Returns the new object.
* @example
*
- * var object = { 'user': 'fred', 'age': 40 };
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
*
- * _.omit(object, 'age');
- * // => { 'user': 'fred' }
- *
- * _.omit(object, _.isNumber);
- * // => { 'user': 'fred' }
+ * _.omit(object, ['a', 'c']);
+ * // => { 'b': '2' }
*/
- var omit = restParam(function(object, props) {
+ var omit = rest(function(object, props) {
if (object == null) {
return {};
}
- if (typeof props[0] != 'function') {
- var props = arrayMap(baseFlatten(props), String);
- return pickByArray(object, baseDifference(keysIn(object), props));
- }
- var predicate = bindCallback(props[0], props[1], 3);
- return pickByCallback(object, function(value, key, object) {
- return !predicate(value, key, object);
- });
+ props = arrayMap(baseFlatten(props), String);
+ return basePick(object, baseDifference(keysIn(object), props));
});
/**
- * Creates a two dimensional array of the key-value pairs for `object`,
- * e.g. `[[key1, value1], [key2, value2]]`.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @returns {Array} Returns the new array of key-value pairs.
- * @example
- *
- * _.pairs({ 'barney': 36, 'fred': 40 });
- * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
- */
- function pairs(object) {
- object = toObject(object);
-
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- var key = props[index];
- result[index] = [key, object[key]];
- }
- return result;
- }
-
- /**
- * Creates an object composed of the picked `object` properties. Property
- * names may be specified as individual arguments or as arrays of property
- * names. If `predicate` is provided it's invoked for each property of `object`
- * picking the properties `predicate` returns truthy for. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, key, object).
+ * The opposite of `_.pickBy`; this method creates an object composed of the
+ * own and inherited enumerable properties of `object` that `predicate`
+ * doesn't return truthy for.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The source object.
- * @param {Function|...(string|string[])} [predicate] The function invoked per
- * iteration or property names to pick, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
* @returns {Object} Returns the new object.
* @example
*
- * var object = { 'user': 'fred', 'age': 40 };
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
*
- * _.pick(object, 'user');
- * // => { 'user': 'fred' }
- *
- * _.pick(object, _.isString);
- * // => { 'user': 'fred' }
+ * _.omitBy(object, _.isNumber);
+ * // => { 'b': '2' }
*/
- var pick = restParam(function(object, props) {
- if (object == null) {
- return {};
- }
- return typeof props[0] == 'function'
- ? pickByCallback(object, bindCallback(props[0], props[1], 3))
- : pickByArray(object, baseFlatten(props));
+ function omitBy(object, predicate) {
+ predicate = getIteratee(predicate);
+ return basePickBy(object, function(value) {
+ return !predicate(value);
+ });
+ }
+
+ /**
+ * Creates an object composed of the picked `object` properties.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [props] The property names to pick, specified
+ * individually or in arrays.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pick(object, ['a', 'c']);
+ * // => { 'a': 1, 'c': 3 }
+ */
+ var pick = rest(function(object, props) {
+ return object == null ? {} : basePick(object, baseFlatten(props));
});
+ /**
+ * Creates an object composed of the `object` properties `predicate` returns
+ * truthy for. The predicate is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pickBy(object, _.isNumber);
+ * // => { 'a': 1, 'c': 3 }
+ */
+ function pickBy(object, predicate) {
+ return object == null ? {} : basePickBy(object, getIteratee(predicate));
+ }
+
/**
* This method is like `_.get` except that if the resolved value is a function
* it's invoked with the `this` binding of its parent object and its result
@@ -9914,33 +11295,36 @@
* _.result(object, 'a[0].b.c2');
* // => 4
*
- * _.result(object, 'a.b.c', 'default');
+ * _.result(object, 'a[0].b.c3', 'default');
* // => 'default'
*
- * _.result(object, 'a.b.c', _.constant('default'));
+ * _.result(object, 'a[0].b.c3', _.constant('default'));
* // => 'default'
*/
function result(object, path, defaultValue) {
- var result = object == null ? undefined : object[path];
+ if (!isKey(path, object)) {
+ path = baseToPath(path);
+ var result = get(object, path);
+ object = parent(object, path);
+ } else {
+ result = object == null ? undefined : object[path];
+ }
if (result === undefined) {
- if (object != null && !isKey(path, object)) {
- path = toPath(path);
- object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
- result = object == null ? undefined : object[last(path)];
- }
- result = result === undefined ? defaultValue : result;
+ result = defaultValue;
}
return isFunction(result) ? result.call(object) : result;
}
/**
- * Sets the property value of `path` on `object`. If a portion of `path`
- * does not exist it's created.
+ * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
+ * it's created. Arrays are created for missing index properties while objects
+ * are created for all other missing properties. Use `_.setWith` to customize
+ * `path` creation.
*
* @static
* @memberOf _
* @category Object
- * @param {Object} object The object to augment.
+ * @param {Object} object The object to modify.
* @param {Array|string} path The path of the property to set.
* @param {*} value The value to set.
* @returns {Object} Returns `object`.
@@ -9957,38 +11341,88 @@
* // => 5
*/
function set(object, path, value) {
- if (object == null) {
- return object;
- }
- var pathKey = (path + '');
- path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path);
+ return object == null ? object : baseSet(object, path, value);
+ }
- var index = -1,
- length = path.length,
- lastIndex = length - 1,
- nested = object;
+ /**
+ * This method is like `_.set` except that it accepts `customizer` which is
+ * invoked to produce the objects of `path`. If `customizer` returns `undefined`
+ * path creation is handled by the method instead. The `customizer` is invoked
+ * with three arguments: (nsValue, key, nsObject).
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
+ * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
+ */
+ function setWith(object, path, value, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return object == null ? object : baseSet(object, path, value, customizer);
+ }
- while (nested != null && ++index < length) {
- var key = path[index];
- if (isObject(nested)) {
- if (index == lastIndex) {
- nested[key] = value;
- } else if (nested[key] == null) {
- nested[key] = isIndex(path[index + 1]) ? [] : {};
- }
- }
- nested = nested[key];
- }
- return object;
+ /**
+ * Creates an array of own enumerable key-value pairs for `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the new array of key-value pairs.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.toPairs(new Foo);
+ * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
+ */
+ function toPairs(object) {
+ return baseToPairs(object, keys(object));
+ }
+
+ /**
+ * Creates an array of own and inherited enumerable key-value pairs for `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the new array of key-value pairs.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.toPairsIn(new Foo);
+ * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
+ */
+ function toPairsIn(object) {
+ return baseToPairs(object, keysIn(object));
}
/**
* An alternative to `_.reduce`; this method transforms `object` to a new
* `accumulator` object which is the result of running each of its own enumerable
* properties through `iteratee`, with each invocation potentially mutating
- * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked
- * with four arguments: (accumulator, value, key, object). Iteratee functions
- * may exit iteration early by explicitly returning `false`.
+ * the `accumulator` object. The iteratee is invoked with four arguments:
+ * (accumulator, value, key, object). Iteratee functions may exit iteration
+ * early by explicitly returning `false`.
*
* @static
* @memberOf _
@@ -9996,7 +11430,6 @@
* @param {Array|Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The custom accumulator value.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {*} Returns the accumulated value.
* @example
*
@@ -10006,14 +11439,14 @@
* });
* // => [4, 9]
*
- * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) {
- * result[key] = n * 3;
+ * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
* });
- * // => { 'a': 3, 'b': 6 }
+ * // => { '1': ['a', 'c'], '2': ['b'] }
*/
- function transform(object, iteratee, accumulator, thisArg) {
+ function transform(object, iteratee, accumulator) {
var isArr = isArray(object) || isTypedArray(object);
- iteratee = getCallback(iteratee, thisArg, 4);
+ iteratee = getIteratee(iteratee, 4);
if (accumulator == null) {
if (isArr || isObject(object)) {
@@ -10033,6 +11466,34 @@
return accumulator;
}
+ /**
+ * Removes the property at `path` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 7 } }] };
+ * _.unset(object, 'a[0].b.c');
+ * // => true
+ *
+ * console.log(object);
+ * // => { 'a': [{ 'b': {} }] };
+ *
+ * _.unset(object, 'a[0].b.c');
+ * // => true
+ *
+ * console.log(object);
+ * // => { 'a': [{ 'b': {} }] };
+ */
+ function unset(object, path) {
+ return object == null ? true : baseUnset(object, path);
+ }
+
/**
* Creates an array of the own enumerable property values of `object`.
*
@@ -10059,12 +11520,11 @@
* // => ['h', 'i']
*/
function values(object) {
- return baseValues(object, keys(object));
+ return object ? baseValues(object, keys(object)) : [];
}
/**
- * Creates an array of the own and inherited enumerable property values
- * of `object`.
+ * Creates an array of the own and inherited enumerable property values of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
@@ -10086,22 +11546,58 @@
* // => [1, 2, 3] (iteration order is not guaranteed)
*/
function valuesIn(object) {
- return baseValues(object, keysIn(object));
+ return object == null ? baseValues(object, keysIn(object)) : [];
}
/*------------------------------------------------------------------------*/
/**
- * Checks if `n` is between `start` and up to but not including, `end`. If
- * `end` is not specified it's set to `start` with `start` then set to `0`.
+ * Clamps `number` within the inclusive `lower` and `upper` bounds.
*
* @static
* @memberOf _
* @category Number
- * @param {number} n The number to check.
+ * @param {number} number The number to clamp.
+ * @param {number} [lower] The lower bound.
+ * @param {number} upper The upper bound.
+ * @returns {number} Returns the clamped number.
+ * @example
+ *
+ * _.clamp(-10, -5, 5);
+ * // => -5
+ *
+ * _.clamp(10, -5, 5);
+ * // => 5
+ */
+ function clamp(number, lower, upper) {
+ if (upper === undefined) {
+ upper = lower;
+ lower = undefined;
+ }
+ if (upper !== undefined) {
+ upper = toNumber(upper);
+ upper = upper === upper ? upper : 0;
+ }
+ if (lower !== undefined) {
+ lower = toNumber(lower);
+ lower = lower === lower ? lower : 0;
+ }
+ return baseClamp(toNumber(number), lower, upper);
+ }
+
+ /**
+ * Checks if `n` is between `start` and up to but not including, `end`. If
+ * `end` is not specified it's set to `start` with `start` then set to `0`.
+ * If `start` is greater than `end` the params are swapped to support
+ * negative ranges.
+ *
+ * @static
+ * @memberOf _
+ * @category Number
+ * @param {number} number The number to check.
* @param {number} [start=0] The start of the range.
* @param {number} end The end of the range.
- * @returns {boolean} Returns `true` if `n` is in the range, else `false`.
+ * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
* @example
*
* _.inRange(3, 2, 4);
@@ -10121,29 +11617,36 @@
*
* _.inRange(5.2, 4);
* // => false
+ *
+ * _.inRange(-3, -2, -6);
+ * // => true
*/
- function inRange(value, start, end) {
- start = +start || 0;
+ function inRange(number, start, end) {
+ start = toNumber(start) || 0;
if (end === undefined) {
end = start;
start = 0;
} else {
- end = +end || 0;
+ end = toNumber(end) || 0;
}
- return value >= nativeMin(start, end) && value < nativeMax(start, end);
+ number = toNumber(number);
+ return baseInRange(number, start, end);
}
/**
- * Produces a random number between `min` and `max` (inclusive). If only one
- * argument is provided a number between `0` and the given number is returned.
- * If `floating` is `true`, or either `min` or `max` are floats, a floating-point
- * number is returned instead of an integer.
+ * Produces a random number between the inclusive `lower` and `upper` bounds.
+ * If only one argument is provided a number between `0` and the given number
+ * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
+ * a floating-point number is returned instead of an integer.
+ *
+ * **Note:** JavaScript follows the IEEE-754 standard for resolving
+ * floating-point values which can produce unexpected results.
*
* @static
* @memberOf _
* @category Number
- * @param {number} [min=0] The minimum possible value.
- * @param {number} [max=1] The maximum possible value.
+ * @param {number} [lower=0] The lower bound.
+ * @param {number} [upper=1] The upper bound.
* @param {boolean} [floating] Specify returning a floating-point number.
* @returns {number} Returns the random number.
* @example
@@ -10160,39 +11663,43 @@
* _.random(1.2, 5.2);
* // => a floating-point number between 1.2 and 5.2
*/
- function random(min, max, floating) {
- if (floating && isIterateeCall(min, max, floating)) {
- max = floating = undefined;
+ function random(lower, upper, floating) {
+ if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
+ upper = floating = undefined;
}
- var noMin = min == null,
- noMax = max == null;
-
- if (floating == null) {
- if (noMax && typeof min == 'boolean') {
- floating = min;
- min = 1;
+ if (floating === undefined) {
+ if (typeof upper == 'boolean') {
+ floating = upper;
+ upper = undefined;
}
- else if (typeof max == 'boolean') {
- floating = max;
- noMax = true;
+ else if (typeof lower == 'boolean') {
+ floating = lower;
+ lower = undefined;
}
}
- if (noMin && noMax) {
- max = 1;
- noMax = false;
+ if (lower === undefined && upper === undefined) {
+ lower = 0;
+ upper = 1;
}
- min = +min || 0;
- if (noMax) {
- max = min;
- min = 0;
- } else {
- max = +max || 0;
+ else {
+ lower = toNumber(lower) || 0;
+ if (upper === undefined) {
+ upper = lower;
+ lower = 0;
+ } else {
+ upper = toNumber(upper) || 0;
+ }
}
- if (floating || min % 1 || max % 1) {
+ if (lower > upper) {
+ var temp = lower;
+ lower = upper;
+ upper = temp;
+ }
+ if (floating || lower % 1 || upper % 1) {
var rand = nativeRandom();
- return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max);
+ return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
}
- return baseRandom(min, max);
+ return baseRandom(lower, upper);
}
/*------------------------------------------------------------------------*/
@@ -10218,11 +11725,12 @@
*/
var camelCase = createCompounder(function(result, word, index) {
word = word.toLowerCase();
- return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);
+ return result + (index ? capitalize(word) : word);
});
/**
- * Capitalizes the first character of `string`.
+ * Converts the first character of `string` to upper case and the remaining
+ * to lower case.
*
* @static
* @memberOf _
@@ -10231,12 +11739,11 @@
* @returns {string} Returns the capitalized string.
* @example
*
- * _.capitalize('fred');
+ * _.capitalize('FRED');
* // => 'Fred'
*/
function capitalize(string) {
- string = baseToString(string);
- return string && (string.charAt(0).toUpperCase() + string.slice(1));
+ return upperFirst(toString(string).toLowerCase());
}
/**
@@ -10254,7 +11761,7 @@
* // => 'deja vu'
*/
function deburr(string) {
- string = baseToString(string);
+ string = toString(string);
return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
}
@@ -10280,24 +11787,24 @@
* // => true
*/
function endsWith(string, target, position) {
- string = baseToString(string);
- target = (target + '');
+ string = toString(string);
+ target = typeof target == 'string' ? target : (target + '');
var length = string.length;
position = position === undefined
? length
- : nativeMin(position < 0 ? 0 : (+position || 0), length);
+ : baseClamp(toInteger(position), 0, length);
position -= target.length;
return position >= 0 && string.indexOf(target, position) == position;
}
/**
- * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to
+ * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
* their corresponding HTML entities.
*
- * **Note:** No other characters are escaped. To escape additional characters
- * use a third-party library like [_he_](https://mths.be/he).
+ * **Note:** No other characters are escaped. To escape additional
+ * characters use a third-party library like [_he_](https://mths.be/he).
*
* Though the ">" character is escaped for symmetry, characters like
* ">" and "/" don't need escaping in HTML and have no special meaning
@@ -10305,8 +11812,8 @@
* See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
* (under "semi-related fun fact") for more details.
*
- * Backticks are escaped because in Internet Explorer < 9, they can break out
- * of attribute values or HTML comments. See [#59](https://html5sec.org/#59),
+ * Backticks are escaped because in IE < 9, they can break out of
+ * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
* [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
* [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
* for more details.
@@ -10325,16 +11832,15 @@
* // => 'fred, barney, & pebbles'
*/
function escape(string) {
- // Reset `lastIndex` because in IE < 9 `String#replace` does not.
- string = baseToString(string);
+ string = toString(string);
return (string && reHasUnescapedHtml.test(string))
? string.replace(reUnescapedHtml, escapeHtmlChar)
: string;
}
/**
- * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?",
- * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.
+ * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
+ * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
*
* @static
* @memberOf _
@@ -10344,13 +11850,13 @@
* @example
*
* _.escapeRegExp('[lodash](https://lodash.com/)');
- * // => '\[lodash\]\(https:\/\/lodash\.com\/\)'
+ * // => '\[lodash\]\(https://lodash\.com/\)'
*/
function escapeRegExp(string) {
- string = baseToString(string);
- return (string && reHasRegExpChars.test(string))
- ? string.replace(reRegExpChars, escapeRegExpChar)
- : (string || '(?:)');
+ string = toString(string);
+ return (string && reHasRegExpChar.test(string))
+ ? string.replace(reRegExpChar, '\\$&')
+ : string;
}
/**
@@ -10376,6 +11882,65 @@
return result + (index ? '-' : '') + word.toLowerCase();
});
+ /**
+ * Converts `string`, as space separated words, to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the lower cased string.
+ * @example
+ *
+ * _.lowerCase('--Foo-Bar');
+ * // => 'foo bar'
+ *
+ * _.lowerCase('fooBar');
+ * // => 'foo bar'
+ *
+ * _.lowerCase('__FOO_BAR__');
+ * // => 'foo bar'
+ */
+ var lowerCase = createCompounder(function(result, word, index) {
+ return result + (index ? ' ' : '') + word.toLowerCase();
+ });
+
+ /**
+ * Converts the first character of `string` to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.lowerFirst('Fred');
+ * // => 'fred'
+ *
+ * _.lowerFirst('FRED');
+ * // => 'fRED'
+ */
+ var lowerFirst = createCaseFirst('toLowerCase');
+
+ /**
+ * Converts the first character of `string` to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.upperFirst('fred');
+ * // => 'Fred'
+ *
+ * _.upperFirst('FRED');
+ * // => 'FRED'
+ */
+ var upperFirst = createCaseFirst('toUpperCase');
+
/**
* Pads `string` on the left and right sides if it's shorter than `length`.
* Padding characters are truncated if they can't be evenly divided by `length`.
@@ -10399,19 +11964,45 @@
* // => 'abc'
*/
function pad(string, length, chars) {
- string = baseToString(string);
- length = +length;
+ string = toString(string);
+ length = toInteger(length);
- var strLength = string.length;
- if (strLength >= length || !nativeIsFinite(length)) {
+ var strLength = stringSize(string);
+ if (!length || strLength >= length) {
return string;
}
var mid = (length - strLength) / 2,
leftLength = nativeFloor(mid),
rightLength = nativeCeil(mid);
- chars = createPadding('', rightLength, chars);
- return chars.slice(0, leftLength) + string + chars;
+ return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
+ }
+
+ /**
+ * Pads `string` on the right side if it's shorter than `length`. Padding
+ * characters are truncated if they exceed `length`.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to pad.
+ * @param {number} [length=0] The padding length.
+ * @param {string} [chars=' '] The string used as padding.
+ * @returns {string} Returns the padded string.
+ * @example
+ *
+ * _.padEnd('abc', 6);
+ * // => 'abc '
+ *
+ * _.padEnd('abc', 6, '_-');
+ * // => 'abc_-_'
+ *
+ * _.padEnd('abc', 3);
+ * // => 'abc'
+ */
+ function padEnd(string, length, chars) {
+ string = toString(string);
+ return string + createPadding(string, length, chars);
}
/**
@@ -10427,40 +12018,19 @@
* @returns {string} Returns the padded string.
* @example
*
- * _.padLeft('abc', 6);
+ * _.padStart('abc', 6);
* // => ' abc'
*
- * _.padLeft('abc', 6, '_-');
+ * _.padStart('abc', 6, '_-');
* // => '_-_abc'
*
- * _.padLeft('abc', 3);
+ * _.padStart('abc', 3);
* // => 'abc'
*/
- var padLeft = createPadDir();
-
- /**
- * Pads `string` on the right side if it's shorter than `length`. Padding
- * characters are truncated if they exceed `length`.
- *
- * @static
- * @memberOf _
- * @category String
- * @param {string} [string=''] The string to pad.
- * @param {number} [length=0] The padding length.
- * @param {string} [chars=' '] The string used as padding.
- * @returns {string} Returns the padded string.
- * @example
- *
- * _.padRight('abc', 6);
- * // => 'abc '
- *
- * _.padRight('abc', 6, '_-');
- * // => 'abc_-_'
- *
- * _.padRight('abc', 3);
- * // => 'abc'
- */
- var padRight = createPadDir(true);
+ function padStart(string, length, chars) {
+ string = toString(string);
+ return createPadding(string, length, chars) + string;
+ }
/**
* Converts `string` to an integer of the specified radix. If `radix` is
@@ -10475,7 +12045,7 @@
* @category String
* @param {string} string The string to convert.
* @param {number} [radix] The radix to interpret `value` by.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {number} Returns the converted integer.
* @example
*
@@ -10486,15 +12056,14 @@
* // => [6, 8, 10]
*/
function parseInt(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) {
+ if (guard || radix == null) {
radix = 0;
} else if (radix) {
radix = +radix;
}
- string = trim(string);
+ string = toString(string).replace(reTrim, '');
return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
}
@@ -10519,10 +12088,11 @@
* // => ''
*/
function repeat(string, n) {
+ string = toString(string);
+ n = toInteger(n);
+
var result = '';
- string = baseToString(string);
- n = +n;
- if (n < 1 || !string || !nativeIsFinite(n)) {
+ if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
return result;
}
// Leverage the exponentiation by squaring algorithm for a faster repeat.
@@ -10538,6 +12108,30 @@
return result;
}
+ /**
+ * Replaces matches for `pattern` in `string` with `replacement`.
+ *
+ * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to modify.
+ * @param {RegExp|string} pattern The pattern to replace.
+ * @param {Function|string} replacement The match replacement.
+ * @returns {string} Returns the modified string.
+ * @example
+ *
+ * _.replace('Hi Fred', 'Fred', 'Barney');
+ * // => 'Hi Barney'
+ */
+ function replace() {
+ var args = arguments,
+ string = toString(args[0]);
+
+ return args.length < 3 ? string : string.replace(args[1], args[2]);
+ }
+
/**
* Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
*
@@ -10561,6 +12155,27 @@
return result + (index ? '_' : '') + word.toLowerCase();
});
+ /**
+ * Splits `string` by `separator`.
+ *
+ * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to split.
+ * @param {RegExp|string} separator The separator pattern to split by.
+ * @param {number} [limit] The length to truncate results to.
+ * @returns {Array} Returns the new array of string segments.
+ * @example
+ *
+ * _.split('a-b-c', '-', 2);
+ * // => ['a', 'b']
+ */
+ function split(string, separator, limit) {
+ return toString(string).split(separator, limit);
+ }
+
/**
* Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
*
@@ -10581,7 +12196,7 @@
* // => 'Foo Bar'
*/
var startCase = createCompounder(function(result, word, index) {
- return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));
+ return result + (index ? ' ' : '') + capitalize(word);
});
/**
@@ -10606,11 +12221,8 @@
* // => true
*/
function startsWith(string, target, position) {
- string = baseToString(string);
- position = position == null
- ? 0
- : nativeMin(position < 0 ? 0 : (+position || 0), string.length);
-
+ string = toString(string);
+ position = baseClamp(toInteger(position), 0, string.length);
return string.lastIndexOf(target, position) == position;
}
@@ -10642,7 +12254,7 @@
* @param {RegExp} [options.interpolate] The "interpolate" delimiter.
* @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
* @param {string} [options.variable] The data object variable name.
- * @param- {Object} [otherOptions] Enables the legacy `options` param signature.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the compiled template function.
* @example
*
@@ -10710,18 +12322,18 @@
* };\
* ');
*/
- function template(string, options, otherOptions) {
+ function template(string, options, guard) {
// Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
// and Laura Doktorova's doT.js (https://github.com/olado/doT).
var settings = lodash.templateSettings;
- if (otherOptions && isIterateeCall(string, options, otherOptions)) {
- options = otherOptions = undefined;
+ if (guard && isIterateeCall(string, options, guard)) {
+ options = undefined;
}
- string = baseToString(string);
- options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);
+ string = toString(string);
+ options = assignInWith({}, options, settings, assignInDefaults);
- var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults),
+ var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
importsKeys = keys(imports),
importsValues = baseValues(imports, importsKeys);
@@ -10766,8 +12378,8 @@
}
index = offset + match.length;
- // The JS engine embedded in Adobe products requires returning the `match`
- // string in order to produce the correct `offset` value.
+ // The JS engine embedded in Adobe products needs `match` returned in
+ // order to produce the correct `offset` value.
return match;
});
@@ -10816,6 +12428,52 @@
return result;
}
+ /**
+ * Converts `string`, as a whole, to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the lower cased string.
+ * @example
+ *
+ * _.toLower('--Foo-Bar');
+ * // => '--foo-bar'
+ *
+ * _.toLower('fooBar');
+ * // => 'foobar'
+ *
+ * _.toLower('__FOO_BAR__');
+ * // => '__foo_bar__'
+ */
+ function toLower(value) {
+ return toString(value).toLowerCase();
+ }
+
+ /**
+ * Converts `string`, as a whole, to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the upper cased string.
+ * @example
+ *
+ * _.toUpper('--foo-bar');
+ * // => '--FOO-BAR'
+ *
+ * _.toUpper('fooBar');
+ * // => 'FOOBAR'
+ *
+ * _.toUpper('__foo_bar__');
+ * // => '__FOO_BAR__'
+ */
+ function toUpper(value) {
+ return toString(value).toUpperCase();
+ }
+
/**
* Removes leading and trailing whitespace or specified characters from `string`.
*
@@ -10824,7 +12482,7 @@
* @category String
* @param {string} [string=''] The string to trim.
* @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {string} Returns the trimmed string.
* @example
*
@@ -10838,46 +12496,21 @@
* // => ['foo', 'bar']
*/
function trim(string, chars, guard) {
- var value = string;
- string = baseToString(string);
+ string = toString(string);
if (!string) {
return string;
}
- if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
- return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
+ if (guard || chars === undefined) {
+ return string.replace(reTrim, '');
}
chars = (chars + '');
- return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
- }
-
- /**
- * Removes leading whitespace or specified characters from `string`.
- *
- * @static
- * @memberOf _
- * @category String
- * @param {string} [string=''] The string to trim.
- * @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {string} Returns the trimmed string.
- * @example
- *
- * _.trimLeft(' abc ');
- * // => 'abc '
- *
- * _.trimLeft('-_-abc-_-', '_-');
- * // => 'abc-_-'
- */
- function trimLeft(string, chars, guard) {
- var value = string;
- string = baseToString(string);
- if (!string) {
+ if (!chars) {
return string;
}
- if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
- return string.slice(trimmedLeftIndex(string));
- }
- return string.slice(charsLeftIndex(string, (chars + '')));
+ var strSymbols = stringToArray(string),
+ chrSymbols = stringToArray(chars);
+
+ return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join('');
}
/**
@@ -10888,26 +12521,64 @@
* @category String
* @param {string} [string=''] The string to trim.
* @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {string} Returns the trimmed string.
* @example
*
- * _.trimRight(' abc ');
+ * _.trimEnd(' abc ');
* // => ' abc'
*
- * _.trimRight('-_-abc-_-', '_-');
+ * _.trimEnd('-_-abc-_-', '_-');
* // => '-_-abc'
*/
- function trimRight(string, chars, guard) {
- var value = string;
- string = baseToString(string);
+ function trimEnd(string, chars, guard) {
+ string = toString(string);
if (!string) {
return string;
}
- if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
- return string.slice(0, trimmedRightIndex(string) + 1);
+ if (guard || chars === undefined) {
+ return string.replace(reTrimEnd, '');
}
- return string.slice(0, charsRightIndex(string, (chars + '')) + 1);
+ chars = (chars + '');
+ if (!chars) {
+ return string;
+ }
+ var strSymbols = stringToArray(string);
+ return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join('');
+ }
+
+ /**
+ * Removes leading whitespace or specified characters from `string`.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to trim.
+ * @param {string} [chars=whitespace] The characters to trim.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {string} Returns the trimmed string.
+ * @example
+ *
+ * _.trimStart(' abc ');
+ * // => 'abc '
+ *
+ * _.trimStart('-_-abc-_-', '_-');
+ * // => 'abc-_-'
+ */
+ function trimStart(string, chars, guard) {
+ string = toString(string);
+ if (!string) {
+ return string;
+ }
+ if (guard || chars === undefined) {
+ return string.replace(reTrimStart, '');
+ }
+ chars = (chars + '');
+ if (!chars) {
+ return string;
+ }
+ var strSymbols = stringToArray(string);
+ return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join('');
}
/**
@@ -10919,79 +12590,79 @@
* @memberOf _
* @category String
* @param {string} [string=''] The string to truncate.
- * @param {Object|number} [options] The options object or maximum string length.
+ * @param {Object} [options] The options object.
* @param {number} [options.length=30] The maximum string length.
* @param {string} [options.omission='...'] The string to indicate text is omitted.
* @param {RegExp|string} [options.separator] The separator pattern to truncate to.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
* @returns {string} Returns the truncated string.
* @example
*
- * _.trunc('hi-diddly-ho there, neighborino');
+ * _.truncate('hi-diddly-ho there, neighborino');
* // => 'hi-diddly-ho there, neighbo...'
*
- * _.trunc('hi-diddly-ho there, neighborino', 24);
- * // => 'hi-diddly-ho there, n...'
- *
- * _.trunc('hi-diddly-ho there, neighborino', {
+ * _.truncate('hi-diddly-ho there, neighborino', {
* 'length': 24,
* 'separator': ' '
* });
* // => 'hi-diddly-ho there,...'
*
- * _.trunc('hi-diddly-ho there, neighborino', {
+ * _.truncate('hi-diddly-ho there, neighborino', {
* 'length': 24,
* 'separator': /,? +/
* });
* // => 'hi-diddly-ho there...'
*
- * _.trunc('hi-diddly-ho there, neighborino', {
+ * _.truncate('hi-diddly-ho there, neighborino', {
* 'omission': ' [...]'
* });
* // => 'hi-diddly-ho there, neig [...]'
*/
- function trunc(string, options, guard) {
- if (guard && isIterateeCall(string, options, guard)) {
- options = undefined;
- }
+ function truncate(string, options) {
var length = DEFAULT_TRUNC_LENGTH,
omission = DEFAULT_TRUNC_OMISSION;
- if (options != null) {
- if (isObject(options)) {
- var separator = 'separator' in options ? options.separator : separator;
- length = 'length' in options ? (+options.length || 0) : length;
- omission = 'omission' in options ? baseToString(options.omission) : omission;
- } else {
- length = +options || 0;
- }
+ if (isObject(options)) {
+ var separator = 'separator' in options ? options.separator : separator;
+ length = 'length' in options ? toInteger(options.length) : length;
+ omission = 'omission' in options ? toString(options.omission) : omission;
}
- string = baseToString(string);
- if (length >= string.length) {
+ string = toString(string);
+
+ var strLength = string.length;
+ if (reHasComplexSymbol.test(string)) {
+ var strSymbols = stringToArray(string);
+ strLength = strSymbols.length;
+ }
+ if (length >= strLength) {
return string;
}
- var end = length - omission.length;
+ var end = length - stringSize(omission);
if (end < 1) {
return omission;
}
- var result = string.slice(0, end);
- if (separator == null) {
+ var result = strSymbols
+ ? strSymbols.slice(0, end).join('')
+ : string.slice(0, end);
+
+ if (separator === undefined) {
return result + omission;
}
+ if (strSymbols) {
+ end += (result.length - end);
+ }
if (isRegExp(separator)) {
if (string.slice(end).search(separator)) {
var match,
- newEnd,
- substring = string.slice(0, end);
+ substring = result;
if (!separator.global) {
- separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g');
+ separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
}
separator.lastIndex = 0;
while ((match = separator.exec(substring))) {
- newEnd = match.index;
+ var newEnd = match.index;
}
- result = result.slice(0, newEnd == null ? end : newEnd);
+ result = result.slice(0, newEnd === undefined ? end : newEnd);
}
} else if (string.indexOf(separator, end) != end) {
var index = result.lastIndexOf(separator);
@@ -11021,12 +12692,35 @@
* // => 'fred, barney, & pebbles'
*/
function unescape(string) {
- string = baseToString(string);
+ string = toString(string);
return (string && reHasEscapedHtml.test(string))
? string.replace(reEscapedHtml, unescapeHtmlChar)
: string;
}
+ /**
+ * Converts `string`, as space separated words, to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the upper cased string.
+ * @example
+ *
+ * _.upperCase('--foo-bar');
+ * // => 'FOO BAR'
+ *
+ * _.upperCase('fooBar');
+ * // => 'FOO BAR'
+ *
+ * _.upperCase('__foo_bar__');
+ * // => 'FOO BAR'
+ */
+ var upperCase = createCompounder(function(result, word, index) {
+ return result + (index ? ' ' : '') + word.toUpperCase();
+ });
+
/**
* Splits `string` into an array of its words.
*
@@ -11035,7 +12729,7 @@
* @category String
* @param {string} [string=''] The string to inspect.
* @param {RegExp|string} [pattern] The pattern to match words.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the words of `string`.
* @example
*
@@ -11046,11 +12740,13 @@
* // => ['fred', 'barney', '&', 'pebbles']
*/
function words(string, pattern, guard) {
- if (guard && isIterateeCall(string, pattern, guard)) {
- pattern = undefined;
+ string = toString(string);
+ pattern = guard ? undefined : pattern;
+
+ if (pattern === undefined) {
+ pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
}
- string = baseToString(string);
- return string.match(pattern || reWords) || [];
+ return string.match(pattern) || [];
}
/*------------------------------------------------------------------------*/
@@ -11061,7 +12757,7 @@
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Function} func The function to attempt.
* @returns {*} Returns the `func` result or error object.
* @example
@@ -11075,29 +12771,107 @@
* elements = [];
* }
*/
- var attempt = restParam(function(func, args) {
+ var attempt = rest(function(func, args) {
try {
- return func.apply(undefined, args);
- } catch(e) {
+ return apply(func, undefined, args);
+ } catch (e) {
return isError(e) ? e : new Error(e);
}
});
/**
- * Creates a function that invokes `func` with the `this` binding of `thisArg`
- * and arguments of the created function. If `func` is a property name the
- * created callback returns the property value for a given element. If `func`
- * is an object the created callback returns `true` for elements that contain
- * the equivalent object properties, otherwise it returns `false`.
+ * Binds methods of an object to the object itself, overwriting the existing
+ * method.
+ *
+ * **Note:** This method doesn't set the "length" property of bound functions.
*
* @static
* @memberOf _
- * @alias iteratee
- * @category Utility
- * @param {*} [func=_.identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {Function} Returns the callback.
+ * @category Util
+ * @param {Object} object The object to bind and assign the bound methods to.
+ * @param {...(string|string[])} methodNames The object method names to bind,
+ * specified individually or in arrays.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var view = {
+ * 'label': 'docs',
+ * 'onClick': function() {
+ * console.log('clicked ' + this.label);
+ * }
+ * };
+ *
+ * _.bindAll(view, 'onClick');
+ * jQuery(element).on('click', view.onClick);
+ * // => logs 'clicked docs' when clicked
+ */
+ var bindAll = rest(function(object, methodNames) {
+ arrayEach(baseFlatten(methodNames), function(key) {
+ object[key] = bind(object[key], object);
+ });
+ return object;
+ });
+
+ /**
+ * Creates a function that iterates over `pairs` invoking the corresponding
+ * function of the first predicate to return truthy. The predicate-function
+ * pairs are invoked with the `this` binding and arguments of the created
+ * function.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Array} pairs The predicate-function pairs.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.cond([
+ * [_.matches({ 'a': 1 }), _.constant('matches A')],
+ * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
+ * [_.constant(true), _.constant('no match')]
+ * ])
+ *
+ * func({ 'a': 1, 'b': 2 });
+ * // => 'matches A'
+ *
+ * func({ 'a': 0, 'b': 1 });
+ * // => 'matches B'
+ *
+ * func({ 'a': '1', 'b': '2' });
+ * // => 'no match'
+ */
+ function cond(pairs) {
+ var length = pairs ? pairs.length : 0,
+ toIteratee = getIteratee();
+
+ pairs = !length ? [] : arrayMap(pairs, function(pair) {
+ if (typeof pair[1] != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ return [toIteratee(pair[0]), pair[1]];
+ });
+
+ return rest(function(args) {
+ var index = -1;
+ while (++index < length) {
+ var pair = pairs[index];
+ if (apply(pair[0], this, args)) {
+ return apply(pair[1], this, args);
+ }
+ }
+ });
+ }
+
+ /**
+ * Creates a function that invokes the predicate properties of `source` with
+ * the corresponding property values of a given object, returning `true` if
+ * all predicates return truthy, else `false`.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Object} source The object of property predicates to conform to.
+ * @returns {Function} Returns the new function.
* @example
*
* var users = [
@@ -11105,29 +12879,11 @@
* { 'user': 'fred', 'age': 40 }
* ];
*
- * // wrap to create custom callback shorthands
- * _.callback = _.wrap(_.callback, function(callback, func, thisArg) {
- * var match = /^(.+?)__([gl]t)(.+)$/.exec(func);
- * if (!match) {
- * return callback(func, thisArg);
- * }
- * return function(object) {
- * return match[2] == 'gt'
- * ? object[match[1]] > match[3]
- * : object[match[1]] < match[3];
- * };
- * });
- *
- * _.filter(users, 'age__gt36');
+ * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
* // => [{ 'user': 'fred', 'age': 40 }]
*/
- function callback(func, thisArg, guard) {
- if (guard && isIterateeCall(func, thisArg, guard)) {
- thisArg = undefined;
- }
- return isObjectLike(func)
- ? matches(func)
- : baseCallback(func, thisArg);
+ function conforms(source) {
+ return baseConforms(baseClone(source, true));
}
/**
@@ -11135,7 +12891,7 @@
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {*} value The value to return from the new function.
* @returns {Function} Returns the new function.
* @example
@@ -11152,12 +12908,55 @@
};
}
+ /**
+ * Creates a function that returns the result of invoking the provided
+ * functions with the `this` binding of the created function, where each
+ * successive invocation is supplied the return value of the previous.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} [funcs] Functions to invoke.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var addSquare = _.flow(_.add, square);
+ * addSquare(1, 2);
+ * // => 9
+ */
+ var flow = createFlow();
+
+ /**
+ * This method is like `_.flow` except that it creates a function that
+ * invokes the provided functions from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} [funcs] Functions to invoke.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var addSquare = _.flowRight(square, _.add);
+ * addSquare(1, 2);
+ * // => 9
+ */
+ var flowRight = createFlow(true);
+
/**
* This method returns the first argument provided to it.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {*} value Any value.
* @returns {*} Returns `value`.
* @example
@@ -11172,18 +12971,50 @@
}
/**
- * Creates a function that performs a deep comparison between a given object
- * and `source`, returning `true` if the given object has equivalent property
- * values, else `false`.
- *
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties. For comparing a single
- * own or inherited property value see `_.matchesProperty`.
+ * Creates a function that invokes `func` with the arguments of the created
+ * function. If `func` is a property name the created callback returns the
+ * property value for a given element. If `func` is an object the created
+ * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
+ * @param {*} [func=_.identity] The value to convert to a callback.
+ * @returns {Function} Returns the callback.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 }
+ * ];
+ *
+ * // create custom iteratee shorthands
+ * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
+ * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
+ * return !p ? callback(func) : function(object) {
+ * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
+ * };
+ * });
+ *
+ * _.filter(users, 'age > 36');
+ * // => [{ 'user': 'fred', 'age': 40 }]
+ */
+ function iteratee(func) {
+ return (isObjectLike(func) && !isArray(func))
+ ? matches(func)
+ : baseIteratee(func);
+ }
+
+ /**
+ * Creates a function that performs a deep partial comparison between a given
+ * object and `source`, returning `true` if the given object has equivalent
+ * property values, else `false`.
+ *
+ * **Note:** This method supports comparing the same values as `_.isEqual`.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
* @param {Object} source The object of property values to match.
* @returns {Function} Returns the new function.
* @example
@@ -11201,16 +13032,15 @@
}
/**
- * Creates a function that compares the property value of `path` on a given
- * object to `value`.
+ * Creates a function that performs a deep partial comparison between the
+ * value at `path` of a given object to `srcValue`, returning `true` if the
+ * object value is equivalent, else `false`.
*
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties.
+ * **Note:** This method supports comparing the same values as `_.isEqual`.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Array|string} path The path of the property to get.
* @param {*} srcValue The value to match.
* @returns {Function} Returns the new function.
@@ -11229,12 +13059,12 @@
}
/**
- * Creates a function that invokes the method at `path` on a given object.
+ * Creates a function that invokes the method at `path` of a given object.
* Any additional arguments are provided to the invoked method.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Array|string} path The path of the method to invoke.
* @param {...*} [args] The arguments to invoke the method with.
* @returns {Function} Returns the new function.
@@ -11248,23 +13078,23 @@
* _.map(objects, _.method('a.b.c'));
* // => [2, 1]
*
- * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
+ * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
* // => [1, 2]
*/
- var method = restParam(function(path, args) {
+ var method = rest(function(path, args) {
return function(object) {
- return invokePath(object, path, args);
+ return baseInvoke(object, path, args);
};
});
/**
* The opposite of `_.method`; this method creates a function that invokes
- * the method at a given path on `object`. Any additional arguments are
+ * the method at a given path of `object`. Any additional arguments are
* provided to the invoked method.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Object} object The object to query.
* @param {...*} [args] The arguments to invoke the method with.
* @returns {Function} Returns the new function.
@@ -11279,9 +13109,9 @@
* _.map([['a', '2'], ['c', '0']], _.methodOf(object));
* // => [2, 0]
*/
- var methodOf = restParam(function(object, args) {
+ var methodOf = rest(function(object, args) {
return function(path) {
- return invokePath(object, path, args);
+ return baseInvoke(object, path, args);
};
});
@@ -11295,7 +13125,7 @@
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Function|Object} [object=lodash] The destination object.
* @param {Object} source The object of functions to add.
* @param {Object} [options] The options object.
@@ -11322,53 +13152,38 @@
* // => ['e']
*/
function mixin(object, source, options) {
- if (options == null) {
- var isObj = isObject(source),
- props = isObj ? keys(source) : undefined,
- methodNames = (props && props.length) ? baseFunctions(source, props) : undefined;
+ var props = keys(source),
+ methodNames = baseFunctions(source, props);
- if (!(methodNames ? methodNames.length : isObj)) {
- methodNames = false;
- options = source;
- source = object;
- object = this;
- }
- }
- if (!methodNames) {
+ if (options == null &&
+ !(isObject(source) && (methodNames.length || !props.length))) {
+ options = source;
+ source = object;
+ object = this;
methodNames = baseFunctions(source, keys(source));
}
- var chain = true,
- index = -1,
- isFunc = isFunction(object),
- length = methodNames.length;
-
- if (options === false) {
- chain = false;
- } else if (isObject(options) && 'chain' in options) {
- chain = options.chain;
- }
- while (++index < length) {
- var methodName = methodNames[index],
- func = source[methodName];
+ var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
+ isFunc = isFunction(object);
+ arrayEach(methodNames, function(methodName) {
+ var func = source[methodName];
object[methodName] = func;
if (isFunc) {
- object.prototype[methodName] = (function(func) {
- return function() {
- var chainAll = this.__chain__;
- if (chain || chainAll) {
- var result = object(this.__wrapped__),
- actions = result.__actions__ = arrayCopy(this.__actions__);
+ object.prototype[methodName] = function() {
+ var chainAll = this.__chain__;
+ if (chain || chainAll) {
+ var result = object(this.__wrapped__),
+ actions = result.__actions__ = copyArray(this.__actions__);
- actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
- result.__chain__ = chainAll;
- return result;
- }
- return func.apply(object, arrayPush([this.value()], arguments));
- };
- }(func));
+ actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
+ result.__chain__ = chainAll;
+ return result;
+ }
+ return func.apply(object, arrayPush([this.value()], arguments));
+ };
}
- }
+ });
+
return object;
}
@@ -11378,7 +13193,7 @@
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @returns {Function} Returns the `lodash` function.
* @example
*
@@ -11395,7 +13210,7 @@
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @example
*
* var object = { 'user': 'fred' };
@@ -11408,12 +13223,99 @@
}
/**
- * Creates a function that returns the property value at `path` on a
- * given object.
+ * Creates a function that returns its nth argument.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
+ * @param {number} [n=0] The index of the argument to return.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.nthArg(1);
+ *
+ * func('a', 'b', 'c');
+ * // => 'b'
+ */
+ function nthArg(n) {
+ n = toInteger(n);
+ return function() {
+ return arguments[n];
+ };
+ }
+
+ /**
+ * Creates a function that invokes `iteratees` with the arguments provided
+ * to the created function and returns their results.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} iteratees The iteratees to invoke.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.over(Math.max, Math.min);
+ *
+ * func(1, 2, 3, 4);
+ * // => [4, 1]
+ */
+ var over = createOver(arrayMap);
+
+ /**
+ * Creates a function that checks if **all** of the `predicates` return
+ * truthy when invoked with the arguments provided to the created function.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} predicates The predicates to check.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.overEvery(Boolean, isFinite);
+ *
+ * func('1');
+ * // => true
+ *
+ * func(null);
+ * // => false
+ *
+ * func(NaN);
+ * // => false
+ */
+ var overEvery = createOver(arrayEvery);
+
+ /**
+ * Creates a function that checks if **any** of the `predicates` return
+ * truthy when invoked with the arguments provided to the created function.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} predicates The predicates to check.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.overSome(Boolean, isFinite);
+ *
+ * func('1');
+ * // => true
+ *
+ * func(null);
+ * // => true
+ *
+ * func(NaN);
+ * // => false
+ */
+ var overSome = createOver(arraySome);
+
+ /**
+ * Creates a function that returns the value at `path` of a given object.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
* @param {Array|string} path The path of the property to get.
* @returns {Function} Returns the new function.
* @example
@@ -11426,7 +13328,7 @@
* _.map(objects, _.property('a.b.c'));
* // => [2, 1]
*
- * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
+ * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
* // => [1, 2]
*/
function property(path) {
@@ -11435,11 +13337,11 @@
/**
* The opposite of `_.property`; this method creates a function that returns
- * the property value at a given path on `object`.
+ * the value at a given path of `object`.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Object} object The object to query.
* @returns {Function} Returns the new function.
* @example
@@ -11455,19 +13357,23 @@
*/
function propertyOf(object) {
return function(path) {
- return baseGet(object, toPath(path), (path + ''));
+ return object == null ? undefined : baseGet(object, path);
};
}
/**
* Creates an array of numbers (positive and/or negative) progressing from
- * `start` up to, but not including, `end`. If `end` is not specified it's
- * set to `start` with `start` then set to `0`. If `end` is less than `start`
- * a zero-length range is created unless a negative `step` is specified.
+ * `start` up to, but not including, `end`. A step of `-1` is used if a negative
+ * `start` is specified without an `end` or `step`. If `end` is not specified
+ * it's set to `start` with `start` then set to `0`. If `end` is less than
+ * `start` a zero-length range is created unless a negative `step` is specified.
+ *
+ * **Note:** JavaScript follows the IEEE-754 standard for resolving
+ * floating-point values which can produce unexpected results.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {number} [start=0] The start of the range.
* @param {number} end The end of the range.
* @param {number} [step=1] The value to increment or decrement by.
@@ -11477,6 +13383,9 @@
* _.range(4);
* // => [0, 1, 2, 3]
*
+ * _.range(-4);
+ * // => [0, -1, -2, -3]
+ *
* _.range(1, 5);
* // => [1, 2, 3, 4]
*
@@ -11492,79 +13401,107 @@
* _.range(0);
* // => []
*/
- function range(start, end, step) {
- if (step && isIterateeCall(start, end, step)) {
- end = step = undefined;
- }
- start = +start || 0;
- step = step == null ? 1 : (+step || 0);
+ var range = createRange();
- if (end == null) {
- end = start;
- start = 0;
- } else {
- end = +end || 0;
- }
- // 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(nativeCeil((end - start) / (step || 1)), 0),
- result = Array(length);
+ /**
+ * This method is like `_.range` except that it populates values in
+ * descending order.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {number} [start=0] The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} [step=1] The value to increment or decrement by.
+ * @returns {Array} Returns the new array of numbers.
+ * @example
+ *
+ * _.rangeRight(4);
+ * // => [3, 2, 1, 0]
+ *
+ * _.rangeRight(-4);
+ * // => [-3, -2, -1, 0]
+ *
+ * _.rangeRight(1, 5);
+ * // => [4, 3, 2, 1]
+ *
+ * _.rangeRight(0, 20, 5);
+ * // => [15, 10, 5, 0]
+ *
+ * _.rangeRight(0, -4, -1);
+ * // => [-3, -2, -1, 0]
+ *
+ * _.rangeRight(1, 4, 0);
+ * // => [1, 1, 1]
+ *
+ * _.rangeRight(0);
+ * // => []
+ */
+ var rangeRight = createRange(true);
- while (++index < length) {
- result[index] = start;
- start += step;
+ /**
+ * Invokes the iteratee function `n` times, returning an array of the results
+ * of each invocation. The iteratee is invoked with one argument; (index).
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ * @example
+ *
+ * _.times(3, String);
+ * // => ['0', '1', '2']
+ *
+ * _.times(4, _.constant(true));
+ * // => [true, true, true, true]
+ */
+ function times(n, iteratee) {
+ n = toInteger(n);
+ if (n < 1 || n > MAX_SAFE_INTEGER) {
+ return [];
+ }
+ var index = MAX_ARRAY_LENGTH,
+ length = nativeMin(n, MAX_ARRAY_LENGTH);
+
+ iteratee = toFunction(iteratee);
+ n -= MAX_ARRAY_LENGTH;
+
+ var result = baseTimes(length, iteratee);
+ while (++index < n) {
+ iteratee(index);
}
return result;
}
/**
- * Invokes the iteratee function `n` times, returning an array of the results
- * of each invocation. The `iteratee` is bound to `thisArg` and invoked with
- * one argument; (index).
+ * Converts `value` to a property path array.
*
* @static
* @memberOf _
- * @category Utility
- * @param {number} n The number of times to invoke `iteratee`.
- * @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the array of results.
+ * @category Util
+ * @param {*} value The value to convert.
+ * @returns {Array} Returns the new property path array.
* @example
*
- * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false));
- * // => [3, 6, 4]
+ * _.toPath('a.b.c');
+ * // => ['a', 'b', 'c']
*
- * _.times(3, function(n) {
- * mage.castSpell(n);
- * });
- * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2`
+ * _.toPath('a[0].b.c');
+ * // => ['a', '0', 'b', 'c']
*
- * _.times(3, function(n) {
- * this.cast(n);
- * }, mage);
- * // => also invokes `mage.castSpell(n)` three times
+ * var path = ['a', 'b', 'c'],
+ * newPath = _.toPath(path);
+ *
+ * console.log(newPath);
+ * // => ['a', 'b', 'c']
+ *
+ * console.log(path === newPath);
+ * // => false
*/
- function times(n, iteratee, thisArg) {
- n = nativeFloor(n);
-
- // Exit early to avoid a JSC JIT bug in Safari 8
- // where `Array(0)` is treated as `Array(1)`.
- if (n < 1 || !nativeIsFinite(n)) {
- return [];
- }
- var index = -1,
- result = Array(nativeMin(n, MAX_ARRAY_LENGTH));
-
- iteratee = bindCallback(iteratee, thisArg, 1);
- while (++index < n) {
- if (index < MAX_ARRAY_LENGTH) {
- result[index] = iteratee(index);
- } else {
- iteratee(index);
- }
- }
- return result;
+ function toPath(value) {
+ return isArray(value) ? arrayMap(value, String) : stringToPath(value);
}
/**
@@ -11572,7 +13509,7 @@
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {string} [prefix] The value to prefix the ID with.
* @returns {string} Returns the unique ID.
* @example
@@ -11585,7 +13522,7 @@
*/
function uniqueId(prefix) {
var id = ++idCounter;
- return baseToString(prefix) + id;
+ return toString(prefix) + id;
}
/*------------------------------------------------------------------------*/
@@ -11596,25 +13533,32 @@
* @static
* @memberOf _
* @category Math
- * @param {number} augend The first number to add.
- * @param {number} addend The second number to add.
- * @returns {number} Returns the sum.
+ * @param {number} augend The first number in an addition.
+ * @param {number} addend The second number in an addition.
+ * @returns {number} Returns the total.
* @example
*
* _.add(6, 4);
* // => 10
*/
function add(augend, addend) {
- return (+augend || 0) + (+addend || 0);
+ var result;
+ if (augend !== undefined) {
+ result = augend;
+ }
+ if (addend !== undefined) {
+ result = result === undefined ? addend : (result + addend);
+ }
+ return result;
}
/**
- * Calculates `n` rounded up to `precision`.
+ * Computes `number` rounded up to `precision`.
*
* @static
* @memberOf _
* @category Math
- * @param {number} n The number to round up.
+ * @param {number} number The number to round up.
* @param {number} [precision=0] The precision to round up to.
* @returns {number} Returns the rounded up number.
* @example
@@ -11631,12 +13575,12 @@
var ceil = createRound('ceil');
/**
- * Calculates `n` rounded down to `precision`.
+ * Computes `number` rounded down to `precision`.
*
* @static
* @memberOf _
* @category Math
- * @param {number} n The number to round down.
+ * @param {number} number The number to round down.
* @param {number} [precision=0] The precision to round down to.
* @returns {number} Returns the rounded down number.
* @example
@@ -11653,29 +13597,13 @@
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's invoked
- * for each value in `collection` to generate the criterion by which the value
- * is ranked. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * Computes the maximum value of `array`. If `array` is empty or falsey
+ * `undefined` is returned.
*
* @static
* @memberOf _
* @category Math
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Array} array The array to iterate over.
* @returns {*} Returns the maximum value.
* @example
*
@@ -11683,48 +13611,67 @@
* // => 8
*
* _.max([]);
- * // => -Infinity
- *
- * var users = [
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 }
- * ];
- *
- * _.max(users, function(chr) {
- * return chr.age;
- * });
- * // => { 'user': 'fred', 'age': 40 }
- *
- * // using the `_.property` callback shorthand
- * _.max(users, 'age');
- * // => { 'user': 'fred', 'age': 40 }
+ * // => undefined
*/
- var max = createExtremum(gt, NEGATIVE_INFINITY);
+ function max(array) {
+ return (array && array.length)
+ ? baseExtremum(array, identity, gt)
+ : undefined;
+ }
/**
- * Gets the minimum value of `collection`. If `collection` is empty or falsey
- * `Infinity` is returned. If an iteratee function is provided it's invoked
- * for each value in `collection` to generate the criterion by which the value
- * is ranked. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * This method is like `_.max` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * the value is ranked. The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @category Math
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Array} array The array to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {*} Returns the maximum value.
+ * @example
+ *
+ * var objects = [{ 'n': 1 }, { 'n': 2 }];
+ *
+ * _.maxBy(objects, function(o) { return o.a; });
+ * // => { 'n': 2 }
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.maxBy(objects, 'n');
+ * // => { 'n': 2 }
+ */
+ function maxBy(array, iteratee) {
+ return (array && array.length)
+ ? baseExtremum(array, getIteratee(iteratee), gt)
+ : undefined;
+ }
+
+ /**
+ * Computes the mean of the values in `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {number} Returns the mean.
+ * @example
+ *
+ * _.mean([4, 2, 8, 6]);
+ * // => 5
+ */
+ function mean(array) {
+ return sum(array) / (array ? array.length : 0);
+ }
+
+ /**
+ * Computes the minimum value of `array`. If `array` is empty or falsey
+ * `undefined` is returned.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
* @returns {*} Returns the minimum value.
* @example
*
@@ -11732,31 +13679,49 @@
* // => 2
*
* _.min([]);
- * // => Infinity
- *
- * var users = [
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 }
- * ];
- *
- * _.min(users, function(chr) {
- * return chr.age;
- * });
- * // => { 'user': 'barney', 'age': 36 }
- *
- * // using the `_.property` callback shorthand
- * _.min(users, 'age');
- * // => { 'user': 'barney', 'age': 36 }
+ * // => undefined
*/
- var min = createExtremum(lt, POSITIVE_INFINITY);
+ function min(array) {
+ return (array && array.length)
+ ? baseExtremum(array, identity, lt)
+ : undefined;
+ }
/**
- * Calculates `n` rounded to `precision`.
+ * This method is like `_.min` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * the value is ranked. The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @category Math
- * @param {number} n The number to round.
+ * @param {Array} array The array to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {*} Returns the minimum value.
+ * @example
+ *
+ * var objects = [{ 'n': 1 }, { 'n': 2 }];
+ *
+ * _.minBy(objects, function(o) { return o.a; });
+ * // => { 'n': 1 }
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.minBy(objects, 'n');
+ * // => { 'n': 1 }
+ */
+ function minBy(array, iteratee) {
+ return (array && array.length)
+ ? baseExtremum(array, getIteratee(iteratee), lt)
+ : undefined;
+ }
+
+ /**
+ * Computes `number` rounded to `precision`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} number The number to round.
* @param {number} [precision=0] The precision to round to.
* @returns {number} Returns the rounded number.
* @example
@@ -11773,45 +13738,75 @@
var round = createRound('round');
/**
- * Gets the sum of the values in `collection`.
+ * Subtract two numbers.
*
* @static
* @memberOf _
* @category Math
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {number} minuend The first number in a subtraction.
+ * @param {number} subtrahend The second number in a subtraction.
+ * @returns {number} Returns the difference.
+ * @example
+ *
+ * _.subtract(6, 4);
+ * // => 2
+ */
+ function subtract(minuend, subtrahend) {
+ var result;
+ if (minuend !== undefined) {
+ result = minuend;
+ }
+ if (subtrahend !== undefined) {
+ result = result === undefined ? subtrahend : (result - subtrahend);
+ }
+ return result;
+ }
+
+ /**
+ * Computes the sum of the values in `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
* @returns {number} Returns the sum.
* @example
*
- * _.sum([4, 6]);
- * // => 10
- *
- * _.sum({ 'a': 4, 'b': 6 });
- * // => 10
- *
- * var objects = [
- * { 'n': 4 },
- * { 'n': 6 }
- * ];
- *
- * _.sum(objects, function(object) {
- * return object.n;
- * });
- * // => 10
- *
- * // using the `_.property` callback shorthand
- * _.sum(objects, 'n');
- * // => 10
+ * _.sum([4, 2, 8, 6]);
+ * // => 20
*/
- function sum(collection, iteratee, thisArg) {
- if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = undefined;
- }
- iteratee = getCallback(iteratee, thisArg, 3);
- return iteratee.length == 1
- ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee)
- : baseSum(collection, iteratee);
+ function sum(array) {
+ return (array && array.length)
+ ? baseSum(array, identity)
+ : undefined;
+ }
+
+ /**
+ * This method is like `_.sum` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the value to be summed.
+ * The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the sum.
+ * @example
+ *
+ * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
+ *
+ * _.sumBy(objects, function(o) { return o.n; });
+ * // => 20
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.sumBy(objects, 'n');
+ * // => 20
+ */
+ function sumBy(array, iteratee) {
+ return (array && array.length)
+ ? baseSum(array, getIteratee(iteratee))
+ : undefined;
}
/*------------------------------------------------------------------------*/
@@ -11825,15 +13820,26 @@
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
LazyWrapper.prototype.constructor = LazyWrapper;
- // Add functions to the `Map` cache.
+ // Avoid inheriting from `Object.prototype` when possible.
+ Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
+
+ // Add functions to the `MapCache`.
+ MapCache.prototype.clear = mapClear;
MapCache.prototype['delete'] = mapDelete;
MapCache.prototype.get = mapGet;
MapCache.prototype.has = mapHas;
MapCache.prototype.set = mapSet;
- // Add functions to the `Set` cache.
+ // Add functions to the `SetCache`.
SetCache.prototype.push = cachePush;
+ // Add functions to the `Stack` cache.
+ Stack.prototype.clear = stackClear;
+ Stack.prototype['delete'] = stackDelete;
+ Stack.prototype.get = stackGet;
+ Stack.prototype.has = stackHas;
+ Stack.prototype.set = stackSet;
+
// Assign cache to `_.memoize`.
memoize.Cache = MapCache;
@@ -11841,15 +13847,20 @@
lodash.after = after;
lodash.ary = ary;
lodash.assign = assign;
+ lodash.assignIn = assignIn;
+ lodash.assignInWith = assignInWith;
+ lodash.assignWith = assignWith;
lodash.at = at;
lodash.before = before;
lodash.bind = bind;
lodash.bindAll = bindAll;
lodash.bindKey = bindKey;
- lodash.callback = callback;
lodash.chain = chain;
lodash.chunk = chunk;
lodash.compact = compact;
+ lodash.concat = concat;
+ lodash.cond = cond;
+ lodash.conforms = conforms;
lodash.constant = constant;
lodash.countBy = countBy;
lodash.create = create;
@@ -11861,29 +13872,32 @@
lodash.defer = defer;
lodash.delay = delay;
lodash.difference = difference;
+ lodash.differenceBy = differenceBy;
+ lodash.differenceWith = differenceWith;
lodash.drop = drop;
lodash.dropRight = dropRight;
lodash.dropRightWhile = dropRightWhile;
lodash.dropWhile = dropWhile;
lodash.fill = fill;
lodash.filter = filter;
+ lodash.flatMap = flatMap;
lodash.flatten = flatten;
lodash.flattenDeep = flattenDeep;
+ lodash.flip = flip;
lodash.flow = flow;
lodash.flowRight = flowRight;
- lodash.forEach = forEach;
- lodash.forEachRight = forEachRight;
- lodash.forIn = forIn;
- lodash.forInRight = forInRight;
- lodash.forOwn = forOwn;
- lodash.forOwnRight = forOwnRight;
+ lodash.fromPairs = fromPairs;
lodash.functions = functions;
+ lodash.functionsIn = functionsIn;
lodash.groupBy = groupBy;
- lodash.indexBy = indexBy;
lodash.initial = initial;
lodash.intersection = intersection;
+ lodash.intersectionBy = intersectionBy;
+ lodash.intersectionWith = intersectionWith;
lodash.invert = invert;
- lodash.invoke = invoke;
+ lodash.invokeMap = invokeMap;
+ lodash.iteratee = iteratee;
+ lodash.keyBy = keyBy;
lodash.keys = keys;
lodash.keysIn = keysIn;
lodash.map = map;
@@ -11893,36 +13907,49 @@
lodash.matchesProperty = matchesProperty;
lodash.memoize = memoize;
lodash.merge = merge;
+ lodash.mergeWith = mergeWith;
lodash.method = method;
lodash.methodOf = methodOf;
lodash.mixin = mixin;
- lodash.modArgs = modArgs;
lodash.negate = negate;
+ lodash.nthArg = nthArg;
lodash.omit = omit;
+ lodash.omitBy = omitBy;
lodash.once = once;
- lodash.pairs = pairs;
+ lodash.orderBy = orderBy;
+ lodash.over = over;
+ lodash.overArgs = overArgs;
+ lodash.overEvery = overEvery;
+ lodash.overSome = overSome;
lodash.partial = partial;
lodash.partialRight = partialRight;
lodash.partition = partition;
lodash.pick = pick;
- lodash.pluck = pluck;
+ lodash.pickBy = pickBy;
lodash.property = property;
lodash.propertyOf = propertyOf;
lodash.pull = pull;
+ lodash.pullAll = pullAll;
+ lodash.pullAllBy = pullAllBy;
lodash.pullAt = pullAt;
lodash.range = range;
+ lodash.rangeRight = rangeRight;
lodash.rearg = rearg;
lodash.reject = reject;
lodash.remove = remove;
lodash.rest = rest;
- lodash.restParam = restParam;
+ lodash.reverse = reverse;
+ lodash.sampleSize = sampleSize;
lodash.set = set;
+ lodash.setWith = setWith;
lodash.shuffle = shuffle;
lodash.slice = slice;
lodash.sortBy = sortBy;
- lodash.sortByAll = sortByAll;
- lodash.sortByOrder = sortByOrder;
+ lodash.sortedUniq = sortedUniq;
+ lodash.sortedUniqBy = sortedUniqBy;
+ lodash.split = split;
lodash.spread = spread;
+ lodash.tail = tail;
lodash.take = take;
lodash.takeRight = takeRight;
lodash.takeRightWhile = takeRightWhile;
@@ -11930,37 +13957,39 @@
lodash.tap = tap;
lodash.throttle = throttle;
lodash.thru = thru;
- lodash.times = times;
lodash.toArray = toArray;
+ lodash.toPairs = toPairs;
+ lodash.toPairsIn = toPairsIn;
+ lodash.toPath = toPath;
lodash.toPlainObject = toPlainObject;
lodash.transform = transform;
+ lodash.unary = unary;
lodash.union = union;
+ lodash.unionBy = unionBy;
+ lodash.unionWith = unionWith;
lodash.uniq = uniq;
+ lodash.uniqBy = uniqBy;
+ lodash.uniqWith = uniqWith;
+ lodash.unset = unset;
lodash.unzip = unzip;
lodash.unzipWith = unzipWith;
lodash.values = values;
lodash.valuesIn = valuesIn;
- lodash.where = where;
lodash.without = without;
+ lodash.words = words;
lodash.wrap = wrap;
lodash.xor = xor;
+ lodash.xorBy = xorBy;
+ lodash.xorWith = xorWith;
lodash.zip = zip;
lodash.zipObject = zipObject;
lodash.zipWith = zipWith;
// Add aliases.
- lodash.backflow = flowRight;
- lodash.collect = map;
- lodash.compose = flowRight;
lodash.each = forEach;
lodash.eachRight = forEachRight;
- lodash.extend = assign;
- lodash.iteratee = callback;
- lodash.methods = functions;
- lodash.object = zipObject;
- lodash.select = filter;
- lodash.tail = rest;
- lodash.unique = uniq;
+ lodash.extend = assignIn;
+ lodash.extendWith = assignInWith;
// Add functions to `lodash.prototype`.
mixin(lodash, lodash);
@@ -11973,10 +14002,14 @@
lodash.camelCase = camelCase;
lodash.capitalize = capitalize;
lodash.ceil = ceil;
+ lodash.clamp = clamp;
lodash.clone = clone;
lodash.cloneDeep = cloneDeep;
+ lodash.cloneDeepWith = cloneDeepWith;
+ lodash.cloneWith = cloneWith;
lodash.deburr = deburr;
lodash.endsWith = endsWith;
+ lodash.eq = eq;
lodash.escape = escape;
lodash.escapeRegExp = escapeRegExp;
lodash.every = every;
@@ -11986,111 +14019,128 @@
lodash.findLast = findLast;
lodash.findLastIndex = findLastIndex;
lodash.findLastKey = findLastKey;
- lodash.findWhere = findWhere;
- lodash.first = first;
lodash.floor = floor;
+ lodash.forEach = forEach;
+ lodash.forEachRight = forEachRight;
+ lodash.forIn = forIn;
+ lodash.forInRight = forInRight;
+ lodash.forOwn = forOwn;
+ lodash.forOwnRight = forOwnRight;
lodash.get = get;
lodash.gt = gt;
lodash.gte = gte;
lodash.has = has;
+ lodash.hasIn = hasIn;
+ lodash.head = head;
lodash.identity = identity;
lodash.includes = includes;
lodash.indexOf = indexOf;
lodash.inRange = inRange;
+ lodash.invoke = invoke;
lodash.isArguments = isArguments;
lodash.isArray = isArray;
+ lodash.isArrayLike = isArrayLike;
+ lodash.isArrayLikeObject = isArrayLikeObject;
lodash.isBoolean = isBoolean;
lodash.isDate = isDate;
lodash.isElement = isElement;
lodash.isEmpty = isEmpty;
lodash.isEqual = isEqual;
+ lodash.isEqualWith = isEqualWith;
lodash.isError = isError;
lodash.isFinite = isFinite;
lodash.isFunction = isFunction;
+ lodash.isInteger = isInteger;
+ lodash.isLength = isLength;
lodash.isMatch = isMatch;
+ lodash.isMatchWith = isMatchWith;
lodash.isNaN = isNaN;
lodash.isNative = isNative;
+ lodash.isNil = isNil;
lodash.isNull = isNull;
lodash.isNumber = isNumber;
lodash.isObject = isObject;
+ lodash.isObjectLike = isObjectLike;
lodash.isPlainObject = isPlainObject;
lodash.isRegExp = isRegExp;
+ lodash.isSafeInteger = isSafeInteger;
lodash.isString = isString;
+ lodash.isSymbol = isSymbol;
lodash.isTypedArray = isTypedArray;
lodash.isUndefined = isUndefined;
+ lodash.join = join;
lodash.kebabCase = kebabCase;
lodash.last = last;
lodash.lastIndexOf = lastIndexOf;
+ lodash.lowerCase = lowerCase;
+ lodash.lowerFirst = lowerFirst;
lodash.lt = lt;
lodash.lte = lte;
lodash.max = max;
+ lodash.maxBy = maxBy;
+ lodash.mean = mean;
lodash.min = min;
+ lodash.minBy = minBy;
lodash.noConflict = noConflict;
lodash.noop = noop;
lodash.now = now;
lodash.pad = pad;
- lodash.padLeft = padLeft;
- lodash.padRight = padRight;
+ lodash.padEnd = padEnd;
+ lodash.padStart = padStart;
lodash.parseInt = parseInt;
lodash.random = random;
lodash.reduce = reduce;
lodash.reduceRight = reduceRight;
lodash.repeat = repeat;
+ lodash.replace = replace;
lodash.result = result;
lodash.round = round;
lodash.runInContext = runInContext;
+ lodash.sample = sample;
lodash.size = size;
lodash.snakeCase = snakeCase;
lodash.some = some;
lodash.sortedIndex = sortedIndex;
+ lodash.sortedIndexBy = sortedIndexBy;
+ lodash.sortedIndexOf = sortedIndexOf;
lodash.sortedLastIndex = sortedLastIndex;
+ lodash.sortedLastIndexBy = sortedLastIndexBy;
+ lodash.sortedLastIndexOf = sortedLastIndexOf;
lodash.startCase = startCase;
lodash.startsWith = startsWith;
+ lodash.subtract = subtract;
lodash.sum = sum;
+ lodash.sumBy = sumBy;
lodash.template = template;
+ lodash.times = times;
+ lodash.toInteger = toInteger;
+ lodash.toLength = toLength;
+ lodash.toLower = toLower;
+ lodash.toNumber = toNumber;
+ lodash.toSafeInteger = toSafeInteger;
+ lodash.toString = toString;
+ lodash.toUpper = toUpper;
lodash.trim = trim;
- lodash.trimLeft = trimLeft;
- lodash.trimRight = trimRight;
- lodash.trunc = trunc;
+ lodash.trimEnd = trimEnd;
+ lodash.trimStart = trimStart;
+ lodash.truncate = truncate;
lodash.unescape = unescape;
lodash.uniqueId = uniqueId;
- lodash.words = words;
+ lodash.upperCase = upperCase;
+ lodash.upperFirst = upperFirst;
// Add aliases.
- lodash.all = every;
- lodash.any = some;
- lodash.contains = includes;
- lodash.eq = isEqual;
- lodash.detect = find;
- lodash.foldl = reduce;
- lodash.foldr = reduceRight;
- lodash.head = first;
- lodash.include = includes;
- lodash.inject = reduce;
+ lodash.first = head;
mixin(lodash, (function() {
var source = {};
baseForOwn(lodash, function(func, methodName) {
- if (!lodash.prototype[methodName]) {
+ if (!hasOwnProperty.call(lodash.prototype, methodName)) {
source[methodName] = func;
}
});
return source;
- }()), false);
-
- /*------------------------------------------------------------------------*/
-
- // Add functions capable of returning wrapped and unwrapped values when chaining.
- lodash.sample = sample;
-
- lodash.prototype.sample = function(n) {
- if (!this.__chain__ && n == null) {
- return sample(this.value());
- }
- return this.thru(function(value) {
- return sample(value, n);
- });
- };
+ }()), { 'chain': false });
/*------------------------------------------------------------------------*/
@@ -12115,13 +14165,13 @@
if (filtered && !index) {
return new LazyWrapper(this);
}
- n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0);
+ n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
var result = this.clone();
if (filtered) {
- result.__takeCount__ = nativeMin(result.__takeCount__, n);
+ result.__takeCount__ = nativeMin(n, result.__takeCount__);
} else {
- result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
+ result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
}
return result;
};
@@ -12134,18 +14184,18 @@
// Add `LazyWrapper` methods that accept an `iteratee` value.
arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
var type = index + 1,
- isFilter = type != LAZY_MAP_FLAG;
+ isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
- LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {
+ LazyWrapper.prototype[methodName] = function(iteratee) {
var result = this.clone();
- result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type });
+ result.__iteratees__.push({ 'iteratee': getIteratee(iteratee, 3), 'type': type });
result.__filtered__ = result.__filtered__ || isFilter;
return result;
};
});
- // Add `LazyWrapper` methods for `_.first` and `_.last`.
- arrayEach(['first', 'last'], function(methodName, index) {
+ // Add `LazyWrapper` methods for `_.head` and `_.last`.
+ arrayEach(['head', 'last'], function(methodName, index) {
var takeName = 'take' + (index ? 'Right' : '');
LazyWrapper.prototype[methodName] = function() {
@@ -12153,8 +14203,8 @@
};
});
- // Add `LazyWrapper` methods for `_.initial` and `_.rest`.
- arrayEach(['initial', 'rest'], function(methodName, index) {
+ // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
+ arrayEach(['initial', 'tail'], function(methodName, index) {
var dropName = 'drop' + (index ? '' : 'Right');
LazyWrapper.prototype[methodName] = function() {
@@ -12162,29 +14212,36 @@
};
});
- // Add `LazyWrapper` methods for `_.pluck` and `_.where`.
- arrayEach(['pluck', 'where'], function(methodName, index) {
- var operationName = index ? 'filter' : 'map',
- createCallback = index ? baseMatches : property;
-
- LazyWrapper.prototype[methodName] = function(value) {
- return this[operationName](createCallback(value));
- };
- });
-
LazyWrapper.prototype.compact = function() {
return this.filter(identity);
};
- LazyWrapper.prototype.reject = function(predicate, thisArg) {
- predicate = getCallback(predicate, thisArg, 1);
+ LazyWrapper.prototype.find = function(predicate) {
+ return this.filter(predicate).head();
+ };
+
+ LazyWrapper.prototype.findLast = function(predicate) {
+ return this.reverse().find(predicate);
+ };
+
+ LazyWrapper.prototype.invokeMap = rest(function(path, args) {
+ if (typeof path == 'function') {
+ return new LazyWrapper(this);
+ }
+ return this.map(function(value) {
+ return baseInvoke(value, path, args);
+ });
+ });
+
+ LazyWrapper.prototype.reject = function(predicate) {
+ predicate = getIteratee(predicate, 3);
return this.filter(function(value) {
return !predicate(value);
});
};
LazyWrapper.prototype.slice = function(start, end) {
- start = start == null ? 0 : (+start || 0);
+ start = toInteger(start);
var result = this;
if (result.__filtered__ && (start > 0 || end < 0)) {
@@ -12196,74 +14253,70 @@
result = result.drop(start);
}
if (end !== undefined) {
- end = (+end || 0);
+ end = toInteger(end);
result = end < 0 ? result.dropRight(-end) : result.take(end - start);
}
return result;
};
- LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) {
- return this.reverse().takeWhile(predicate, thisArg).reverse();
+ LazyWrapper.prototype.takeRightWhile = function(predicate) {
+ return this.reverse().takeWhile(predicate).reverse();
};
LazyWrapper.prototype.toArray = function() {
- return this.take(POSITIVE_INFINITY);
+ return this.take(MAX_ARRAY_LENGTH);
};
// Add `LazyWrapper` methods to `lodash.prototype`.
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
- var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),
- retUnwrapped = /^(?:first|last)$/.test(methodName),
- lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName];
+ var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
+ isTaker = /^(?:head|last)$/.test(methodName),
+ lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
+ retUnwrapped = isTaker || /^find/.test(methodName);
if (!lodashFunc) {
return;
}
lodash.prototype[methodName] = function() {
- var args = retUnwrapped ? [1] : arguments,
- chainAll = this.__chain__,
- value = this.__wrapped__,
- isHybrid = !!this.__actions__.length,
+ var value = this.__wrapped__,
+ args = isTaker ? [1] : arguments,
isLazy = value instanceof LazyWrapper,
iteratee = args[0],
useLazy = isLazy || isArray(value);
+ var interceptor = function(value) {
+ var result = lodashFunc.apply(lodash, arrayPush([value], args));
+ return (isTaker && chainAll) ? result[0] : result;
+ };
+
if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
// Avoid lazy use if the iteratee has a "length" value other than `1`.
isLazy = useLazy = false;
}
- var interceptor = function(value) {
- return (retUnwrapped && chainAll)
- ? lodashFunc(value, 1)[0]
- : lodashFunc.apply(undefined, arrayPush([value], args));
- };
-
- var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined },
+ var chainAll = this.__chain__,
+ isHybrid = !!this.__actions__.length,
+ isUnwrapped = retUnwrapped && !chainAll,
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);
+ result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
return new LodashWrapper(result, chainAll);
}
- return this.thru(interceptor);
+ if (isUnwrapped && onlyLazy) {
+ return func.apply(this, args);
+ }
+ result = this.thru(interceptor);
+ return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
};
});
// Add `Array` and `String` methods to `lodash.prototype`.
- arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) {
- var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName],
+ arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
+ var func = arrayProto[methodName],
chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
- retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName);
+ retUnwrapped = /^(?:pop|shift)$/.test(methodName);
lodash.prototype[methodName] = function() {
var args = arguments;
@@ -12295,20 +14348,18 @@
LazyWrapper.prototype.value = lazyValue;
// Add chaining functions to the `lodash` wrapper.
+ lodash.prototype.at = wrapperAt;
lodash.prototype.chain = wrapperChain;
lodash.prototype.commit = wrapperCommit;
- lodash.prototype.concat = wrapperConcat;
+ lodash.prototype.flatMap = wrapperFlatMap;
+ lodash.prototype.next = wrapperNext;
lodash.prototype.plant = wrapperPlant;
lodash.prototype.reverse = wrapperReverse;
- lodash.prototype.toString = wrapperToString;
- lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
-
- // Add function aliases to the `lodash` wrapper.
- lodash.prototype.collect = lodash.prototype.map;
- lodash.prototype.head = lodash.prototype.first;
- lodash.prototype.select = lodash.prototype.filter;
- lodash.prototype.tail = lodash.prototype.rest;
+ lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
+ if (iteratorSymbol) {
+ lodash.prototype[iteratorSymbol] = wrapperToIterator;
+ }
return lodash;
}
@@ -12317,6 +14368,11 @@
// Export lodash.
var _ = runInContext();
+ // Expose lodash on the free variable `window` or `self` when available. This
+ // prevents errors in cases where lodash is loaded by a script tag in the presence
+ // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
+ (freeWindow || freeSelf || {})._ = _;
+
// Some AMD build optimizers like r.js check for condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// Define as an anonymous module so, through path mapping, it can be
diff --git a/map.js b/map.js
new file mode 100644
index 000000000..32c505cb2
--- /dev/null
+++ b/map.js
@@ -0,0 +1,50 @@
+define(['./internal/arrayMap', './internal/baseIteratee', './internal/baseMap', './isArray'], function(arrayMap, baseIteratee, baseMap, isArray) {
+
+ /**
+ * Creates an array of values by running each element in `collection` through
+ * `iteratee`. The iteratee is invoked with three arguments:
+ * (value, index|key, collection).
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+ *
+ * The guarded methods are:
+ * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
+ * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
+ * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
+ * and `words`
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * _.map([1, 2], square);
+ * // => [3, 6]
+ *
+ * _.map({ 'a': 1, 'b': 2 }, square);
+ * // => [3, 6] (iteration order is not guaranteed)
+ *
+ * var users = [
+ * { 'user': 'barney' },
+ * { 'user': 'fred' }
+ * ];
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.map(users, 'user');
+ * // => ['barney', 'fred']
+ */
+ function map(collection, iteratee) {
+ var func = isArray(collection) ? arrayMap : baseMap;
+ return func(collection, baseIteratee(iteratee, 3));
+ }
+
+ return map;
+});
diff --git a/object/mapKeys.js b/mapKeys.js
similarity index 62%
rename from object/mapKeys.js
rename to mapKeys.js
index bcb44aab2..9b3a85bbb 100644
--- a/object/mapKeys.js
+++ b/mapKeys.js
@@ -1,4 +1,4 @@
-define(['../internal/createObjectMapper'], function(createObjectMapper) {
+define(['./internal/baseForOwn', './internal/baseIteratee'], function(baseForOwn, baseIteratee) {
/**
* The opposite of `_.mapValues`; this method creates an object with the
@@ -9,9 +9,7 @@ define(['../internal/createObjectMapper'], function(createObjectMapper) {
* @memberOf _
* @category Object
* @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
* @returns {Object} Returns the new mapped object.
* @example
*
@@ -20,7 +18,15 @@ define(['../internal/createObjectMapper'], function(createObjectMapper) {
* });
* // => { 'a1': 1, 'b2': 2 }
*/
- var mapKeys = createObjectMapper(true);
+ function mapKeys(object, iteratee) {
+ var result = {};
+ iteratee = baseIteratee(iteratee, 3);
+
+ baseForOwn(object, function(value, key, object) {
+ result[iteratee(value, key, object)] = value;
+ });
+ return result;
+ }
return mapKeys;
});
diff --git a/mapValues.js b/mapValues.js
new file mode 100644
index 000000000..253b76f63
--- /dev/null
+++ b/mapValues.js
@@ -0,0 +1,39 @@
+define(['./internal/baseForOwn', './internal/baseIteratee'], function(baseForOwn, baseIteratee) {
+
+ /**
+ * Creates an object with the same keys as `object` and values generated by
+ * running each own enumerable property of `object` through `iteratee`. The
+ * iteratee function is invoked with three arguments: (value, key, object).
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new mapped object.
+ * @example
+ *
+ * var users = {
+ * 'fred': { 'user': 'fred', 'age': 40 },
+ * 'pebbles': { 'user': 'pebbles', 'age': 1 }
+ * };
+ *
+ * _.mapValues(users, function(o) { return o.age; });
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.mapValues(users, 'age');
+ * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+ */
+ function mapValues(object, iteratee) {
+ var result = {};
+ iteratee = baseIteratee(iteratee, 3);
+
+ baseForOwn(object, function(value, key, object) {
+ result[key] = iteratee(value, key, object);
+ });
+ return result;
+ }
+
+ return mapValues;
+});
diff --git a/matches.js b/matches.js
new file mode 100644
index 000000000..dae86a90f
--- /dev/null
+++ b/matches.js
@@ -0,0 +1,30 @@
+define(['./internal/baseClone', './internal/baseMatches'], function(baseClone, baseMatches) {
+
+ /**
+ * Creates a function that performs a deep partial comparison between a given
+ * object and `source`, returning `true` if the given object has equivalent
+ * property values, else `false`.
+ *
+ * **Note:** This method supports comparing the same values as `_.isEqual`.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * _.filter(users, _.matches({ 'age': 40, 'active': false }));
+ * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
+ */
+ function matches(source) {
+ return baseMatches(baseClone(source, true));
+ }
+
+ return matches;
+});
diff --git a/utility/matchesProperty.js b/matchesProperty.js
similarity index 55%
rename from utility/matchesProperty.js
rename to matchesProperty.js
index b4414e26d..3fda9b03b 100644
--- a/utility/matchesProperty.js
+++ b/matchesProperty.js
@@ -1,16 +1,15 @@
-define(['../internal/baseClone', '../internal/baseMatchesProperty'], function(baseClone, baseMatchesProperty) {
+define(['./internal/baseClone', './internal/baseMatchesProperty'], function(baseClone, baseMatchesProperty) {
/**
- * Creates a function that compares the property value of `path` on a given
- * object to `value`.
+ * Creates a function that performs a deep partial comparison between the
+ * value at `path` of a given object to `srcValue`, returning `true` if the
+ * object value is equivalent, else `false`.
*
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties.
+ * **Note:** This method supports comparing the same values as `_.isEqual`.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Array|string} path The path of the property to get.
* @param {*} srcValue The value to match.
* @returns {Function} Returns the new function.
diff --git a/math.js b/math.js
index 1aa9da59d..d9d5ca27d 100644
--- a/math.js
+++ b/math.js
@@ -1,11 +1,16 @@
-define(['./math/add', './math/ceil', './math/floor', './math/max', './math/min', './math/round', './math/sum'], function(add, ceil, floor, max, min, round, sum) {
+define(['./add', './ceil', './floor', './max', './maxBy', './mean', './min', './minBy', './round', './subtract', './sum', './sumBy'], function(add, ceil, floor, max, maxBy, mean, min, minBy, round, subtract, sum, sumBy) {
return {
'add': add,
'ceil': ceil,
'floor': floor,
'max': max,
+ 'maxBy': maxBy,
+ 'mean': mean,
'min': min,
+ 'minBy': minBy,
'round': round,
- 'sum': sum
+ 'subtract': subtract,
+ 'sum': sum,
+ 'sumBy': sumBy
};
});
diff --git a/math/add.js b/math/add.js
deleted file mode 100644
index 2bf7087c0..000000000
--- a/math/add.js
+++ /dev/null
@@ -1,22 +0,0 @@
-define([], function() {
-
- /**
- * Adds two numbers.
- *
- * @static
- * @memberOf _
- * @category Math
- * @param {number} augend The first number to add.
- * @param {number} addend The second number to add.
- * @returns {number} Returns the sum.
- * @example
- *
- * _.add(6, 4);
- * // => 10
- */
- function add(augend, addend) {
- return (+augend || 0) + (+addend || 0);
- }
-
- return add;
-});
diff --git a/math/max.js b/math/max.js
deleted file mode 100644
index c48911e11..000000000
--- a/math/max.js
+++ /dev/null
@@ -1,56 +0,0 @@
-define(['../internal/createExtremum', '../lang/gt'], function(createExtremum, gt) {
-
- /** Used as references for `-Infinity` and `Infinity`. */
- var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY;
-
- /**
- * Gets the maximum value of `collection`. If `collection` is empty or falsey
- * `-Infinity` is returned. If an iteratee function is provided it's invoked
- * for each value in `collection` to generate the criterion by which the value
- * is ranked. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Math
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {*} Returns the maximum value.
- * @example
- *
- * _.max([4, 2, 8, 6]);
- * // => 8
- *
- * _.max([]);
- * // => -Infinity
- *
- * var users = [
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 }
- * ];
- *
- * _.max(users, function(chr) {
- * return chr.age;
- * });
- * // => { 'user': 'fred', 'age': 40 }
- *
- * // using the `_.property` callback shorthand
- * _.max(users, 'age');
- * // => { 'user': 'fred', 'age': 40 }
- */
- var max = createExtremum(gt, NEGATIVE_INFINITY);
-
- return max;
-});
diff --git a/math/min.js b/math/min.js
deleted file mode 100644
index 9702fa1f6..000000000
--- a/math/min.js
+++ /dev/null
@@ -1,56 +0,0 @@
-define(['../internal/createExtremum', '../lang/lt'], function(createExtremum, lt) {
-
- /** Used as references for `-Infinity` and `Infinity`. */
- var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
-
- /**
- * Gets the minimum value of `collection`. If `collection` is empty or falsey
- * `Infinity` is returned. If an iteratee function is provided it's invoked
- * for each value in `collection` to generate the criterion by which the value
- * is ranked. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index, collection).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Math
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {*} Returns the minimum value.
- * @example
- *
- * _.min([4, 2, 8, 6]);
- * // => 2
- *
- * _.min([]);
- * // => Infinity
- *
- * var users = [
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 }
- * ];
- *
- * _.min(users, function(chr) {
- * return chr.age;
- * });
- * // => { 'user': 'barney', 'age': 36 }
- *
- * // using the `_.property` callback shorthand
- * _.min(users, 'age');
- * // => { 'user': 'barney', 'age': 36 }
- */
- var min = createExtremum(lt, POSITIVE_INFINITY);
-
- return min;
-});
diff --git a/math/sum.js b/math/sum.js
deleted file mode 100644
index 962ae59f9..000000000
--- a/math/sum.js
+++ /dev/null
@@ -1,49 +0,0 @@
-define(['../internal/arraySum', '../internal/baseCallback', '../internal/baseSum', '../lang/isArray', '../internal/isIterateeCall', '../internal/toIterable'], function(arraySum, baseCallback, baseSum, isArray, isIterateeCall, toIterable) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Gets the sum of the values in `collection`.
- *
- * @static
- * @memberOf _
- * @category Math
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {number} Returns the sum.
- * @example
- *
- * _.sum([4, 6]);
- * // => 10
- *
- * _.sum({ 'a': 4, 'b': 6 });
- * // => 10
- *
- * var objects = [
- * { 'n': 4 },
- * { 'n': 6 }
- * ];
- *
- * _.sum(objects, function(object) {
- * return object.n;
- * });
- * // => 10
- *
- * // using the `_.property` callback shorthand
- * _.sum(objects, 'n');
- * // => 10
- */
- function sum(collection, iteratee, thisArg) {
- if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = undefined;
- }
- iteratee = baseCallback(iteratee, thisArg, 3);
- return iteratee.length == 1
- ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee)
- : baseSum(collection, iteratee);
- }
-
- return sum;
-});
diff --git a/max.js b/max.js
new file mode 100644
index 000000000..3ef829779
--- /dev/null
+++ b/max.js
@@ -0,0 +1,30 @@
+define(['./internal/baseExtremum', './gt', './identity'], function(baseExtremum, gt, identity) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Computes the maximum value of `array`. If `array` is empty or falsey
+ * `undefined` is returned.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {*} Returns the maximum value.
+ * @example
+ *
+ * _.max([4, 2, 8, 6]);
+ * // => 8
+ *
+ * _.max([]);
+ * // => undefined
+ */
+ function max(array) {
+ return (array && array.length)
+ ? baseExtremum(array, identity, gt)
+ : undefined;
+ }
+
+ return max;
+});
diff --git a/maxBy.js b/maxBy.js
new file mode 100644
index 000000000..cff461a4f
--- /dev/null
+++ b/maxBy.js
@@ -0,0 +1,35 @@
+define(['./internal/baseExtremum', './internal/baseIteratee', './gt'], function(baseExtremum, baseIteratee, gt) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.max` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * the value is ranked. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {*} Returns the maximum value.
+ * @example
+ *
+ * var objects = [{ 'n': 1 }, { 'n': 2 }];
+ *
+ * _.maxBy(objects, function(o) { return o.a; });
+ * // => { 'n': 2 }
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.maxBy(objects, 'n');
+ * // => { 'n': 2 }
+ */
+ function maxBy(array, iteratee) {
+ return (array && array.length)
+ ? baseExtremum(array, baseIteratee(iteratee), gt)
+ : undefined;
+ }
+
+ return maxBy;
+});
diff --git a/mean.js b/mean.js
new file mode 100644
index 000000000..5ee6669b5
--- /dev/null
+++ b/mean.js
@@ -0,0 +1,21 @@
+define(['./sum'], function(sum) {
+
+ /**
+ * Computes the mean of the values in `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {number} Returns the mean.
+ * @example
+ *
+ * _.mean([4, 2, 8, 6]);
+ * // => 5
+ */
+ function mean(array) {
+ return sum(array) / (array ? array.length : 0);
+ }
+
+ return mean;
+});
diff --git a/function/memoize.js b/memoize.js
similarity index 66%
rename from function/memoize.js
rename to memoize.js
index 86ba5b03c..b82c6e01f 100644
--- a/function/memoize.js
+++ b/memoize.js
@@ -1,4 +1,4 @@
-define(['../internal/MapCache'], function(MapCache) {
+define(['./internal/MapCache'], function(MapCache) {
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -7,14 +7,13 @@ define(['../internal/MapCache'], function(MapCache) {
* Creates a function that memoizes the result of `func`. If `resolver` is
* provided it determines the cache key for storing the result based on the
* arguments provided to the memoized function. By default, the first argument
- * provided to the memoized function is coerced to a string and used as the
- * cache key. The `func` is invoked with the `this` binding of the memoized
- * function.
+ * provided to the memoized function is used as the map cache key. The `func`
+ * is invoked with the `this` binding of the memoized function.
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
* constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
- * method interface of `get`, `has`, and `set`.
+ * method interface of `delete`, `get`, `has`, and `set`.
*
* @static
* @memberOf _
@@ -24,35 +23,27 @@ define(['../internal/MapCache'], function(MapCache) {
* @returns {Function} Returns the new memoizing function.
* @example
*
- * var upperCase = _.memoize(function(string) {
- * return string.toUpperCase();
- * });
+ * var object = { 'a': 1, 'b': 2 };
+ * var other = { 'c': 3, 'd': 4 };
*
- * upperCase('fred');
- * // => 'FRED'
+ * var values = _.memoize(_.values);
+ * values(object);
+ * // => [1, 2]
+ *
+ * values(other);
+ * // => [3, 4]
+ *
+ * object.a = 2;
+ * values(object);
+ * // => [1, 2]
*
* // modifying the result cache
- * upperCase.cache.set('fred', 'BARNEY');
- * upperCase('fred');
- * // => 'BARNEY'
+ * values.cache.set(object, ['a', 'b']);
+ * values(object);
+ * // => ['a', 'b']
*
* // replacing `_.memoize.Cache`
- * var object = { 'user': 'fred' };
- * var other = { 'user': 'barney' };
- * var identity = _.memoize(_.identity);
- *
- * identity(object);
- * // => { 'user': 'fred' }
- * identity(other);
- * // => { 'user': 'fred' }
- *
* _.memoize.Cache = WeakMap;
- * var identity = _.memoize(_.identity);
- *
- * identity(object);
- * // => { 'user': 'fred' }
- * identity(other);
- * // => { 'user': 'barney' }
*/
function memoize(func, resolver) {
if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
diff --git a/merge.js b/merge.js
new file mode 100644
index 000000000..80bc6f49c
--- /dev/null
+++ b/merge.js
@@ -0,0 +1,37 @@
+define(['./internal/baseMerge', './internal/createAssigner'], function(baseMerge, createAssigner) {
+
+ /**
+ * Recursively merges own and inherited enumerable properties of source
+ * objects into the destination object, skipping source properties that resolve
+ * to `undefined`. Array and plain object properties are merged recursively.
+ * Other objects and value types are overridden by assignment. Source objects
+ * are applied from left to right. Subsequent sources overwrite property
+ * assignments of previous sources.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @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 }] }
+ */
+ var merge = createAssigner(function(object, source) {
+ baseMerge(object, source);
+ });
+
+ return merge;
+});
diff --git a/mergeWith.js b/mergeWith.js
new file mode 100644
index 000000000..2e1440cbc
--- /dev/null
+++ b/mergeWith.js
@@ -0,0 +1,43 @@
+define(['./internal/baseMerge', './internal/createAssigner'], function(baseMerge, createAssigner) {
+
+ /**
+ * This method is like `_.merge` except that it accepts `customizer` which
+ * is invoked to produce the merged values of the destination and source
+ * properties. If `customizer` returns `undefined` merging is handled by the
+ * method instead. The `customizer` is invoked with seven arguments:
+ * (objValue, srcValue, key, object, source, stack).
+ *
+ * @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.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * if (_.isArray(objValue)) {
+ * return objValue.concat(srcValue);
+ * }
+ * }
+ *
+ * var object = {
+ * 'fruits': ['apple'],
+ * 'vegetables': ['beet']
+ * };
+ *
+ * var other = {
+ * 'fruits': ['banana'],
+ * 'vegetables': ['carrot']
+ * };
+ *
+ * _.mergeWith(object, other, customizer);
+ * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
+ */
+ var mergeWith = createAssigner(function(object, source, customizer) {
+ baseMerge(object, source, customizer);
+ });
+
+ return mergeWith;
+});
diff --git a/utility/method.js b/method.js
similarity index 63%
rename from utility/method.js
rename to method.js
index 3852f175f..edefb141c 100644
--- a/utility/method.js
+++ b/method.js
@@ -1,12 +1,12 @@
-define(['../internal/invokePath', '../function/restParam'], function(invokePath, restParam) {
+define(['./internal/baseInvoke', './rest'], function(baseInvoke, rest) {
/**
- * Creates a function that invokes the method at `path` on a given object.
+ * Creates a function that invokes the method at `path` of a given object.
* Any additional arguments are provided to the invoked method.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Array|string} path The path of the method to invoke.
* @param {...*} [args] The arguments to invoke the method with.
* @returns {Function} Returns the new function.
@@ -20,12 +20,12 @@ define(['../internal/invokePath', '../function/restParam'], function(invokePath,
* _.map(objects, _.method('a.b.c'));
* // => [2, 1]
*
- * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
+ * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
* // => [1, 2]
*/
- var method = restParam(function(path, args) {
+ var method = rest(function(path, args) {
return function(object) {
- return invokePath(object, path, args);
+ return baseInvoke(object, path, args);
};
});
diff --git a/utility/methodOf.js b/methodOf.js
similarity index 70%
rename from utility/methodOf.js
rename to methodOf.js
index 0a398b3b9..5374374cf 100644
--- a/utility/methodOf.js
+++ b/methodOf.js
@@ -1,13 +1,13 @@
-define(['../internal/invokePath', '../function/restParam'], function(invokePath, restParam) {
+define(['./internal/baseInvoke', './rest'], function(baseInvoke, rest) {
/**
* The opposite of `_.method`; this method creates a function that invokes
- * the method at a given path on `object`. Any additional arguments are
+ * the method at a given path of `object`. Any additional arguments are
* provided to the invoked method.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Object} object The object to query.
* @param {...*} [args] The arguments to invoke the method with.
* @returns {Function} Returns the new function.
@@ -22,9 +22,9 @@ define(['../internal/invokePath', '../function/restParam'], function(invokePath,
* _.map([['a', '2'], ['c', '0']], _.methodOf(object));
* // => [2, 0]
*/
- var methodOf = restParam(function(object, args) {
+ var methodOf = rest(function(object, args) {
return function(path) {
- return invokePath(object, path, args);
+ return baseInvoke(object, path, args);
};
});
diff --git a/min.js b/min.js
new file mode 100644
index 000000000..f53590db6
--- /dev/null
+++ b/min.js
@@ -0,0 +1,30 @@
+define(['./internal/baseExtremum', './identity', './lt'], function(baseExtremum, identity, lt) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Computes the minimum value of `array`. If `array` is empty or falsey
+ * `undefined` is returned.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {*} Returns the minimum value.
+ * @example
+ *
+ * _.min([4, 2, 8, 6]);
+ * // => 2
+ *
+ * _.min([]);
+ * // => undefined
+ */
+ function min(array) {
+ return (array && array.length)
+ ? baseExtremum(array, identity, lt)
+ : undefined;
+ }
+
+ return min;
+});
diff --git a/minBy.js b/minBy.js
new file mode 100644
index 000000000..6f124cade
--- /dev/null
+++ b/minBy.js
@@ -0,0 +1,35 @@
+define(['./internal/baseExtremum', './internal/baseIteratee', './lt'], function(baseExtremum, baseIteratee, lt) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.min` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * the value is ranked. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {*} Returns the minimum value.
+ * @example
+ *
+ * var objects = [{ 'n': 1 }, { 'n': 2 }];
+ *
+ * _.minBy(objects, function(o) { return o.a; });
+ * // => { 'n': 1 }
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.minBy(objects, 'n');
+ * // => { 'n': 1 }
+ */
+ function minBy(array, iteratee) {
+ return (array && array.length)
+ ? baseExtremum(array, baseIteratee(iteratee), lt)
+ : undefined;
+ }
+
+ return minBy;
+});
diff --git a/mixin.js b/mixin.js
new file mode 100644
index 000000000..291e5c805
--- /dev/null
+++ b/mixin.js
@@ -0,0 +1,69 @@
+define(['./internal/arrayEach', './internal/arrayPush', './internal/baseFunctions', './internal/copyArray', './isFunction', './isObject', './keys'], function(arrayEach, arrayPush, baseFunctions, copyArray, isFunction, isObject, keys) {
+
+ /**
+ * Adds all own enumerable function properties of a source object to the
+ * destination object. If `object` is a function then methods are added to
+ * its prototype as well.
+ *
+ * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
+ * avoid conflicts caused by modifying the original.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Function|Object} [object=lodash] The destination object.
+ * @param {Object} source The object of functions to add.
+ * @param {Object} [options] The options object.
+ * @param {boolean} [options.chain=true] Specify whether the functions added
+ * are chainable.
+ * @returns {Function|Object} Returns `object`.
+ * @example
+ *
+ * function vowels(string) {
+ * return _.filter(string, function(v) {
+ * return /[aeiou]/i.test(v);
+ * });
+ * }
+ *
+ * _.mixin({ 'vowels': vowels });
+ * _.vowels('fred');
+ * // => ['e']
+ *
+ * _('fred').vowels().value();
+ * // => ['e']
+ *
+ * _.mixin({ 'vowels': vowels }, { 'chain': false });
+ * _('fred').vowels();
+ * // => ['e']
+ */
+ function mixin(object, source, options) {
+ var props = keys(source),
+ methodNames = baseFunctions(source, props);
+
+ var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
+ isFunc = isFunction(object);
+
+ arrayEach(methodNames, function(methodName) {
+ var func = source[methodName];
+ object[methodName] = func;
+ if (isFunc) {
+ object.prototype[methodName] = function() {
+ var chainAll = this.__chain__;
+ if (chain || chainAll) {
+ var result = object(this.__wrapped__),
+ actions = result.__actions__ = copyArray(this.__actions__);
+
+ actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
+ result.__chain__ = chainAll;
+ return result;
+ }
+ return func.apply(object, arrayPush([this.value()], arguments));
+ };
+ }
+ });
+
+ return object;
+ }
+
+ return mixin;
+});
diff --git a/function/negate.js b/negate.js
similarity index 100%
rename from function/negate.js
rename to negate.js
diff --git a/next.js b/next.js
new file mode 100644
index 000000000..ec30008e0
--- /dev/null
+++ b/next.js
@@ -0,0 +1,38 @@
+define(['./toArray'], function(toArray) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Gets the next value on a wrapped object following the
+ * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
+ *
+ * @name next
+ * @memberOf _
+ * @category Seq
+ * @returns {Object} Returns the next iterator value.
+ * @example
+ *
+ * var wrapped = _([1, 2]);
+ *
+ * wrapped.next();
+ * // => { 'done': false, 'value': 1 }
+ *
+ * wrapped.next();
+ * // => { 'done': false, 'value': 2 }
+ *
+ * wrapped.next();
+ * // => { 'done': true, 'value': undefined }
+ */
+ function wrapperNext() {
+ if (this.__values__ === undefined) {
+ this.__values__ = toArray(this.value());
+ }
+ var done = this.__index__ >= this.__values__.length,
+ value = done ? undefined : this.__values__[this.__index__++];
+
+ return { 'done': done, 'value': value };
+ }
+
+ return wrapperNext;
+});
diff --git a/utility/noop.js b/noop.js
similarity index 93%
rename from utility/noop.js
rename to noop.js
index 7e45039ef..66bb011b5 100644
--- a/utility/noop.js
+++ b/noop.js
@@ -6,7 +6,7 @@ define([], function() {
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @example
*
* var object = { 'user': 'fred' };
diff --git a/now.js b/now.js
new file mode 100644
index 000000000..8963f2a96
--- /dev/null
+++ b/now.js
@@ -0,0 +1,22 @@
+define([], function() {
+
+ /**
+ * Gets the timestamp of the number of milliseconds that have elapsed since
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Date
+ * @returns {number} Returns the timestamp.
+ * @example
+ *
+ * _.defer(function(stamp) {
+ * console.log(_.now() - stamp);
+ * }, _.now());
+ * // => logs the number of milliseconds it took for the deferred function to be invoked
+ */
+ var now = Date.now;
+
+ return now;
+});
diff --git a/nthArg.js b/nthArg.js
new file mode 100644
index 000000000..01b1170fc
--- /dev/null
+++ b/nthArg.js
@@ -0,0 +1,26 @@
+define(['./toInteger'], function(toInteger) {
+
+ /**
+ * Creates a function that returns its nth argument.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {number} [n=0] The index of the argument to return.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.nthArg(1);
+ *
+ * func('a', 'b', 'c');
+ * // => 'b'
+ */
+ function nthArg(n) {
+ n = toInteger(n);
+ return function() {
+ return arguments[n];
+ };
+ }
+
+ return nthArg;
+});
diff --git a/number.js b/number.js
index f7de03728..9d66be60c 100644
--- a/number.js
+++ b/number.js
@@ -1,5 +1,6 @@
-define(['./number/inRange', './number/random'], function(inRange, random) {
+define(['./clamp', './inRange', './random'], function(clamp, inRange, random) {
return {
+ 'clamp': clamp,
'inRange': inRange,
'random': random
};
diff --git a/number/random.js b/number/random.js
deleted file mode 100644
index 86dc9ed56..000000000
--- a/number/random.js
+++ /dev/null
@@ -1,73 +0,0 @@
-define(['../internal/baseRandom', '../internal/isIterateeCall'], function(baseRandom, isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeMin = Math.min,
- nativeRandom = Math.random;
-
- /**
- * Produces a random number between `min` and `max` (inclusive). If only one
- * argument is provided a number between `0` and the given number is returned.
- * If `floating` is `true`, or either `min` or `max` are floats, a floating-point
- * number is returned instead of an integer.
- *
- * @static
- * @memberOf _
- * @category Number
- * @param {number} [min=0] The minimum possible value.
- * @param {number} [max=1] The maximum possible value.
- * @param {boolean} [floating] Specify returning a floating-point number.
- * @returns {number} Returns the random number.
- * @example
- *
- * _.random(0, 5);
- * // => an integer between 0 and 5
- *
- * _.random(5);
- * // => also an integer between 0 and 5
- *
- * _.random(5, true);
- * // => a floating-point number between 0 and 5
- *
- * _.random(1.2, 5.2);
- * // => a floating-point number between 1.2 and 5.2
- */
- function random(min, max, floating) {
- if (floating && isIterateeCall(min, max, floating)) {
- max = floating = undefined;
- }
- var noMin = min == null,
- noMax = max == null;
-
- if (floating == null) {
- if (noMax && typeof min == 'boolean') {
- floating = min;
- min = 1;
- }
- else if (typeof max == 'boolean') {
- floating = max;
- noMax = true;
- }
- }
- if (noMin && noMax) {
- max = 1;
- noMax = false;
- }
- min = +min || 0;
- if (noMax) {
- max = min;
- min = 0;
- } else {
- max = +max || 0;
- }
- if (floating || min % 1 || max % 1) {
- var rand = nativeRandom();
- return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max);
- }
- return baseRandom(min, max);
- }
-
- return random;
-});
diff --git a/object.js b/object.js
index 0a4a8212a..bef7274bc 100644
--- a/object.js
+++ b/object.js
@@ -1,10 +1,12 @@
-define(['./object/assign', './object/create', './object/defaults', './object/defaultsDeep', './object/extend', './object/findKey', './object/findLastKey', './object/forIn', './object/forInRight', './object/forOwn', './object/forOwnRight', './object/functions', './object/get', './object/has', './object/invert', './object/keys', './object/keysIn', './object/mapKeys', './object/mapValues', './object/merge', './object/methods', './object/omit', './object/pairs', './object/pick', './object/result', './object/set', './object/transform', './object/values', './object/valuesIn'], function(assign, create, defaults, defaultsDeep, extend, findKey, findLastKey, forIn, forInRight, forOwn, forOwnRight, functions, get, has, invert, keys, keysIn, mapKeys, mapValues, merge, methods, omit, pairs, pick, result, set, transform, values, valuesIn) {
+define(['./assign', './assignIn', './assignInWith', './assignWith', './create', './defaults', './defaultsDeep', './findKey', './findLastKey', './forIn', './forInRight', './forOwn', './forOwnRight', './functions', './functionsIn', './get', './has', './hasIn', './invert', './invoke', './keys', './keysIn', './mapKeys', './mapValues', './merge', './mergeWith', './omit', './omitBy', './pick', './pickBy', './result', './set', './setWith', './toPairs', './toPairsIn', './transform', './unset', './values', './valuesIn'], function(assign, assignIn, assignInWith, assignWith, create, defaults, defaultsDeep, findKey, findLastKey, forIn, forInRight, forOwn, forOwnRight, functions, functionsIn, get, has, hasIn, invert, invoke, keys, keysIn, mapKeys, mapValues, merge, mergeWith, omit, omitBy, pick, pickBy, result, set, setWith, toPairs, toPairsIn, transform, unset, values, valuesIn) {
return {
'assign': assign,
+ 'assignIn': assignIn,
+ 'assignInWith': assignInWith,
+ 'assignWith': assignWith,
'create': create,
'defaults': defaults,
'defaultsDeep': defaultsDeep,
- 'extend': extend,
'findKey': findKey,
'findLastKey': findLastKey,
'forIn': forIn,
@@ -12,21 +14,29 @@ define(['./object/assign', './object/create', './object/defaults', './object/def
'forOwn': forOwn,
'forOwnRight': forOwnRight,
'functions': functions,
+ 'functionsIn': functionsIn,
'get': get,
'has': has,
+ 'hasIn': hasIn,
'invert': invert,
+ 'invoke': invoke,
'keys': keys,
'keysIn': keysIn,
'mapKeys': mapKeys,
'mapValues': mapValues,
'merge': merge,
- 'methods': methods,
+ 'mergeWith': mergeWith,
'omit': omit,
- 'pairs': pairs,
+ 'omitBy': omitBy,
'pick': pick,
+ 'pickBy': pickBy,
'result': result,
'set': set,
+ 'setWith': setWith,
+ 'toPairs': toPairs,
+ 'toPairsIn': toPairsIn,
'transform': transform,
+ 'unset': unset,
'values': values,
'valuesIn': valuesIn
};
diff --git a/object/assign.js b/object/assign.js
deleted file mode 100644
index 47a9eeae3..000000000
--- a/object/assign.js
+++ /dev/null
@@ -1,42 +0,0 @@
-define(['../internal/assignWith', '../internal/baseAssign', '../internal/createAssigner'], function(assignWith, baseAssign, createAssigner) {
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object. Subsequent sources overwrite property assignments of previous sources.
- * If `customizer` is provided it's invoked to produce the assigned values.
- * The `customizer` is bound to `thisArg` and invoked with five arguments:
- * (objectValue, sourceValue, key, object, source).
- *
- * **Note:** This method mutates `object` and is based on
- * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
- *
- * @static
- * @memberOf _
- * @alias extend
- * @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
- *
- * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
- * // => { 'user': 'fred', 'age': 40 }
- *
- * // using a customizer callback
- * var defaults = _.partialRight(_.assign, function(value, other) {
- * return _.isUndefined(value) ? other : value;
- * });
- *
- * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
- * // => { 'user': 'barney', 'age': 36 }
- */
- var assign = createAssigner(function(object, source, customizer) {
- return customizer
- ? assignWith(object, source, customizer)
- : baseAssign(object, source);
- });
-
- return assign;
-});
diff --git a/object/defaults.js b/object/defaults.js
deleted file mode 100644
index a3f52cf4e..000000000
--- a/object/defaults.js
+++ /dev/null
@@ -1,24 +0,0 @@
-define(['./assign', '../internal/assignDefaults', '../internal/createDefaults'], function(assign, assignDefaults, createDefaults) {
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object for all destination properties that resolve to `undefined`. Once a
- * property is set, additional values of the same property are ignored.
- *
- * **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
- *
- * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
- * // => { 'user': 'barney', 'age': 36 }
- */
- var defaults = createDefaults(assign, assignDefaults);
-
- return defaults;
-});
diff --git a/object/extend.js b/object/extend.js
deleted file mode 100644
index ce1d78602..000000000
--- a/object/extend.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./assign"], function(assign) {
- return assign;
-});
diff --git a/object/findKey.js b/object/findKey.js
deleted file mode 100644
index ffdfaa66f..000000000
--- a/object/findKey.js
+++ /dev/null
@@ -1,54 +0,0 @@
-define(['../internal/baseForOwn', '../internal/createFindKey'], function(baseForOwn, createFindKey) {
-
- /**
- * This method is like `_.find` except that it returns the key of the first
- * element `predicate` returns truthy for instead of the element itself.
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
- * @example
- *
- * var users = {
- * 'barney': { 'age': 36, 'active': true },
- * 'fred': { 'age': 40, 'active': false },
- * 'pebbles': { 'age': 1, 'active': true }
- * };
- *
- * _.findKey(users, function(chr) {
- * return chr.age < 40;
- * });
- * // => 'barney' (iteration order is not guaranteed)
- *
- * // using the `_.matches` callback shorthand
- * _.findKey(users, { 'age': 1, 'active': true });
- * // => 'pebbles'
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.findKey(users, 'active', false);
- * // => 'fred'
- *
- * // using the `_.property` callback shorthand
- * _.findKey(users, 'active');
- * // => 'barney'
- */
- var findKey = createFindKey(baseForOwn);
-
- return findKey;
-});
diff --git a/object/findLastKey.js b/object/findLastKey.js
deleted file mode 100644
index f42c0f4af..000000000
--- a/object/findLastKey.js
+++ /dev/null
@@ -1,54 +0,0 @@
-define(['../internal/baseForOwnRight', '../internal/createFindKey'], function(baseForOwnRight, createFindKey) {
-
- /**
- * This method is like `_.findKey` except that it iterates over elements of
- * a collection in the opposite order.
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
- * @example
- *
- * var users = {
- * 'barney': { 'age': 36, 'active': true },
- * 'fred': { 'age': 40, 'active': false },
- * 'pebbles': { 'age': 1, 'active': true }
- * };
- *
- * _.findLastKey(users, function(chr) {
- * return chr.age < 40;
- * });
- * // => returns `pebbles` assuming `_.findKey` returns `barney`
- *
- * // using the `_.matches` callback shorthand
- * _.findLastKey(users, { 'age': 36, 'active': true });
- * // => 'barney'
- *
- * // using the `_.matchesProperty` callback shorthand
- * _.findLastKey(users, 'active', false);
- * // => 'fred'
- *
- * // using the `_.property` callback shorthand
- * _.findLastKey(users, 'active');
- * // => 'pebbles'
- */
- var findLastKey = createFindKey(baseForOwnRight);
-
- return findLastKey;
-});
diff --git a/object/functions.js b/object/functions.js
deleted file mode 100644
index 35504e68f..000000000
--- a/object/functions.js
+++ /dev/null
@@ -1,23 +0,0 @@
-define(['../internal/baseFunctions', './keysIn'], function(baseFunctions, keysIn) {
-
- /**
- * Creates an array of function property names from all enumerable properties,
- * own and inherited, of `object`.
- *
- * @static
- * @memberOf _
- * @alias methods
- * @category Object
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns the new array of property names.
- * @example
- *
- * _.functions(_);
- * // => ['after', 'ary', 'assign', ...]
- */
- function functions(object) {
- return baseFunctions(object, keysIn(object));
- }
-
- return functions;
-});
diff --git a/object/has.js b/object/has.js
deleted file mode 100644
index 7884453ce..000000000
--- a/object/has.js
+++ /dev/null
@@ -1,50 +0,0 @@
-define(['../internal/baseGet', '../internal/baseSlice', '../lang/isArguments', '../lang/isArray', '../internal/isIndex', '../internal/isKey', '../internal/isLength', '../array/last', '../internal/toPath'], function(baseGet, baseSlice, isArguments, isArray, isIndex, isKey, isLength, last, toPath) {
-
- /** Used for native method references. */
- var objectProto = Object.prototype;
-
- /** Used to check objects for own properties. */
- var hasOwnProperty = objectProto.hasOwnProperty;
-
- /**
- * Checks if `path` is a direct property.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @param {Array|string} path The path to check.
- * @returns {boolean} Returns `true` if `path` is a direct property, else `false`.
- * @example
- *
- * var object = { 'a': { 'b': { 'c': 3 } } };
- *
- * _.has(object, 'a');
- * // => true
- *
- * _.has(object, 'a.b.c');
- * // => true
- *
- * _.has(object, ['a', 'b', 'c']);
- * // => true
- */
- function has(object, path) {
- if (object == null) {
- return false;
- }
- var result = hasOwnProperty.call(object, path);
- if (!result && !isKey(path)) {
- path = toPath(path);
- object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
- if (object == null) {
- return false;
- }
- path = last(path);
- result = hasOwnProperty.call(object, path);
- }
- return result || (isLength(object.length) && isIndex(path, object.length) &&
- (isArray(object) || isArguments(object)));
- }
-
- return has;
-});
diff --git a/object/keys.js b/object/keys.js
deleted file mode 100644
index 9e3f4653d..000000000
--- a/object/keys.js
+++ /dev/null
@@ -1,46 +0,0 @@
-define(['../internal/getNative', '../internal/isArrayLike', '../lang/isObject', '../internal/shimKeys'], function(getNative, isArrayLike, isObject, shimKeys) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /* Native method references for those with the same name as other `lodash` methods. */
- 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](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
- * for more details.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @returns {Array} Returns the array of property names.
- * @example
- *
- * function Foo() {
- * this.a = 1;
- * this.b = 2;
- * }
- *
- * Foo.prototype.c = 3;
- *
- * _.keys(new Foo);
- * // => ['a', 'b'] (iteration order is not guaranteed)
- *
- * _.keys('hi');
- * // => ['0', '1']
- */
- var keys = !nativeKeys ? shimKeys : function(object) {
- var Ctor = object == null ? undefined : object.constructor;
- if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
- (typeof object != 'function' && isArrayLike(object))) {
- return shimKeys(object);
- }
- return isObject(object) ? nativeKeys(object) : [];
- };
-
- return keys;
-});
diff --git a/object/mapValues.js b/object/mapValues.js
deleted file mode 100644
index ad58b5e6e..000000000
--- a/object/mapValues.js
+++ /dev/null
@@ -1,47 +0,0 @@
-define(['../internal/createObjectMapper'], function(createObjectMapper) {
-
- /**
- * Creates an object with the same keys as `object` and values generated by
- * running each own enumerable property of `object` through `iteratee`. The
- * iteratee function is bound to `thisArg` and invoked with three arguments:
- * (value, key, object).
- *
- * If a property name is provided for `iteratee` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `iteratee` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Object} Returns the new mapped object.
- * @example
- *
- * _.mapValues({ 'a': 1, 'b': 2 }, function(n) {
- * return n * 3;
- * });
- * // => { 'a': 3, 'b': 6 }
- *
- * var users = {
- * 'fred': { 'user': 'fred', 'age': 40 },
- * 'pebbles': { 'user': 'pebbles', 'age': 1 }
- * };
- *
- * // using the `_.property` callback shorthand
- * _.mapValues(users, 'age');
- * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
- */
- var mapValues = createObjectMapper();
-
- return mapValues;
-});
diff --git a/object/merge.js b/object/merge.js
deleted file mode 100644
index 76994799b..000000000
--- a/object/merge.js
+++ /dev/null
@@ -1,54 +0,0 @@
-define(['../internal/baseMerge', '../internal/createAssigner'], function(baseMerge, createAssigner) {
-
- /**
- * 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's 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);
-
- return merge;
-});
diff --git a/object/methods.js b/object/methods.js
deleted file mode 100644
index 956753358..000000000
--- a/object/methods.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./functions"], function(functions) {
- return functions;
-});
diff --git a/object/omit.js b/object/omit.js
deleted file mode 100644
index b6669c6df..000000000
--- a/object/omit.js
+++ /dev/null
@@ -1,41 +0,0 @@
-define(['../internal/arrayMap', '../internal/baseDifference', '../internal/baseFlatten', '../internal/bindCallback', './keysIn', '../internal/pickByArray', '../internal/pickByCallback', '../function/restParam'], function(arrayMap, baseDifference, baseFlatten, bindCallback, keysIn, pickByArray, pickByCallback, restParam) {
-
- /**
- * The opposite of `_.pick`; this method creates an object composed of the
- * own and inherited enumerable properties of `object` that are not omitted.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The source object.
- * @param {Function|...(string|string[])} [predicate] The function invoked per
- * iteration or property names to omit, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Object} Returns the new object.
- * @example
- *
- * var object = { 'user': 'fred', 'age': 40 };
- *
- * _.omit(object, 'age');
- * // => { 'user': 'fred' }
- *
- * _.omit(object, _.isNumber);
- * // => { 'user': 'fred' }
- */
- var omit = restParam(function(object, props) {
- if (object == null) {
- return {};
- }
- if (typeof props[0] != 'function') {
- var props = arrayMap(baseFlatten(props), String);
- return pickByArray(object, baseDifference(keysIn(object), props));
- }
- var predicate = bindCallback(props[0], props[1], 3);
- return pickByCallback(object, function(value, key, object) {
- return !predicate(value, key, object);
- });
- });
-
- return omit;
-});
diff --git a/object/pairs.js b/object/pairs.js
deleted file mode 100644
index f50463bcb..000000000
--- a/object/pairs.js
+++ /dev/null
@@ -1,33 +0,0 @@
-define(['./keys', '../internal/toObject'], function(keys, toObject) {
-
- /**
- * Creates a two dimensional array of the key-value pairs for `object`,
- * e.g. `[[key1, value1], [key2, value2]]`.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @returns {Array} Returns the new array of key-value pairs.
- * @example
- *
- * _.pairs({ 'barney': 36, 'fred': 40 });
- * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
- */
- function pairs(object) {
- object = toObject(object);
-
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- var key = props[index];
- result[index] = [key, object[key]];
- }
- return result;
- }
-
- return pairs;
-});
diff --git a/object/pick.js b/object/pick.js
deleted file mode 100644
index 651699cdf..000000000
--- a/object/pick.js
+++ /dev/null
@@ -1,39 +0,0 @@
-define(['../internal/baseFlatten', '../internal/bindCallback', '../internal/pickByArray', '../internal/pickByCallback', '../function/restParam'], function(baseFlatten, bindCallback, pickByArray, pickByCallback, restParam) {
-
- /**
- * Creates an object composed of the picked `object` properties. Property
- * names may be specified as individual arguments or as arrays of property
- * names. If `predicate` is provided it's invoked for each property of `object`
- * picking the properties `predicate` returns truthy for. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The source object.
- * @param {Function|...(string|string[])} [predicate] The function invoked per
- * iteration or property names to pick, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `predicate`.
- * @returns {Object} Returns the new object.
- * @example
- *
- * var object = { 'user': 'fred', 'age': 40 };
- *
- * _.pick(object, 'user');
- * // => { 'user': 'fred' }
- *
- * _.pick(object, _.isString);
- * // => { 'user': 'fred' }
- */
- var pick = restParam(function(object, props) {
- if (object == null) {
- return {};
- }
- return typeof props[0] == 'function'
- ? pickByCallback(object, bindCallback(props[0], props[1], 3))
- : pickByArray(object, baseFlatten(props));
- });
-
- return pick;
-});
diff --git a/object/set.js b/object/set.js
deleted file mode 100644
index 52e97c518..000000000
--- a/object/set.js
+++ /dev/null
@@ -1,53 +0,0 @@
-define(['../internal/isIndex', '../internal/isKey', '../lang/isObject', '../internal/toPath'], function(isIndex, isKey, isObject, toPath) {
-
- /**
- * Sets the property value of `path` on `object`. If a portion of `path`
- * does not exist it's created.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to augment.
- * @param {Array|string} path The path of the property to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var object = { 'a': [{ 'b': { 'c': 3 } }] };
- *
- * _.set(object, 'a[0].b.c', 4);
- * console.log(object.a[0].b.c);
- * // => 4
- *
- * _.set(object, 'x[0].y.z', 5);
- * console.log(object.x[0].y.z);
- * // => 5
- */
- function set(object, path, value) {
- if (object == null) {
- return object;
- }
- var pathKey = (path + '');
- path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path);
-
- var index = -1,
- length = path.length,
- lastIndex = length - 1,
- nested = object;
-
- while (nested != null && ++index < length) {
- var key = path[index];
- if (isObject(nested)) {
- if (index == lastIndex) {
- nested[key] = value;
- } else if (nested[key] == null) {
- nested[key] = isIndex(path[index + 1]) ? [] : {};
- }
- }
- nested = nested[key];
- }
- return object;
- }
-
- return set;
-});
diff --git a/omit.js b/omit.js
new file mode 100644
index 000000000..88bd2502d
--- /dev/null
+++ b/omit.js
@@ -0,0 +1,30 @@
+define(['./internal/arrayMap', './internal/baseDifference', './internal/baseFlatten', './internal/basePick', './keysIn', './rest'], function(arrayMap, baseDifference, baseFlatten, basePick, keysIn, rest) {
+
+ /**
+ * The opposite of `_.pick`; this method creates an object composed of the
+ * own and inherited enumerable properties of `object` that are not omitted.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [props] The property names to omit, specified
+ * individually or in arrays..
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.omit(object, ['a', 'c']);
+ * // => { 'b': '2' }
+ */
+ var omit = rest(function(object, props) {
+ if (object == null) {
+ return {};
+ }
+ props = arrayMap(baseFlatten(props), String);
+ return basePick(object, baseDifference(keysIn(object), props));
+ });
+
+ return omit;
+});
diff --git a/omitBy.js b/omitBy.js
new file mode 100644
index 000000000..268dbf3d5
--- /dev/null
+++ b/omitBy.js
@@ -0,0 +1,29 @@
+define(['./internal/baseIteratee', './internal/basePickBy'], function(baseIteratee, basePickBy) {
+
+ /**
+ * The opposite of `_.pickBy`; this method creates an object composed of the
+ * own and inherited enumerable properties of `object` that `predicate`
+ * doesn't return truthy for.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.omitBy(object, _.isNumber);
+ * // => { 'b': '2' }
+ */
+ function omitBy(object, predicate) {
+ predicate = baseIteratee(predicate);
+ return basePickBy(object, function(value) {
+ return !predicate(value);
+ });
+ }
+
+ return omitBy;
+});
diff --git a/function/once.js b/once.js
similarity index 78%
rename from function/once.js
rename to once.js
index e24008b50..abb183827 100644
--- a/function/once.js
+++ b/once.js
@@ -2,8 +2,8 @@ define(['./before'], function(before) {
/**
* Creates a function that is restricted to invoking `func` once. Repeat calls
- * to the function return the value of the first call. The `func` is invoked
- * with the `this` binding and arguments of the created function.
+ * to the function return the value of the first invocation. The `func` is
+ * invoked with the `this` binding and arguments of the created function.
*
* @static
* @memberOf _
diff --git a/orderBy.js b/orderBy.js
new file mode 100644
index 000000000..b3a2d5b0c
--- /dev/null
+++ b/orderBy.js
@@ -0,0 +1,48 @@
+define(['./internal/baseOrderBy', './isArray'], function(baseOrderBy, isArray) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.sortBy` except that it allows specifying the sort
+ * orders of the iteratees to sort by. If `orders` is unspecified, all values
+ * are sorted in ascending order. Otherwise, specify an order of "desc" for
+ * descending or "asc" for ascending sort order of corresponding values.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
+ * @param {string[]} [orders] The sort orders of `iteratees`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'fred', 'age': 48 },
+ * { 'user': 'barney', 'age': 34 },
+ * { 'user': 'fred', 'age': 42 },
+ * { 'user': 'barney', 'age': 36 }
+ * ];
+ *
+ * // sort by `user` in ascending order and by `age` in descending order
+ * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
+ */
+ function orderBy(collection, iteratees, orders, guard) {
+ if (collection == null) {
+ return [];
+ }
+ if (!isArray(iteratees)) {
+ iteratees = iteratees == null ? [] : [iteratees];
+ }
+ orders = guard ? undefined : orders;
+ if (!isArray(orders)) {
+ orders = orders == null ? [] : [orders];
+ }
+ return baseOrderBy(collection, iteratees, orders);
+ }
+
+ return orderBy;
+});
diff --git a/over.js b/over.js
new file mode 100644
index 000000000..9c8a1e29c
--- /dev/null
+++ b/over.js
@@ -0,0 +1,22 @@
+define(['./internal/arrayMap', './internal/createOver'], function(arrayMap, createOver) {
+
+ /**
+ * Creates a function that invokes `iteratees` with the arguments provided
+ * to the created function and returns their results.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} iteratees The iteratees to invoke.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.over(Math.max, Math.min);
+ *
+ * func(1, 2, 3, 4);
+ * // => [4, 1]
+ */
+ var over = createOver(arrayMap);
+
+ return over;
+});
diff --git a/overArgs.js b/overArgs.js
new file mode 100644
index 000000000..84d43b3ed
--- /dev/null
+++ b/overArgs.js
@@ -0,0 +1,53 @@
+define(['./internal/apply', './internal/arrayMap', './internal/baseFlatten', './internal/baseIteratee', './rest'], function(apply, arrayMap, baseFlatten, baseIteratee, rest) {
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMin = Math.min;
+
+ /**
+ * Creates a function that invokes `func` with arguments transformed by
+ * corresponding `transforms`.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to wrap.
+ * @param {...(Function|Function[])} [transforms] The functions to transform
+ * arguments, specified individually or in arrays.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function doubled(n) {
+ * return n * 2;
+ * }
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var func = _.overArgs(function(x, y) {
+ * return [x, y];
+ * }, square, doubled);
+ *
+ * func(9, 3);
+ * // => [81, 6]
+ *
+ * func(10, 5);
+ * // => [100, 10]
+ */
+ var overArgs = rest(function(func, transforms) {
+ transforms = arrayMap(baseFlatten(transforms), baseIteratee);
+
+ var funcsLength = transforms.length;
+ return rest(function(args) {
+ var index = -1,
+ length = nativeMin(args.length, funcsLength);
+
+ while (++index < length) {
+ args[index] = transforms[index].call(this, args[index]);
+ }
+ return apply(func, this, args);
+ });
+ });
+
+ return overArgs;
+});
diff --git a/overEvery.js b/overEvery.js
new file mode 100644
index 000000000..da5f2fa2e
--- /dev/null
+++ b/overEvery.js
@@ -0,0 +1,28 @@
+define(['./internal/arrayEvery', './internal/createOver'], function(arrayEvery, createOver) {
+
+ /**
+ * Creates a function that checks if **all** of the `predicates` return
+ * truthy when invoked with the arguments provided to the created function.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} predicates The predicates to check.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.overEvery(Boolean, isFinite);
+ *
+ * func('1');
+ * // => true
+ *
+ * func(null);
+ * // => false
+ *
+ * func(NaN);
+ * // => false
+ */
+ var overEvery = createOver(arrayEvery);
+
+ return overEvery;
+});
diff --git a/overSome.js b/overSome.js
new file mode 100644
index 000000000..54391de6d
--- /dev/null
+++ b/overSome.js
@@ -0,0 +1,28 @@
+define(['./internal/arraySome', './internal/createOver'], function(arraySome, createOver) {
+
+ /**
+ * Creates a function that checks if **any** of the `predicates` return
+ * truthy when invoked with the arguments provided to the created function.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {...(Function|Function[])} predicates The predicates to check.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var func = _.overSome(Boolean, isFinite);
+ *
+ * func('1');
+ * // => true
+ *
+ * func(null);
+ * // => true
+ *
+ * func(NaN);
+ * // => false
+ */
+ var overSome = createOver(arraySome);
+
+ return overSome;
+});
diff --git a/package.json b/package.json
index a20f18e1c..a4e5dc15a 100644
--- a/package.json
+++ b/package.json
@@ -1,15 +1,18 @@
{
- "name": "lodash",
- "version": "3.10.1",
+ "name": "lodash-amd",
+ "version": "4.0.0",
+ "description": "Lodash exported as AMD modules.",
+ "homepage": "https://lodash.com/custom-builds",
+ "license": "MIT",
"main": "main.js",
- "private": true,
- "volo": {
- "type": "directory",
- "ignore": [
- ".*",
- "*.log",
- "*.md",
- "node_modules"
- ]
- }
+ "keywords": "amd, modules, stdlib, util",
+ "author": "John-David Dalton (http://allyoucanleet.com/)",
+ "contributors": [
+ "John-David Dalton (http://allyoucanleet.com/)",
+ "Blaine Bublitz (https://github.com/phated)",
+ "Mathias Bynens (https://mathiasbynens.be/)"
+ ],
+ "bugs": "https://github.com/lodash/lodash-cli/issues",
+ "repository": "lodash/lodash",
+ "scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" }
}
diff --git a/string/pad.js b/pad.js
similarity index 60%
rename from string/pad.js
rename to pad.js
index 2c7a53f58..9fa5b7ed8 100644
--- a/string/pad.js
+++ b/pad.js
@@ -1,9 +1,8 @@
-define(['../internal/baseToString', '../internal/createPadding', '../internal/root'], function(baseToString, createPadding, root) {
+define(['./internal/createPadding', './internal/stringSize', './toInteger', './toString'], function(createPadding, stringSize, toInteger, toString) {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeCeil = Math.ceil,
- nativeFloor = Math.floor,
- nativeIsFinite = root.isFinite;
+ nativeFloor = Math.floor;
/**
* Pads `string` on the left and right sides if it's shorter than `length`.
@@ -28,19 +27,18 @@ define(['../internal/baseToString', '../internal/createPadding', '../internal/ro
* // => 'abc'
*/
function pad(string, length, chars) {
- string = baseToString(string);
- length = +length;
+ string = toString(string);
+ length = toInteger(length);
- var strLength = string.length;
- if (strLength >= length || !nativeIsFinite(length)) {
+ var strLength = stringSize(string);
+ if (!length || strLength >= length) {
return string;
}
var mid = (length - strLength) / 2,
leftLength = nativeFloor(mid),
rightLength = nativeCeil(mid);
- chars = createPadding('', rightLength, chars);
- return chars.slice(0, leftLength) + string + chars;
+ return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
}
return pad;
diff --git a/string/padRight.js b/padEnd.js
similarity index 61%
rename from string/padRight.js
rename to padEnd.js
index 0fae3e9b9..f901462dd 100644
--- a/string/padRight.js
+++ b/padEnd.js
@@ -1,4 +1,4 @@
-define(['../internal/createPadDir'], function(createPadDir) {
+define(['./internal/createPadding', './toString'], function(createPadding, toString) {
/**
* Pads `string` on the right side if it's shorter than `length`. Padding
@@ -13,16 +13,19 @@ define(['../internal/createPadDir'], function(createPadDir) {
* @returns {string} Returns the padded string.
* @example
*
- * _.padRight('abc', 6);
+ * _.padEnd('abc', 6);
* // => 'abc '
*
- * _.padRight('abc', 6, '_-');
+ * _.padEnd('abc', 6, '_-');
* // => 'abc_-_'
*
- * _.padRight('abc', 3);
+ * _.padEnd('abc', 3);
* // => 'abc'
*/
- var padRight = createPadDir(true);
+ function padEnd(string, length, chars) {
+ string = toString(string);
+ return string + createPadding(string, length, chars);
+ }
- return padRight;
+ return padEnd;
});
diff --git a/string/padLeft.js b/padStart.js
similarity index 60%
rename from string/padLeft.js
rename to padStart.js
index 55224a9a9..d3ff5f8c7 100644
--- a/string/padLeft.js
+++ b/padStart.js
@@ -1,4 +1,4 @@
-define(['../internal/createPadDir'], function(createPadDir) {
+define(['./internal/createPadding', './toString'], function(createPadding, toString) {
/**
* Pads `string` on the left side if it's shorter than `length`. Padding
@@ -13,16 +13,19 @@ define(['../internal/createPadDir'], function(createPadDir) {
* @returns {string} Returns the padded string.
* @example
*
- * _.padLeft('abc', 6);
+ * _.padStart('abc', 6);
* // => ' abc'
*
- * _.padLeft('abc', 6, '_-');
+ * _.padStart('abc', 6, '_-');
* // => '_-_abc'
*
- * _.padLeft('abc', 3);
+ * _.padStart('abc', 3);
* // => 'abc'
*/
- var padLeft = createPadDir();
+ function padStart(string, length, chars) {
+ string = toString(string);
+ return createPadding(string, length, chars) + string;
+ }
- return padLeft;
+ return padStart;
});
diff --git a/string/parseInt.js b/parseInt.js
similarity index 70%
rename from string/parseInt.js
rename to parseInt.js
index d6a8d3846..b545bc192 100644
--- a/string/parseInt.js
+++ b/parseInt.js
@@ -1,9 +1,12 @@
-define(['../internal/isIterateeCall', '../internal/root', './trim'], function(isIterateeCall, root, trim) {
+define(['./internal/root', './toString'], function(root, toString) {
+
+ /** Used to match leading and trailing whitespace. */
+ var reTrim = /^\s+|\s+$/g;
/** Used to detect hexadecimal string values. */
- var reHasHexPrefix = /^0[xX]/;
+ var reHasHexPrefix = /^0x/i;
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeParseInt = root.parseInt;
/**
@@ -19,7 +22,7 @@ define(['../internal/isIterateeCall', '../internal/root', './trim'], function(is
* @category String
* @param {string} string The string to convert.
* @param {number} [radix] The radix to interpret `value` by.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {number} Returns the converted integer.
* @example
*
@@ -30,15 +33,14 @@ define(['../internal/isIterateeCall', '../internal/root', './trim'], function(is
* // => [6, 8, 10]
*/
function parseInt(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) {
+ if (guard || radix == null) {
radix = 0;
} else if (radix) {
radix = +radix;
}
- string = trim(string);
+ string = toString(string).replace(reTrim, '');
return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
}
diff --git a/function/partial.js b/partial.js
similarity index 69%
rename from function/partial.js
rename to partial.js
index de58dbf1e..f99cc68d4 100644
--- a/function/partial.js
+++ b/partial.js
@@ -1,4 +1,7 @@
-define(['../internal/createPartial'], function(createPartial) {
+define(['./internal/createWrapper', './internal/replaceHolders', './rest'], function(createWrapper, replaceHolders, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/** Used to compose bitmasks for wrapper metadata. */
var PARTIAL_FLAG = 32;
@@ -11,7 +14,7 @@ define(['../internal/createPartial'], function(createPartial) {
* The `_.partial.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
- * **Note:** This method does not set the "length" property of partially
+ * **Note:** This method doesn't set the "length" property of partially
* applied functions.
*
* @static
@@ -35,10 +38,10 @@ define(['../internal/createPartial'], function(createPartial) {
* greetFred('hi');
* // => 'hi fred'
*/
- var partial = createPartial(PARTIAL_FLAG);
-
- // Assign default placeholders.
- partial.placeholder = {};
+ var partial = rest(function(func, partials) {
+ var holders = replaceHolders(partials, partial.placeholder);
+ return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
+ });
return partial;
});
diff --git a/function/partialRight.js b/partialRight.js
similarity index 68%
rename from function/partialRight.js
rename to partialRight.js
index e6713e176..4104256dc 100644
--- a/function/partialRight.js
+++ b/partialRight.js
@@ -1,4 +1,7 @@
-define(['../internal/createPartial'], function(createPartial) {
+define(['./internal/createWrapper', './internal/replaceHolders', './rest'], function(createWrapper, replaceHolders, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/** Used to compose bitmasks for wrapper metadata. */
var PARTIAL_RIGHT_FLAG = 64;
@@ -10,7 +13,7 @@ define(['../internal/createPartial'], function(createPartial) {
* The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
- * **Note:** This method does not set the "length" property of partially
+ * **Note:** This method doesn't set the "length" property of partially
* applied functions.
*
* @static
@@ -34,10 +37,10 @@ define(['../internal/createPartial'], function(createPartial) {
* sayHelloTo('fred');
* // => 'hello fred'
*/
- var partialRight = createPartial(PARTIAL_RIGHT_FLAG);
-
- // Assign default placeholders.
- partialRight.placeholder = {};
+ var partialRight = rest(function(func, partials) {
+ var holders = replaceHolders(partials, partialRight.placeholder);
+ return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
+ });
return partialRight;
});
diff --git a/partition.js b/partition.js
new file mode 100644
index 000000000..72ba9bbf8
--- /dev/null
+++ b/partition.js
@@ -0,0 +1,43 @@
+define(['./internal/createAggregator'], function(createAggregator) {
+
+ /**
+ * Creates an array of elements split into two groups, the first of which
+ * contains elements `predicate` returns truthy for, while the second of which
+ * contains elements `predicate` returns falsey for. The predicate is invoked
+ * with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the array of grouped elements.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': false },
+ * { 'user': 'fred', 'age': 40, 'active': true },
+ * { 'user': 'pebbles', 'age': 1, 'active': false }
+ * ];
+ *
+ * _.partition(users, function(o) { return o.active; });
+ * // => objects for [['fred'], ['barney', 'pebbles']]
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.partition(users, { 'age': 1, 'active': false });
+ * // => objects for [['pebbles'], ['barney', 'fred']]
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.partition(users, ['active', false]);
+ * // => objects for [['barney', 'pebbles'], ['fred']]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.partition(users, 'active');
+ * // => objects for [['fred'], ['barney', 'pebbles']]
+ */
+ var partition = createAggregator(function(result, value, key) {
+ result[key ? 0 : 1].push(value);
+ }, function() { return [[], []]; });
+
+ return partition;
+});
diff --git a/pick.js b/pick.js
new file mode 100644
index 000000000..d938ccd6f
--- /dev/null
+++ b/pick.js
@@ -0,0 +1,25 @@
+define(['./internal/baseFlatten', './internal/basePick', './rest'], function(baseFlatten, basePick, rest) {
+
+ /**
+ * Creates an object composed of the picked `object` properties.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [props] The property names to pick, specified
+ * individually or in arrays.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pick(object, ['a', 'c']);
+ * // => { 'a': 1, 'c': 3 }
+ */
+ var pick = rest(function(object, props) {
+ return object == null ? {} : basePick(object, baseFlatten(props));
+ });
+
+ return pick;
+});
diff --git a/pickBy.js b/pickBy.js
new file mode 100644
index 000000000..7db42ca8f
--- /dev/null
+++ b/pickBy.js
@@ -0,0 +1,25 @@
+define(['./internal/baseIteratee', './internal/basePickBy'], function(baseIteratee, basePickBy) {
+
+ /**
+ * Creates an object composed of the `object` properties `predicate` returns
+ * truthy for. The predicate is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pickBy(object, _.isNumber);
+ * // => { 'a': 1, 'c': 3 }
+ */
+ function pickBy(object, predicate) {
+ return object == null ? {} : basePickBy(object, baseIteratee(predicate));
+ }
+
+ return pickBy;
+});
diff --git a/chain/wrapperPlant.js b/plant.js
similarity index 60%
rename from chain/wrapperPlant.js
rename to plant.js
index d30ebb627..39143bf7d 100644
--- a/chain/wrapperPlant.js
+++ b/plant.js
@@ -1,23 +1,26 @@
-define(['../internal/baseLodash', '../internal/wrapperClone'], function(baseLodash, wrapperClone) {
+define(['./internal/baseLodash', './internal/wrapperClone'], function(baseLodash, wrapperClone) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* Creates a clone of the chained sequence planting `value` as the wrapped value.
*
* @name plant
* @memberOf _
- * @category Chain
+ * @category Seq
+ * @param {*} value The value to plant.
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
- * var array = [1, 2];
- * var wrapped = _(array).map(function(value) {
- * return Math.pow(value, 2);
- * });
+ * function square(n) {
+ * return n * n;
+ * }
*
- * var other = [3, 4];
- * var otherWrapped = wrapped.plant(other);
+ * var wrapped = _([1, 2]).map(square);
+ * var other = wrapped.plant([3, 4]);
*
- * otherWrapped.value();
+ * other.value();
* // => [9, 16]
*
* wrapped.value();
@@ -29,6 +32,8 @@ define(['../internal/baseLodash', '../internal/wrapperClone'], function(baseLoda
while (parent instanceof baseLodash) {
var clone = wrapperClone(parent);
+ clone.__index__ = 0;
+ clone.__values__ = undefined;
if (result) {
previous.__wrapped__ = clone;
} else {
diff --git a/utility/property.js b/property.js
similarity index 60%
rename from utility/property.js
rename to property.js
index f3539d3cf..9f5059508 100644
--- a/utility/property.js
+++ b/property.js
@@ -1,12 +1,11 @@
-define(['../internal/baseProperty', '../internal/basePropertyDeep', '../internal/isKey'], function(baseProperty, basePropertyDeep, isKey) {
+define(['./internal/baseProperty', './internal/basePropertyDeep', './internal/isKey'], function(baseProperty, basePropertyDeep, isKey) {
/**
- * Creates a function that returns the property value at `path` on a
- * given object.
+ * Creates a function that returns the value at `path` of a given object.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Array|string} path The path of the property to get.
* @returns {Function} Returns the new function.
* @example
@@ -19,7 +18,7 @@ define(['../internal/baseProperty', '../internal/basePropertyDeep', '../internal
* _.map(objects, _.property('a.b.c'));
* // => [2, 1]
*
- * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
+ * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
* // => [1, 2]
*/
function property(path) {
diff --git a/utility/propertyOf.js b/propertyOf.js
similarity index 68%
rename from utility/propertyOf.js
rename to propertyOf.js
index 65bf49bc5..427767cfc 100644
--- a/utility/propertyOf.js
+++ b/propertyOf.js
@@ -1,12 +1,15 @@
-define(['../internal/baseGet', '../internal/toPath'], function(baseGet, toPath) {
+define(['./internal/baseGet'], function(baseGet) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* The opposite of `_.property`; this method creates a function that returns
- * the property value at a given path on `object`.
+ * the value at a given path of `object`.
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Object} object The object to query.
* @returns {Function} Returns the new function.
* @example
@@ -22,7 +25,7 @@ define(['../internal/baseGet', '../internal/toPath'], function(baseGet, toPath)
*/
function propertyOf(object) {
return function(path) {
- return baseGet(object, toPath(path), (path + ''));
+ return object == null ? undefined : baseGet(object, path);
};
}
diff --git a/pull.js b/pull.js
new file mode 100644
index 000000000..9af99b733
--- /dev/null
+++ b/pull.js
@@ -0,0 +1,27 @@
+define(['./pullAll', './rest'], function(pullAll, rest) {
+
+ /**
+ * Removes all provided values from `array` using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * **Note:** Unlike `_.without`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {...*} [values] The values to remove.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [1, 2, 3, 1, 2, 3];
+ *
+ * _.pull(array, 2, 3);
+ * console.log(array);
+ * // => [1, 1]
+ */
+ var pull = rest(pullAll);
+
+ return pull;
+});
diff --git a/pullAll.js b/pullAll.js
new file mode 100644
index 000000000..b4c6fbf9b
--- /dev/null
+++ b/pullAll.js
@@ -0,0 +1,29 @@
+define(['./internal/basePullAll'], function(basePullAll) {
+
+ /**
+ * This method is like `_.pull` except that it accepts an array of values to remove.
+ *
+ * **Note:** Unlike `_.difference`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [1, 2, 3, 1, 2, 3];
+ *
+ * _.pull(array, [2, 3]);
+ * console.log(array);
+ * // => [1, 1]
+ */
+ function pullAll(array, values) {
+ return (array && array.length && values && values.length)
+ ? basePullAll(array, values)
+ : array;
+ }
+
+ return pullAll;
+});
diff --git a/pullAllBy.js b/pullAllBy.js
new file mode 100644
index 000000000..f93b50812
--- /dev/null
+++ b/pullAllBy.js
@@ -0,0 +1,32 @@
+define(['./internal/baseIteratee', './internal/basePullAllBy'], function(baseIteratee, basePullAllBy) {
+
+ /**
+ * This method is like `_.pullAll` except that it accepts `iteratee` which is
+ * invoked for each element of `array` and `values` to to generate the criterion
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
+ *
+ * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
+ * console.log(array);
+ * // => [{ 'x': 2 }]
+ */
+ function pullAllBy(array, values, iteratee) {
+ return (array && array.length && values && values.length)
+ ? basePullAllBy(array, values, baseIteratee(iteratee))
+ : array;
+ }
+
+ return pullAllBy;
+});
diff --git a/pullAt.js b/pullAt.js
new file mode 100644
index 000000000..438a2efef
--- /dev/null
+++ b/pullAt.js
@@ -0,0 +1,36 @@
+define(['./internal/arrayMap', './internal/baseAt', './internal/baseFlatten', './internal/basePullAt', './internal/compareAscending', './rest'], function(arrayMap, baseAt, baseFlatten, basePullAt, compareAscending, rest) {
+
+ /**
+ * Removes elements from `array` corresponding to `indexes` and returns an
+ * array of removed elements.
+ *
+ * **Note:** Unlike `_.at`, this method mutates `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to modify.
+ * @param {...(number|number[])} [indexes] The indexes of elements to remove,
+ * specified individually or in arrays.
+ * @returns {Array} Returns the new array of removed elements.
+ * @example
+ *
+ * var array = [5, 10, 15, 20];
+ * var evens = _.pullAt(array, 1, 3);
+ *
+ * console.log(array);
+ * // => [5, 15]
+ *
+ * console.log(evens);
+ * // => [10, 20]
+ */
+ var pullAt = rest(function(array, indexes) {
+ indexes = arrayMap(baseFlatten(indexes), String);
+
+ var result = baseAt(array, indexes);
+ basePullAt(array, indexes.sort(compareAscending));
+ return result;
+ });
+
+ return pullAt;
+});
diff --git a/random.js b/random.js
new file mode 100644
index 000000000..23106a732
--- /dev/null
+++ b/random.js
@@ -0,0 +1,83 @@
+define(['./internal/baseRandom', './internal/isIterateeCall', './toNumber'], function(baseRandom, isIterateeCall, toNumber) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Built-in method references without a dependency on `root`. */
+ var freeParseFloat = parseFloat;
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMin = Math.min,
+ nativeRandom = Math.random;
+
+ /**
+ * Produces a random number between the inclusive `lower` and `upper` bounds.
+ * If only one argument is provided a number between `0` and the given number
+ * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
+ * a floating-point number is returned instead of an integer.
+ *
+ * **Note:** JavaScript follows the IEEE-754 standard for resolving
+ * floating-point values which can produce unexpected results.
+ *
+ * @static
+ * @memberOf _
+ * @category Number
+ * @param {number} [lower=0] The lower bound.
+ * @param {number} [upper=1] The upper bound.
+ * @param {boolean} [floating] Specify returning a floating-point number.
+ * @returns {number} Returns the random number.
+ * @example
+ *
+ * _.random(0, 5);
+ * // => an integer between 0 and 5
+ *
+ * _.random(5);
+ * // => also an integer between 0 and 5
+ *
+ * _.random(5, true);
+ * // => a floating-point number between 0 and 5
+ *
+ * _.random(1.2, 5.2);
+ * // => a floating-point number between 1.2 and 5.2
+ */
+ function random(lower, upper, floating) {
+ if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
+ upper = floating = undefined;
+ }
+ if (floating === undefined) {
+ if (typeof upper == 'boolean') {
+ floating = upper;
+ upper = undefined;
+ }
+ else if (typeof lower == 'boolean') {
+ floating = lower;
+ lower = undefined;
+ }
+ }
+ if (lower === undefined && upper === undefined) {
+ lower = 0;
+ upper = 1;
+ }
+ else {
+ lower = toNumber(lower) || 0;
+ if (upper === undefined) {
+ upper = lower;
+ lower = 0;
+ } else {
+ upper = toNumber(upper) || 0;
+ }
+ }
+ if (lower > upper) {
+ var temp = lower;
+ lower = upper;
+ upper = temp;
+ }
+ if (floating || lower % 1 || upper % 1) {
+ var rand = nativeRandom();
+ return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
+ }
+ return baseRandom(lower, upper);
+ }
+
+ return random;
+});
diff --git a/range.js b/range.js
new file mode 100644
index 000000000..6b55a1bfa
--- /dev/null
+++ b/range.js
@@ -0,0 +1,46 @@
+define(['./internal/createRange'], function(createRange) {
+
+ /**
+ * Creates an array of numbers (positive and/or negative) progressing from
+ * `start` up to, but not including, `end`. A step of `-1` is used if a negative
+ * `start` is specified without an `end` or `step`. If `end` is not specified
+ * it's set to `start` with `start` then set to `0`. If `end` is less than
+ * `start` a zero-length range is created unless a negative `step` is specified.
+ *
+ * **Note:** JavaScript follows the IEEE-754 standard for resolving
+ * floating-point values which can produce unexpected results.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {number} [start=0] The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} [step=1] The value to increment or decrement by.
+ * @returns {Array} Returns the new array of numbers.
+ * @example
+ *
+ * _.range(4);
+ * // => [0, 1, 2, 3]
+ *
+ * _.range(-4);
+ * // => [0, -1, -2, -3]
+ *
+ * _.range(1, 5);
+ * // => [1, 2, 3, 4]
+ *
+ * _.range(0, 20, 5);
+ * // => [0, 5, 10, 15]
+ *
+ * _.range(0, -4, -1);
+ * // => [0, -1, -2, -3]
+ *
+ * _.range(1, 4, 0);
+ * // => [1, 1, 1]
+ *
+ * _.range(0);
+ * // => []
+ */
+ var range = createRange();
+
+ return range;
+});
diff --git a/rangeRight.js b/rangeRight.js
new file mode 100644
index 000000000..8a2f997e6
--- /dev/null
+++ b/rangeRight.js
@@ -0,0 +1,40 @@
+define(['./internal/createRange'], function(createRange) {
+
+ /**
+ * This method is like `_.range` except that it populates values in
+ * descending order.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {number} [start=0] The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} [step=1] The value to increment or decrement by.
+ * @returns {Array} Returns the new array of numbers.
+ * @example
+ *
+ * _.rangeRight(4);
+ * // => [3, 2, 1, 0]
+ *
+ * _.rangeRight(-4);
+ * // => [-3, -2, -1, 0]
+ *
+ * _.rangeRight(1, 5);
+ * // => [4, 3, 2, 1]
+ *
+ * _.rangeRight(0, 20, 5);
+ * // => [15, 10, 5, 0]
+ *
+ * _.rangeRight(0, -4, -1);
+ * // => [-3, -2, -1, 0]
+ *
+ * _.rangeRight(1, 4, 0);
+ * // => [1, 1, 1]
+ *
+ * _.rangeRight(0);
+ * // => []
+ */
+ var rangeRight = createRange(true);
+
+ return rangeRight;
+});
diff --git a/function/rearg.js b/rearg.js
similarity index 73%
rename from function/rearg.js
rename to rearg.js
index 356077426..095cf347b 100644
--- a/function/rearg.js
+++ b/rearg.js
@@ -1,4 +1,4 @@
-define(['../internal/baseFlatten', '../internal/createWrapper', './restParam'], function(baseFlatten, createWrapper, restParam) {
+define(['./internal/baseFlatten', './internal/createWrapper', './rest'], function(baseFlatten, createWrapper, rest) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -17,7 +17,7 @@ define(['../internal/baseFlatten', '../internal/createWrapper', './restParam'],
* @category Function
* @param {Function} func The function to rearrange arguments for.
* @param {...(number|number[])} indexes The arranged argument indexes,
- * specified as individual indexes or arrays of indexes.
+ * specified individually or in arrays.
* @returns {Function} Returns the new function.
* @example
*
@@ -27,14 +27,8 @@ define(['../internal/baseFlatten', '../internal/createWrapper', './restParam'],
*
* rearged('b', 'c', 'a')
* // => ['a', 'b', 'c']
- *
- * var map = _.rearg(_.map, [1, 0]);
- * map(function(n) {
- * return n * 3;
- * }, [1, 2, 3]);
- * // => [3, 6, 9]
*/
- var rearg = restParam(function(func, indexes) {
+ var rearg = rest(function(func, indexes) {
return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
});
diff --git a/collection/reduce.js b/reduce.js
similarity index 51%
rename from collection/reduce.js
rename to reduce.js
index 78010130e..3bd09e303 100644
--- a/collection/reduce.js
+++ b/reduce.js
@@ -1,43 +1,46 @@
-define(['../internal/arrayReduce', '../internal/baseEach', '../internal/createReduce'], function(arrayReduce, baseEach, createReduce) {
+define(['./internal/arrayReduce', './internal/baseEach', './internal/baseIteratee', './internal/baseReduce', './isArray'], function(arrayReduce, baseEach, baseIteratee, baseReduce, isArray) {
/**
* Reduces `collection` to a value which is the accumulated result of running
* each element in `collection` through `iteratee`, where each successive
* invocation is supplied the return value of the previous. If `accumulator`
* is not provided the first element of `collection` is used as the initial
- * value. The `iteratee` is bound to `thisArg` and invoked with four arguments:
+ * value. The iteratee is invoked with four arguments:
* (accumulator, value, index|key, collection).
*
* Many lodash methods are guarded to work as iteratees for methods like
* `_.reduce`, `_.reduceRight`, and `_.transform`.
*
* The guarded methods are:
- * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`,
- * and `sortByOrder`
+ * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
+ * and `sortBy`
*
* @static
* @memberOf _
- * @alias foldl, inject
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {*} Returns the accumulated value.
* @example
*
- * _.reduce([1, 2], function(total, n) {
- * return total + n;
+ * _.reduce([1, 2], function(sum, n) {
+ * return sum + n;
* });
* // => 3
*
- * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) {
- * result[key] = n * 3;
+ * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
* return result;
* }, {});
- * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)
+ * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
*/
- var reduce = createReduce(arrayReduce, baseEach);
+ function reduce(collection, iteratee, accumulator) {
+ var func = isArray(collection) ? arrayReduce : baseReduce,
+ initFromCollection = arguments.length < 3;
+
+ return func(collection, baseIteratee(iteratee, 4), accumulator, initFromCollection, baseEach);
+ }
return reduce;
});
diff --git a/collection/reduceRight.js b/reduceRight.js
similarity index 51%
rename from collection/reduceRight.js
rename to reduceRight.js
index 9d695af5c..e93d5b609 100644
--- a/collection/reduceRight.js
+++ b/reduceRight.js
@@ -1,4 +1,4 @@
-define(['../internal/arrayReduceRight', '../internal/baseEachRight', '../internal/createReduce'], function(arrayReduceRight, baseEachRight, createReduce) {
+define(['./internal/arrayReduceRight', './internal/baseEachRight', './internal/baseIteratee', './internal/baseReduce', './isArray'], function(arrayReduceRight, baseEachRight, baseIteratee, baseReduce, isArray) {
/**
* This method is like `_.reduce` except that it iterates over elements of
@@ -6,12 +6,10 @@ define(['../internal/arrayReduceRight', '../internal/baseEachRight', '../interna
*
* @static
* @memberOf _
- * @alias foldr
* @category Collection
- * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {*} Returns the accumulated value.
* @example
*
@@ -22,7 +20,12 @@ define(['../internal/arrayReduceRight', '../internal/baseEachRight', '../interna
* }, []);
* // => [4, 5, 2, 3, 0, 1]
*/
- var reduceRight = createReduce(arrayReduceRight, baseEachRight);
+ function reduceRight(collection, iteratee, accumulator) {
+ var func = isArray(collection) ? arrayReduceRight : baseReduce,
+ initFromCollection = arguments.length < 3;
+
+ return func(collection, baseIteratee(iteratee, 4), accumulator, initFromCollection, baseEachRight);
+ }
return reduceRight;
});
diff --git a/reject.js b/reject.js
new file mode 100644
index 000000000..c73cea099
--- /dev/null
+++ b/reject.js
@@ -0,0 +1,44 @@
+define(['./internal/arrayFilter', './internal/baseFilter', './internal/baseIteratee', './isArray'], function(arrayFilter, baseFilter, baseIteratee, isArray) {
+
+ /**
+ * The opposite of `_.filter`; this method returns the elements of `collection`
+ * that `predicate` does **not** return truthy for.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': false },
+ * { 'user': 'fred', 'age': 40, 'active': true }
+ * ];
+ *
+ * _.reject(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.reject(users, { 'age': 40, 'active': true });
+ * // => objects for ['barney']
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.reject(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.reject(users, 'active');
+ * // => objects for ['barney']
+ */
+ function reject(collection, predicate) {
+ var func = isArray(collection) ? arrayFilter : baseFilter;
+ predicate = baseIteratee(predicate, 3);
+ return func(collection, function(value, index, collection) {
+ return !predicate(value, index, collection);
+ });
+ }
+
+ return reject;
+});
diff --git a/array/remove.js b/remove.js
similarity index 54%
rename from array/remove.js
rename to remove.js
index 2c9e39e07..71d0d725b 100644
--- a/array/remove.js
+++ b/remove.js
@@ -1,20 +1,9 @@
-define(['../internal/baseCallback', '../internal/basePullAt'], function(baseCallback, basePullAt) {
+define(['./internal/baseIteratee', './internal/basePullAt'], function(baseIteratee, basePullAt) {
/**
* Removes all elements from `array` that `predicate` returns truthy for
- * and returns an array of the removed elements. The predicate is bound to
- * `thisArg` and invoked with three arguments: (value, index, array).
- *
- * If a property name is provided for `predicate` the created `_.property`
- * style callback returns the property value of the given element.
- *
- * If a value is also provided for `thisArg` the created `_.matchesProperty`
- * style callback returns `true` for elements that have a matching property
- * value, else `false`.
- *
- * If an object is provided for `predicate` the created `_.matches` style
- * callback returns `true` for elements that have the properties of the given
- * object, else `false`.
+ * and returns an array of the removed elements. The predicate is invoked with
+ * three arguments: (value, index, array).
*
* **Note:** Unlike `_.filter`, this method mutates `array`.
*
@@ -22,9 +11,7 @@ define(['../internal/baseCallback', '../internal/basePullAt'], function(baseCall
* @memberOf _
* @category Array
* @param {Array} array The array to modify.
- * @param {Function|Object|string} [predicate=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new array of removed elements.
* @example
*
@@ -39,7 +26,7 @@ define(['../internal/baseCallback', '../internal/basePullAt'], function(baseCall
* console.log(evens);
* // => [2, 4]
*/
- function remove(array, predicate, thisArg) {
+ function remove(array, predicate) {
var result = [];
if (!(array && array.length)) {
return result;
@@ -48,7 +35,7 @@ define(['../internal/baseCallback', '../internal/basePullAt'], function(baseCall
indexes = [],
length = array.length;
- predicate = baseCallback(predicate, thisArg, 3);
+ predicate = baseIteratee(predicate, 3);
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
diff --git a/string/repeat.js b/repeat.js
similarity index 68%
rename from string/repeat.js
rename to repeat.js
index 8b9f0defb..c780e7c66 100644
--- a/string/repeat.js
+++ b/repeat.js
@@ -1,8 +1,10 @@
-define(['../internal/baseToString', '../internal/root'], function(baseToString, root) {
+define(['./toInteger', './toString'], function(toInteger, toString) {
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeFloor = Math.floor,
- nativeIsFinite = root.isFinite;
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER = 9007199254740991;
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeFloor = Math.floor;
/**
* Repeats the given string `n` times.
@@ -25,10 +27,11 @@ define(['../internal/baseToString', '../internal/root'], function(baseToString,
* // => ''
*/
function repeat(string, n) {
+ string = toString(string);
+ n = toInteger(n);
+
var result = '';
- string = baseToString(string);
- n = +n;
- if (n < 1 || !string || !nativeIsFinite(n)) {
+ if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
return result;
}
// Leverage the exponentiation by squaring algorithm for a faster repeat.
diff --git a/replace.js b/replace.js
new file mode 100644
index 000000000..c93751fe7
--- /dev/null
+++ b/replace.js
@@ -0,0 +1,28 @@
+define(['./toString'], function(toString) {
+
+ /**
+ * Replaces matches for `pattern` in `string` with `replacement`.
+ *
+ * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to modify.
+ * @param {RegExp|string} pattern The pattern to replace.
+ * @param {Function|string} replacement The match replacement.
+ * @returns {string} Returns the modified string.
+ * @example
+ *
+ * _.replace('Hi Fred', 'Fred', 'Barney');
+ * // => 'Hi Barney'
+ */
+ function replace() {
+ var args = arguments,
+ string = toString(args[0]);
+
+ return args.length < 3 ? string : string.replace(args[1], args[2]);
+ }
+
+ return replace;
+});
diff --git a/function/restParam.js b/rest.js
similarity index 70%
rename from function/restParam.js
rename to rest.js
index 53bb815fb..ddfd68e42 100644
--- a/function/restParam.js
+++ b/rest.js
@@ -1,4 +1,4 @@
-define([], function() {
+define(['./internal/apply', './toInteger'], function(apply, toInteger) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -6,14 +6,14 @@ define([], function() {
/** 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. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Creates a function that invokes `func` with the `this` binding of the
* created function and arguments from `start` and beyond provided as an array.
*
- * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
+ * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
*
* @static
* @memberOf _
@@ -23,7 +23,7 @@ define([], function() {
* @returns {Function} Returns the new function.
* @example
*
- * var say = _.restParam(function(what, names) {
+ * var say = _.rest(function(what, names) {
* return what + ' ' + _.initial(names).join(', ') +
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
* });
@@ -31,34 +31,34 @@ define([], function() {
* say('hello', 'fred', 'barney', 'pebbles');
* // => 'hello fred, barney, & pebbles'
*/
- function restParam(func, start) {
+ function rest(func, start) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
+ start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
- rest = Array(length);
+ array = Array(length);
while (++index < length) {
- rest[index] = args[start + index];
+ array[index] = args[start + index];
}
switch (start) {
- case 0: return func.call(this, rest);
- case 1: return func.call(this, args[0], rest);
- case 2: return func.call(this, args[0], args[1], rest);
+ case 0: return func.call(this, array);
+ case 1: return func.call(this, args[0], array);
+ case 2: return func.call(this, args[0], args[1], array);
}
var otherArgs = Array(start + 1);
index = -1;
while (++index < start) {
otherArgs[index] = args[index];
}
- otherArgs[start] = rest;
- return func.apply(this, otherArgs);
+ otherArgs[start] = array;
+ return apply(func, this, otherArgs);
};
}
- return restParam;
+ return rest;
});
diff --git a/object/result.js b/result.js
similarity index 60%
rename from object/result.js
rename to result.js
index 6553acbd5..78538688e 100644
--- a/object/result.js
+++ b/result.js
@@ -1,4 +1,4 @@
-define(['../internal/baseGet', '../internal/baseSlice', '../lang/isFunction', '../internal/isKey', '../array/last', '../internal/toPath'], function(baseGet, baseSlice, isFunction, isKey, last, toPath) {
+define(['./internal/baseToPath', './get', './isFunction', './internal/isKey', './internal/parent'], function(baseToPath, get, isFunction, isKey, parent) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -25,21 +25,22 @@ define(['../internal/baseGet', '../internal/baseSlice', '../lang/isFunction', '.
* _.result(object, 'a[0].b.c2');
* // => 4
*
- * _.result(object, 'a.b.c', 'default');
+ * _.result(object, 'a[0].b.c3', 'default');
* // => 'default'
*
- * _.result(object, 'a.b.c', _.constant('default'));
+ * _.result(object, 'a[0].b.c3', _.constant('default'));
* // => 'default'
*/
function result(object, path, defaultValue) {
- var result = object == null ? undefined : object[path];
+ if (!isKey(path, object)) {
+ path = baseToPath(path);
+ var result = get(object, path);
+ object = parent(object, path);
+ } else {
+ result = object == null ? undefined : object[path];
+ }
if (result === undefined) {
- if (object != null && !isKey(path, object)) {
- path = toPath(path);
- object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
- result = object == null ? undefined : object[last(path)];
- }
- result = result === undefined ? defaultValue : result;
+ result = defaultValue;
}
return isFunction(result) ? result.call(object) : result;
}
diff --git a/reverse.js b/reverse.js
new file mode 100644
index 000000000..0bc531a86
--- /dev/null
+++ b/reverse.js
@@ -0,0 +1,34 @@
+define([], function() {
+
+ /** Used for built-in method references. */
+ var arrayProto = Array.prototype;
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeReverse = arrayProto.reverse;
+
+ /**
+ * Reverses `array` so that the first element becomes the last, the second
+ * element becomes the second to last, and so on.
+ *
+ * **Note:** This method mutates `array` and is based on
+ * [`Array#reverse`](https://mdn.io/Array/reverse).
+ *
+ * @memberOf _
+ * @category Array
+ * @returns {Array} Returns `array`.
+ * @example
+ *
+ * var array = [1, 2, 3];
+ *
+ * _.reverse(array);
+ * // => [3, 2, 1]
+ *
+ * console.log(array);
+ * // => [3, 2, 1]
+ */
+ function reverse(array) {
+ return array ? nativeReverse.call(array) : array;
+ }
+
+ return reverse;
+});
diff --git a/math/round.js b/round.js
similarity index 71%
rename from math/round.js
rename to round.js
index 32cf6479f..a26fb48e3 100644
--- a/math/round.js
+++ b/round.js
@@ -1,12 +1,12 @@
-define(['../internal/createRound'], function(createRound) {
+define(['./internal/createRound'], function(createRound) {
/**
- * Calculates `n` rounded to `precision`.
+ * Computes `number` rounded to `precision`.
*
* @static
* @memberOf _
* @category Math
- * @param {number} n The number to round.
+ * @param {number} number The number to round.
* @param {number} [precision=0] The precision to round to.
* @returns {number} Returns the rounded number.
* @example
diff --git a/sample.js b/sample.js
new file mode 100644
index 000000000..e60de5dc9
--- /dev/null
+++ b/sample.js
@@ -0,0 +1,27 @@
+define(['./internal/baseRandom', './isArrayLike', './values'], function(baseRandom, isArrayLike, values) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Gets a random element from `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to sample.
+ * @returns {*} Returns the random element.
+ * @example
+ *
+ * _.sample([1, 2, 3, 4]);
+ * // => 2
+ */
+ function sample(collection) {
+ var array = isArrayLike(collection) ? collection : values(collection),
+ length = array.length;
+
+ return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
+ }
+
+ return sample;
+});
diff --git a/sampleSize.js b/sampleSize.js
new file mode 100644
index 000000000..7d7acad4f
--- /dev/null
+++ b/sampleSize.js
@@ -0,0 +1,36 @@
+define(['./internal/baseClamp', './internal/baseRandom', './toArray', './toInteger'], function(baseClamp, baseRandom, toArray, toInteger) {
+
+ /**
+ * Gets `n` random elements from `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to sample.
+ * @param {number} [n=0] The number of elements to sample.
+ * @returns {Array} Returns the random elements.
+ * @example
+ *
+ * _.sampleSize([1, 2, 3, 4], 2);
+ * // => [3, 1]
+ */
+ function sampleSize(collection, n) {
+ var index = -1,
+ result = toArray(collection),
+ length = result.length,
+ lastIndex = length - 1;
+
+ n = baseClamp(toInteger(n), 0, length);
+ while (++index < n) {
+ var rand = baseRandom(index, lastIndex),
+ value = result[rand];
+
+ result[rand] = result[index];
+ result[index] = value;
+ }
+ result.length = n;
+ return result;
+ }
+
+ return sampleSize;
+});
diff --git a/seq.js b/seq.js
new file mode 100644
index 000000000..990a7e6fe
--- /dev/null
+++ b/seq.js
@@ -0,0 +1,19 @@
+define(['./wrapperAt', './chain', './commit', './wrapperFlatMap', './wrapperLodash', './next', './plant', './wrapperReverse', './tap', './thru', './toIterator', './toJSON', './wrapperValue', './valueOf', './wrapperChain'], function(at, chain, commit, flatMap, lodash, next, plant, reverse, tap, thru, toIterator, toJSON, value, valueOf, wrapperChain) {
+ return {
+ 'at': at,
+ 'chain': chain,
+ 'commit': commit,
+ 'flatMap': flatMap,
+ 'lodash': lodash,
+ 'next': next,
+ 'plant': plant,
+ 'reverse': reverse,
+ 'tap': tap,
+ 'thru': thru,
+ 'toIterator': toIterator,
+ 'toJSON': toJSON,
+ 'value': value,
+ 'valueOf': valueOf,
+ 'wrapperChain': wrapperChain
+ };
+});
diff --git a/set.js b/set.js
new file mode 100644
index 000000000..e50389959
--- /dev/null
+++ b/set.js
@@ -0,0 +1,33 @@
+define(['./internal/baseSet'], function(baseSet) {
+
+ /**
+ * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
+ * it's created. Arrays are created for missing index properties while objects
+ * are created for all other missing properties. Use `_.setWith` to customize
+ * `path` creation.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.set(object, 'a[0].b.c', 4);
+ * console.log(object.a[0].b.c);
+ * // => 4
+ *
+ * _.set(object, 'x[0].y.z', 5);
+ * console.log(object.x[0].y.z);
+ * // => 5
+ */
+ function set(object, path, value) {
+ return object == null ? object : baseSet(object, path, value);
+ }
+
+ return set;
+});
diff --git a/setWith.js b/setWith.js
new file mode 100644
index 000000000..2bc472acf
--- /dev/null
+++ b/setWith.js
@@ -0,0 +1,31 @@
+define(['./internal/baseSet'], function(baseSet) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.set` except that it accepts `customizer` which is
+ * invoked to produce the objects of `path`. If `customizer` returns `undefined`
+ * path creation is handled by the method instead. The `customizer` is invoked
+ * with three arguments: (nsValue, key, nsObject).
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to set.
+ * @param {*} value The value to set.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
+ * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
+ */
+ function setWith(object, path, value, customizer) {
+ customizer = typeof customizer == 'function' ? customizer : undefined;
+ return object == null ? object : baseSet(object, path, value, customizer);
+ }
+
+ return setWith;
+});
diff --git a/collection/shuffle.js b/shuffle.js
similarity index 59%
rename from collection/shuffle.js
rename to shuffle.js
index 68f57075f..80c26f532 100644
--- a/collection/shuffle.js
+++ b/shuffle.js
@@ -1,7 +1,7 @@
-define(['./sample'], function(sample) {
+define(['./sampleSize'], function(sampleSize) {
- /** Used as references for `-Infinity` and `Infinity`. */
- var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
+ /** Used as references for the maximum length and index of an array. */
+ var MAX_ARRAY_LENGTH = 4294967295;
/**
* Creates an array of shuffled values, using a version of the
@@ -10,7 +10,7 @@ define(['./sample'], function(sample) {
* @static
* @memberOf _
* @category Collection
- * @param {Array|Object|string} collection The collection to shuffle.
+ * @param {Array|Object} collection The collection to shuffle.
* @returns {Array} Returns the new shuffled array.
* @example
*
@@ -18,7 +18,7 @@ define(['./sample'], function(sample) {
* // => [4, 1, 3, 2]
*/
function shuffle(collection) {
- return sample(collection, POSITIVE_INFINITY);
+ return sampleSize(collection, MAX_ARRAY_LENGTH);
}
return shuffle;
diff --git a/size.js b/size.js
new file mode 100644
index 000000000..f5dc24fff
--- /dev/null
+++ b/size.js
@@ -0,0 +1,35 @@
+define(['./isArrayLike', './isString', './keys', './internal/stringSize'], function(isArrayLike, isString, keys, stringSize) {
+
+ /**
+ * Gets the size of `collection` by returning its length for array-like
+ * values or the number of own enumerable properties for objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to inspect.
+ * @returns {number} Returns the collection size.
+ * @example
+ *
+ * _.size([1, 2, 3]);
+ * // => 3
+ *
+ * _.size({ 'a': 1, 'b': 2 });
+ * // => 2
+ *
+ * _.size('pebbles');
+ * // => 7
+ */
+ function size(collection) {
+ if (collection == null) {
+ return 0;
+ }
+ if (isArrayLike(collection)) {
+ var result = collection.length;
+ return (result && isString(collection)) ? stringSize(collection) : result;
+ }
+ return keys(collection).length;
+ }
+
+ return size;
+});
diff --git a/array/slice.js b/slice.js
similarity index 58%
rename from array/slice.js
rename to slice.js
index 412d7eb32..520fd0cf5 100644
--- a/array/slice.js
+++ b/slice.js
@@ -1,10 +1,13 @@
-define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSlice, isIterateeCall) {
+define(['./internal/baseSlice', './internal/isIterateeCall', './toInteger'], function(baseSlice, isIterateeCall, toInteger) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* Creates a slice of `array` from `start` up to, but not including, `end`.
*
- * **Note:** This method is used instead of `Array#slice` to support node
- * lists in IE < 9 and to ensure dense arrays are returned.
+ * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
+ * to ensure dense arrays are returned.
*
* @static
* @memberOf _
@@ -23,6 +26,10 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
start = 0;
end = length;
}
+ else {
+ start = start == null ? 0 : toInteger(start);
+ end = end === undefined ? length : toInteger(end);
+ }
return baseSlice(array, start, end);
}
diff --git a/string/snakeCase.js b/snakeCase.js
similarity index 89%
rename from string/snakeCase.js
rename to snakeCase.js
index 9a6cdbe58..cd4ecdc8b 100644
--- a/string/snakeCase.js
+++ b/snakeCase.js
@@ -1,4 +1,4 @@
-define(['../internal/createCompounder'], function(createCompounder) {
+define(['./internal/createCompounder'], function(createCompounder) {
/**
* Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
diff --git a/some.js b/some.js
new file mode 100644
index 000000000..44d8ed261
--- /dev/null
+++ b/some.js
@@ -0,0 +1,49 @@
+define(['./internal/arraySome', './internal/baseIteratee', './internal/baseSome', './isArray', './internal/isIterateeCall'], function(arraySome, baseIteratee, baseSome, isArray, isIterateeCall) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Checks if `predicate` returns truthy for **any** element of `collection`.
+ * Iteration is stopped once `predicate` returns truthy. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
+ * @example
+ *
+ * _.some([null, 0, 'yes', false], Boolean);
+ * // => true
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false }
+ * ];
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.some(users, { 'user': 'barney', 'active': false });
+ * // => false
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.some(users, ['active', false]);
+ * // => true
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.some(users, 'active');
+ * // => true
+ */
+ function some(collection, predicate, guard) {
+ var func = isArray(collection) ? arraySome : baseSome;
+ if (guard && isIterateeCall(collection, predicate, guard)) {
+ predicate = undefined;
+ }
+ return func(collection, baseIteratee(predicate, 3));
+ }
+
+ return some;
+});
diff --git a/sortBy.js b/sortBy.js
new file mode 100644
index 000000000..62e1c1919
--- /dev/null
+++ b/sortBy.js
@@ -0,0 +1,50 @@
+define(['./internal/baseFlatten', './internal/baseOrderBy', './internal/isIterateeCall', './rest'], function(baseFlatten, baseOrderBy, isIterateeCall, rest) {
+
+ /**
+ * Creates an array of elements, sorted in ascending order by the results of
+ * running each element in a collection through each iteratee. This method
+ * performs a stable sort, that is, it preserves the original sort order of
+ * equal elements. The iteratees are invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
+ * The iteratees to sort by, specified individually or in arrays.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'fred', 'age': 48 },
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 42 },
+ * { 'user': 'barney', 'age': 34 }
+ * ];
+ *
+ * _.sortBy(users, function(o) { return o.user; });
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
+ *
+ * _.sortBy(users, ['user', 'age']);
+ * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
+ *
+ * _.sortBy(users, 'user', function(o) {
+ * return Math.floor(o.age / 10);
+ * });
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
+ */
+ var sortBy = rest(function(collection, iteratees) {
+ if (collection == null) {
+ return [];
+ }
+ var length = iteratees.length;
+ if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
+ iteratees = [];
+ } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
+ iteratees.length = 1;
+ }
+ return baseOrderBy(collection, baseFlatten(iteratees), []);
+ });
+
+ return sortBy;
+});
diff --git a/sortedIndex.js b/sortedIndex.js
new file mode 100644
index 000000000..c0784bb10
--- /dev/null
+++ b/sortedIndex.js
@@ -0,0 +1,26 @@
+define(['./internal/baseSortedIndex'], function(baseSortedIndex) {
+
+ /**
+ * Uses a binary search to determine the lowest index at which `value` should
+ * be inserted into `array` in order to maintain its sort order.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
+ * @example
+ *
+ * _.sortedIndex([30, 50], 40);
+ * // => 1
+ *
+ * _.sortedIndex([4, 5], 4);
+ * // => 0
+ */
+ function sortedIndex(array, value) {
+ return baseSortedIndex(array, value);
+ }
+
+ return sortedIndex;
+});
diff --git a/sortedIndexBy.js b/sortedIndexBy.js
new file mode 100644
index 000000000..1563b1a89
--- /dev/null
+++ b/sortedIndexBy.js
@@ -0,0 +1,31 @@
+define(['./internal/baseIteratee', './internal/baseSortedIndexBy'], function(baseIteratee, baseSortedIndexBy) {
+
+ /**
+ * This method is like `_.sortedIndex` except that it accepts `iteratee`
+ * which is invoked for `value` and each element of `array` to compute their
+ * sort ranking. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
+ * @example
+ *
+ * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
+ *
+ * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
+ * // => 1
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+ * // => 0
+ */
+ function sortedIndexBy(array, value, iteratee) {
+ return baseSortedIndexBy(array, value, baseIteratee(iteratee));
+ }
+
+ return sortedIndexBy;
+});
diff --git a/sortedIndexOf.js b/sortedIndexOf.js
new file mode 100644
index 000000000..ca4c6e66f
--- /dev/null
+++ b/sortedIndexOf.js
@@ -0,0 +1,30 @@
+define(['./internal/baseSortedIndex', './eq'], function(baseSortedIndex, eq) {
+
+ /**
+ * This method is like `_.indexOf` except that it performs a binary
+ * search on a sorted `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.sortedIndexOf([1, 1, 2, 2], 2);
+ * // => 2
+ */
+ function sortedIndexOf(array, value) {
+ var length = array ? array.length : 0;
+ if (length) {
+ var index = baseSortedIndex(array, value);
+ if (index < length && eq(array[index], value)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ return sortedIndexOf;
+});
diff --git a/array/sortedLastIndex.js b/sortedLastIndex.js
similarity index 55%
rename from array/sortedLastIndex.js
rename to sortedLastIndex.js
index 20c917697..42193f8f7 100644
--- a/array/sortedLastIndex.js
+++ b/sortedLastIndex.js
@@ -1,4 +1,4 @@
-define(['../internal/createSortedIndex'], function(createSortedIndex) {
+define(['./internal/baseSortedIndex'], function(baseSortedIndex) {
/**
* This method is like `_.sortedIndex` except that it returns the highest
@@ -10,17 +10,15 @@ define(['../internal/createSortedIndex'], function(createSortedIndex) {
* @category Array
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @param {Function|Object|string} [iteratee=_.identity] The function invoked
- * per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
* @example
*
- * _.sortedLastIndex([4, 4, 5, 5], 5);
- * // => 4
+ * _.sortedLastIndex([4, 5], 4);
+ * // => 1
*/
- var sortedLastIndex = createSortedIndex(true);
+ function sortedLastIndex(array, value) {
+ return baseSortedIndex(array, value, true);
+ }
return sortedLastIndex;
});
diff --git a/sortedLastIndexBy.js b/sortedLastIndexBy.js
new file mode 100644
index 000000000..aaa542f42
--- /dev/null
+++ b/sortedLastIndexBy.js
@@ -0,0 +1,26 @@
+define(['./internal/baseIteratee', './internal/baseSortedIndexBy'], function(baseIteratee, baseSortedIndexBy) {
+
+ /**
+ * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
+ * which is invoked for `value` and each element of `array` to compute their
+ * sort ranking. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the index at which `value` should be inserted into `array`.
+ * @example
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+ * // => 1
+ */
+ function sortedLastIndexBy(array, value, iteratee) {
+ return baseSortedIndexBy(array, value, baseIteratee(iteratee), true);
+ }
+
+ return sortedLastIndexBy;
+});
diff --git a/sortedLastIndexOf.js b/sortedLastIndexOf.js
new file mode 100644
index 000000000..13569c073
--- /dev/null
+++ b/sortedLastIndexOf.js
@@ -0,0 +1,30 @@
+define(['./internal/baseSortedIndex', './eq'], function(baseSortedIndex, eq) {
+
+ /**
+ * This method is like `_.lastIndexOf` except that it performs a binary
+ * search on a sorted `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.sortedLastIndexOf([1, 1, 2, 2], 2);
+ * // => 3
+ */
+ function sortedLastIndexOf(array, value) {
+ var length = array ? array.length : 0;
+ if (length) {
+ var index = baseSortedIndex(array, value, true) - 1;
+ if (eq(array[index], value)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ return sortedLastIndexOf;
+});
diff --git a/sortedUniq.js b/sortedUniq.js
new file mode 100644
index 000000000..f92c43f90
--- /dev/null
+++ b/sortedUniq.js
@@ -0,0 +1,24 @@
+define(['./internal/baseSortedUniq'], function(baseSortedUniq) {
+
+ /**
+ * This method is like `_.uniq` except that it's designed and optimized
+ * for sorted arrays.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.sortedUniq([1, 1, 2]);
+ * // => [1, 2]
+ */
+ function sortedUniq(array) {
+ return (array && array.length)
+ ? baseSortedUniq(array)
+ : [];
+ }
+
+ return sortedUniq;
+});
diff --git a/sortedUniqBy.js b/sortedUniqBy.js
new file mode 100644
index 000000000..dac84c8ab
--- /dev/null
+++ b/sortedUniqBy.js
@@ -0,0 +1,25 @@
+define(['./internal/baseIteratee', './internal/baseSortedUniqBy'], function(baseIteratee, baseSortedUniqBy) {
+
+ /**
+ * This method is like `_.uniqBy` except that it's designed and optimized
+ * for sorted arrays.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
+ * // => [1.1, 2.2]
+ */
+ function sortedUniqBy(array, iteratee) {
+ return (array && array.length)
+ ? baseSortedUniqBy(array, baseIteratee(iteratee))
+ : [];
+ }
+
+ return sortedUniqBy;
+});
diff --git a/split.js b/split.js
new file mode 100644
index 000000000..36e4d2d2f
--- /dev/null
+++ b/split.js
@@ -0,0 +1,25 @@
+define(['./toString'], function(toString) {
+
+ /**
+ * Splits `string` by `separator`.
+ *
+ * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to split.
+ * @param {RegExp|string} separator The separator pattern to split by.
+ * @param {number} [limit] The length to truncate results to.
+ * @returns {Array} Returns the new array of string segments.
+ * @example
+ *
+ * _.split('a-b-c', '-', 2);
+ * // => ['a', 'b']
+ */
+ function split(string, separator, limit) {
+ return toString(string).split(separator, limit);
+ }
+
+ return split;
+});
diff --git a/function/spread.js b/spread.js
similarity index 88%
rename from function/spread.js
rename to spread.js
index 395e96ae9..a92993066 100644
--- a/function/spread.js
+++ b/spread.js
@@ -1,4 +1,4 @@
-define([], function() {
+define(['./internal/apply'], function(apply) {
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -7,7 +7,7 @@ define([], function() {
* Creates a function that invokes `func` with the `this` binding of the created
* function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
*
- * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/Web/JavaScript/Reference/Operators/Spread_operator).
+ * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
*
* @static
* @memberOf _
@@ -39,7 +39,7 @@ define([], function() {
throw new TypeError(FUNC_ERROR_TEXT);
}
return function(array) {
- return func.apply(this, array);
+ return apply(func, this, array);
};
}
diff --git a/string/startCase.js b/startCase.js
similarity index 78%
rename from string/startCase.js
rename to startCase.js
index dc44d28c2..9b5275d7b 100644
--- a/string/startCase.js
+++ b/startCase.js
@@ -1,4 +1,4 @@
-define(['../internal/createCompounder'], function(createCompounder) {
+define(['./capitalize', './internal/createCompounder'], function(capitalize, createCompounder) {
/**
* Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
@@ -20,7 +20,7 @@ define(['../internal/createCompounder'], function(createCompounder) {
* // => 'Foo Bar'
*/
var startCase = createCompounder(function(result, word, index) {
- return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));
+ return result + (index ? ' ' : '') + capitalize(word);
});
return startCase;
diff --git a/string/startsWith.js b/startsWith.js
similarity index 68%
rename from string/startsWith.js
rename to startsWith.js
index bd730a5b6..2ce0c15f8 100644
--- a/string/startsWith.js
+++ b/startsWith.js
@@ -1,7 +1,4 @@
-define(['../internal/baseToString'], function(baseToString) {
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeMin = Math.min;
+define(['./internal/baseClamp', './toInteger', './toString'], function(baseClamp, toInteger, toString) {
/**
* Checks if `string` starts with the given target string.
@@ -25,11 +22,8 @@ define(['../internal/baseToString'], function(baseToString) {
* // => true
*/
function startsWith(string, target, position) {
- string = baseToString(string);
- position = position == null
- ? 0
- : nativeMin(position < 0 ? 0 : (+position || 0), string.length);
-
+ string = toString(string);
+ position = baseClamp(toInteger(position), 0, string.length);
return string.lastIndexOf(target, position) == position;
}
diff --git a/string.js b/string.js
index b1e317936..3a35ccb61 100644
--- a/string.js
+++ b/string.js
@@ -1,4 +1,4 @@
-define(['./string/camelCase', './string/capitalize', './string/deburr', './string/endsWith', './string/escape', './string/escapeRegExp', './string/kebabCase', './string/pad', './string/padLeft', './string/padRight', './string/parseInt', './string/repeat', './string/snakeCase', './string/startCase', './string/startsWith', './string/template', './string/templateSettings', './string/trim', './string/trimLeft', './string/trimRight', './string/trunc', './string/unescape', './string/words'], function(camelCase, capitalize, deburr, endsWith, escape, escapeRegExp, kebabCase, pad, padLeft, padRight, parseInt, repeat, snakeCase, startCase, startsWith, template, templateSettings, trim, trimLeft, trimRight, trunc, unescape, words) {
+define(['./camelCase', './capitalize', './deburr', './endsWith', './escape', './escapeRegExp', './kebabCase', './lowerCase', './lowerFirst', './pad', './padEnd', './padStart', './parseInt', './repeat', './replace', './snakeCase', './split', './startCase', './startsWith', './template', './templateSettings', './toLower', './toUpper', './trim', './trimEnd', './trimStart', './truncate', './unescape', './upperCase', './upperFirst', './words'], function(camelCase, capitalize, deburr, endsWith, escape, escapeRegExp, kebabCase, lowerCase, lowerFirst, pad, padEnd, padStart, parseInt, repeat, replace, snakeCase, split, startCase, startsWith, template, templateSettings, toLower, toUpper, trim, trimEnd, trimStart, truncate, unescape, upperCase, upperFirst, words) {
return {
'camelCase': camelCase,
'capitalize': capitalize,
@@ -7,21 +7,29 @@ define(['./string/camelCase', './string/capitalize', './string/deburr', './strin
'escape': escape,
'escapeRegExp': escapeRegExp,
'kebabCase': kebabCase,
+ 'lowerCase': lowerCase,
+ 'lowerFirst': lowerFirst,
'pad': pad,
- 'padLeft': padLeft,
- 'padRight': padRight,
+ 'padEnd': padEnd,
+ 'padStart': padStart,
'parseInt': parseInt,
'repeat': repeat,
+ 'replace': replace,
'snakeCase': snakeCase,
+ 'split': split,
'startCase': startCase,
'startsWith': startsWith,
'template': template,
'templateSettings': templateSettings,
+ 'toLower': toLower,
+ 'toUpper': toUpper,
'trim': trim,
- 'trimLeft': trimLeft,
- 'trimRight': trimRight,
- 'trunc': trunc,
+ 'trimEnd': trimEnd,
+ 'trimStart': trimStart,
+ 'truncate': truncate,
'unescape': unescape,
+ 'upperCase': upperCase,
+ 'upperFirst': upperFirst,
'words': words
};
});
diff --git a/string/escapeRegExp.js b/string/escapeRegExp.js
deleted file mode 100644
index b6fcf75e1..000000000
--- a/string/escapeRegExp.js
+++ /dev/null
@@ -1,32 +0,0 @@
-define(['../internal/baseToString', '../internal/escapeRegExpChar'], function(baseToString, escapeRegExpChar) {
-
- /**
- * 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 = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,
- reHasRegExpChars = RegExp(reRegExpChars.source);
-
- /**
- * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?",
- * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.
- *
- * @static
- * @memberOf _
- * @category String
- * @param {string} [string=''] The string to escape.
- * @returns {string} Returns the escaped string.
- * @example
- *
- * _.escapeRegExp('[lodash](https://lodash.com/)');
- * // => '\[lodash\]\(https:\/\/lodash\.com\/\)'
- */
- function escapeRegExp(string) {
- string = baseToString(string);
- return (string && reHasRegExpChars.test(string))
- ? string.replace(reRegExpChars, escapeRegExpChar)
- : (string || '(?:)');
- }
-
- return escapeRegExp;
-});
diff --git a/string/trim.js b/string/trim.js
deleted file mode 100644
index 56b863cf1..000000000
--- a/string/trim.js
+++ /dev/null
@@ -1,38 +0,0 @@
-define(['../internal/baseToString', '../internal/charsLeftIndex', '../internal/charsRightIndex', '../internal/isIterateeCall', '../internal/trimmedLeftIndex', '../internal/trimmedRightIndex'], function(baseToString, charsLeftIndex, charsRightIndex, isIterateeCall, trimmedLeftIndex, trimmedRightIndex) {
-
- /**
- * Removes leading and trailing whitespace or specified characters from `string`.
- *
- * @static
- * @memberOf _
- * @category String
- * @param {string} [string=''] The string to trim.
- * @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {string} Returns the trimmed string.
- * @example
- *
- * _.trim(' abc ');
- * // => 'abc'
- *
- * _.trim('-_-abc-_-', '_-');
- * // => 'abc'
- *
- * _.map([' foo ', ' bar '], _.trim);
- * // => ['foo', 'bar']
- */
- function trim(string, chars, guard) {
- var value = string;
- string = baseToString(string);
- if (!string) {
- return string;
- }
- if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
- return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
- }
- chars = (chars + '');
- return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
- }
-
- return trim;
-});
diff --git a/string/trimLeft.js b/string/trimLeft.js
deleted file mode 100644
index 1632bcb50..000000000
--- a/string/trimLeft.js
+++ /dev/null
@@ -1,34 +0,0 @@
-define(['../internal/baseToString', '../internal/charsLeftIndex', '../internal/isIterateeCall', '../internal/trimmedLeftIndex'], function(baseToString, charsLeftIndex, isIterateeCall, trimmedLeftIndex) {
-
- /**
- * Removes leading whitespace or specified characters from `string`.
- *
- * @static
- * @memberOf _
- * @category String
- * @param {string} [string=''] The string to trim.
- * @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {string} Returns the trimmed string.
- * @example
- *
- * _.trimLeft(' abc ');
- * // => 'abc '
- *
- * _.trimLeft('-_-abc-_-', '_-');
- * // => 'abc-_-'
- */
- function trimLeft(string, chars, guard) {
- var value = string;
- string = baseToString(string);
- if (!string) {
- return string;
- }
- if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
- return string.slice(trimmedLeftIndex(string));
- }
- return string.slice(charsLeftIndex(string, (chars + '')));
- }
-
- return trimLeft;
-});
diff --git a/string/trimRight.js b/string/trimRight.js
deleted file mode 100644
index 21f4a89a6..000000000
--- a/string/trimRight.js
+++ /dev/null
@@ -1,34 +0,0 @@
-define(['../internal/baseToString', '../internal/charsRightIndex', '../internal/isIterateeCall', '../internal/trimmedRightIndex'], function(baseToString, charsRightIndex, isIterateeCall, trimmedRightIndex) {
-
- /**
- * Removes trailing whitespace or specified characters from `string`.
- *
- * @static
- * @memberOf _
- * @category String
- * @param {string} [string=''] The string to trim.
- * @param {string} [chars=whitespace] The characters to trim.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {string} Returns the trimmed string.
- * @example
- *
- * _.trimRight(' abc ');
- * // => ' abc'
- *
- * _.trimRight('-_-abc-_-', '_-');
- * // => '-_-abc'
- */
- function trimRight(string, chars, guard) {
- var value = string;
- string = baseToString(string);
- if (!string) {
- return string;
- }
- if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
- return string.slice(0, trimmedRightIndex(string) + 1);
- }
- return string.slice(0, charsRightIndex(string, (chars + '')) + 1);
- }
-
- return trimRight;
-});
diff --git a/string/trunc.js b/string/trunc.js
deleted file mode 100644
index 6af35267c..000000000
--- a/string/trunc.js
+++ /dev/null
@@ -1,106 +0,0 @@
-define(['../internal/baseToString', '../internal/isIterateeCall', '../lang/isObject', '../lang/isRegExp'], function(baseToString, isIterateeCall, isObject, isRegExp) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /** Used as default options for `_.trunc`. */
- var DEFAULT_TRUNC_LENGTH = 30,
- DEFAULT_TRUNC_OMISSION = '...';
-
- /** Used to match `RegExp` flags from their coerced string values. */
- var reFlags = /\w*$/;
-
- /**
- * Truncates `string` if it's longer than the given maximum string length.
- * The last characters of the truncated string are replaced with the omission
- * string which defaults to "...".
- *
- * @static
- * @memberOf _
- * @category String
- * @param {string} [string=''] The string to truncate.
- * @param {Object|number} [options] The options object or maximum string length.
- * @param {number} [options.length=30] The maximum string length.
- * @param {string} [options.omission='...'] The string to indicate text is omitted.
- * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {string} Returns the truncated string.
- * @example
- *
- * _.trunc('hi-diddly-ho there, neighborino');
- * // => 'hi-diddly-ho there, neighbo...'
- *
- * _.trunc('hi-diddly-ho there, neighborino', 24);
- * // => 'hi-diddly-ho there, n...'
- *
- * _.trunc('hi-diddly-ho there, neighborino', {
- * 'length': 24,
- * 'separator': ' '
- * });
- * // => 'hi-diddly-ho there,...'
- *
- * _.trunc('hi-diddly-ho there, neighborino', {
- * 'length': 24,
- * 'separator': /,? +/
- * });
- * // => 'hi-diddly-ho there...'
- *
- * _.trunc('hi-diddly-ho there, neighborino', {
- * 'omission': ' [...]'
- * });
- * // => 'hi-diddly-ho there, neig [...]'
- */
- function trunc(string, options, guard) {
- if (guard && isIterateeCall(string, options, guard)) {
- options = undefined;
- }
- var length = DEFAULT_TRUNC_LENGTH,
- omission = DEFAULT_TRUNC_OMISSION;
-
- if (options != null) {
- if (isObject(options)) {
- var separator = 'separator' in options ? options.separator : separator;
- length = 'length' in options ? (+options.length || 0) : length;
- omission = 'omission' in options ? baseToString(options.omission) : omission;
- } else {
- length = +options || 0;
- }
- }
- string = baseToString(string);
- if (length >= string.length) {
- return string;
- }
- var end = length - omission.length;
- if (end < 1) {
- return omission;
- }
- var result = string.slice(0, end);
- if (separator == null) {
- return result + omission;
- }
- if (isRegExp(separator)) {
- if (string.slice(end).search(separator)) {
- var match,
- newEnd,
- substring = string.slice(0, end);
-
- if (!separator.global) {
- separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g');
- }
- separator.lastIndex = 0;
- while ((match = separator.exec(substring))) {
- newEnd = match.index;
- }
- result = result.slice(0, newEnd == null ? end : newEnd);
- }
- } else if (string.indexOf(separator, end) != end) {
- var index = result.lastIndexOf(separator);
- if (index > -1) {
- result = result.slice(0, index);
- }
- }
- return result + omission;
- }
-
- return trunc;
-});
diff --git a/string/words.js b/string/words.js
deleted file mode 100644
index 628d76376..000000000
--- a/string/words.js
+++ /dev/null
@@ -1,41 +0,0 @@
-define(['../internal/baseToString', '../internal/isIterateeCall'], function(baseToString, isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /** Used to match words to create compound words. */
- var reWords = (function() {
- var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]',
- lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+';
-
- return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');
- }());
-
- /**
- * Splits `string` into an array of its words.
- *
- * @static
- * @memberOf _
- * @category String
- * @param {string} [string=''] The string to inspect.
- * @param {RegExp|string} [pattern] The pattern to match words.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {Array} Returns the words of `string`.
- * @example
- *
- * _.words('fred, barney, & pebbles');
- * // => ['fred', 'barney', 'pebbles']
- *
- * _.words('fred, barney, & pebbles', /[^, ]+/g);
- * // => ['fred', 'barney', '&', 'pebbles']
- */
- function words(string, pattern, guard) {
- if (guard && isIterateeCall(string, pattern, guard)) {
- pattern = undefined;
- }
- string = baseToString(string);
- return string.match(pattern || reWords) || [];
- }
-
- return words;
-});
diff --git a/subtract.js b/subtract.js
new file mode 100644
index 000000000..258936405
--- /dev/null
+++ b/subtract.js
@@ -0,0 +1,32 @@
+define([], function() {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Subtract two numbers.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {number} minuend The first number in a subtraction.
+ * @param {number} subtrahend The second number in a subtraction.
+ * @returns {number} Returns the difference.
+ * @example
+ *
+ * _.subtract(6, 4);
+ * // => 2
+ */
+ function subtract(minuend, subtrahend) {
+ var result;
+ if (minuend !== undefined) {
+ result = minuend;
+ }
+ if (subtrahend !== undefined) {
+ result = result === undefined ? subtrahend : (result - subtrahend);
+ }
+ return result;
+ }
+
+ return subtract;
+});
diff --git a/sum.js b/sum.js
new file mode 100644
index 000000000..13ea9cacc
--- /dev/null
+++ b/sum.js
@@ -0,0 +1,26 @@
+define(['./internal/baseSum', './identity'], function(baseSum, identity) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * Computes the sum of the values in `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {number} Returns the sum.
+ * @example
+ *
+ * _.sum([4, 2, 8, 6]);
+ * // => 20
+ */
+ function sum(array) {
+ return (array && array.length)
+ ? baseSum(array, identity)
+ : undefined;
+ }
+
+ return sum;
+});
diff --git a/sumBy.js b/sumBy.js
new file mode 100644
index 000000000..d4cda5d55
--- /dev/null
+++ b/sumBy.js
@@ -0,0 +1,35 @@
+define(['./internal/baseIteratee', './internal/baseSum'], function(baseIteratee, baseSum) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.sum` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the value to be summed.
+ * The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {number} Returns the sum.
+ * @example
+ *
+ * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
+ *
+ * _.sumBy(objects, function(o) { return o.n; });
+ * // => 20
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.sumBy(objects, 'n');
+ * // => 20
+ */
+ function sumBy(array, iteratee) {
+ return (array && array.length)
+ ? baseSum(array, baseIteratee(iteratee))
+ : undefined;
+ }
+
+ return sumBy;
+});
diff --git a/support.js b/support.js
deleted file mode 100644
index df2f8dd6d..000000000
--- a/support.js
+++ /dev/null
@@ -1,13 +0,0 @@
-define([], function() {
-
- /**
- * An object environment feature flags.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- var support = {};
-
- return support;
-});
diff --git a/array/rest.js b/tail.js
similarity index 80%
rename from array/rest.js
rename to tail.js
index 02833cc84..2dbeee8d7 100644
--- a/array/rest.js
+++ b/tail.js
@@ -5,18 +5,17 @@ define(['./drop'], function(drop) {
*
* @static
* @memberOf _
- * @alias tail
* @category Array
* @param {Array} array The array to query.
* @returns {Array} Returns the slice of `array`.
* @example
*
- * _.rest([1, 2, 3]);
+ * _.tail([1, 2, 3]);
* // => [2, 3]
*/
- function rest(array) {
+ function tail(array) {
return drop(array, 1);
}
- return rest;
+ return tail;
});
diff --git a/array/take.js b/take.js
similarity index 64%
rename from array/take.js
rename to take.js
index 421ce40d0..9cbb323ef 100644
--- a/array/take.js
+++ b/take.js
@@ -1,4 +1,7 @@
-define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSlice, isIterateeCall) {
+define(['./internal/baseSlice', './toInteger'], function(baseSlice, toInteger) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* Creates a slice of `array` with `n` elements taken from the beginning.
@@ -8,7 +11,7 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to take.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
@@ -25,13 +28,10 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
* // => []
*/
function take(array, n, guard) {
- var length = array ? array.length : 0;
- if (!length) {
+ if (!(array && array.length)) {
return [];
}
- if (guard ? isIterateeCall(array, n, guard) : n == null) {
- n = 1;
- }
+ n = (guard || n === undefined) ? 1 : toInteger(n);
return baseSlice(array, 0, n < 0 ? 0 : n);
}
diff --git a/array/takeRight.js b/takeRight.js
similarity index 63%
rename from array/takeRight.js
rename to takeRight.js
index d5e4f9998..cd5da5e9a 100644
--- a/array/takeRight.js
+++ b/takeRight.js
@@ -1,4 +1,7 @@
-define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSlice, isIterateeCall) {
+define(['./internal/baseSlice', './toInteger'], function(baseSlice, toInteger) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
/**
* Creates a slice of `array` with `n` elements taken from the end.
@@ -8,7 +11,7 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to take.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
@@ -29,11 +32,9 @@ define(['../internal/baseSlice', '../internal/isIterateeCall'], function(baseSli
if (!length) {
return [];
}
- if (guard ? isIterateeCall(array, n, guard) : n == null) {
- n = 1;
- }
- n = length - (+n || 0);
- return baseSlice(array, n < 0 ? 0 : n);
+ n = (guard || n === undefined) ? 1 : toInteger(n);
+ n = length - n;
+ return baseSlice(array, n < 0 ? 0 : n, length);
}
return takeRight;
diff --git a/takeRightWhile.js b/takeRightWhile.js
new file mode 100644
index 000000000..7422bfbb2
--- /dev/null
+++ b/takeRightWhile.js
@@ -0,0 +1,44 @@
+define(['./internal/baseIteratee', './internal/baseWhile'], function(baseIteratee, baseWhile) {
+
+ /**
+ * Creates a slice of `array` with elements taken from the end. Elements are
+ * taken until `predicate` returns falsey. The predicate is invoked with three
+ * arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false },
+ * { 'user': 'pebbles', 'active': false }
+ * ];
+ *
+ * _.takeRightWhile(users, function(o) { return !o.active; });
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
+ * // => objects for ['pebbles']
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.takeRightWhile(users, ['active', false]);
+ * // => objects for ['fred', 'pebbles']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.takeRightWhile(users, 'active');
+ * // => []
+ */
+ function takeRightWhile(array, predicate) {
+ return (array && array.length)
+ ? baseWhile(array, baseIteratee(predicate, 3), false, true)
+ : [];
+ }
+
+ return takeRightWhile;
+});
diff --git a/takeWhile.js b/takeWhile.js
new file mode 100644
index 000000000..d6fa143ac
--- /dev/null
+++ b/takeWhile.js
@@ -0,0 +1,44 @@
+define(['./internal/baseIteratee', './internal/baseWhile'], function(baseIteratee, baseWhile) {
+
+ /**
+ * Creates a slice of `array` with elements taken from the beginning. Elements
+ * are taken until `predicate` returns falsey. The predicate is invoked with
+ * three arguments: (value, index, array).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the slice of `array`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false},
+ * { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.takeWhile(users, function(o) { return !o.active; });
+ * // => objects for ['barney', 'fred']
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.takeWhile(users, { 'user': 'barney', 'active': false });
+ * // => objects for ['barney']
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.takeWhile(users, ['active', false]);
+ * // => objects for ['barney', 'fred']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.takeWhile(users, 'active');
+ * // => []
+ */
+ function takeWhile(array, predicate) {
+ return (array && array.length)
+ ? baseWhile(array, baseIteratee(predicate, 3))
+ : [];
+ }
+
+ return takeWhile;
+});
diff --git a/chain/tap.js b/tap.js
similarity index 56%
rename from chain/tap.js
rename to tap.js
index ebccd6a8b..c6d1478e9 100644
--- a/chain/tap.js
+++ b/tap.js
@@ -2,16 +2,15 @@ define([], function() {
/**
* This method invokes `interceptor` and returns `value`. The interceptor is
- * bound to `thisArg` and invoked with one argument; (value). The purpose of
- * this method is to "tap into" a method chain in order to perform operations
- * on intermediate results within the chain.
+ * invoked with one argument; (value). The purpose of this method is to "tap into"
+ * a method chain in order to perform operations on intermediate results within
+ * the chain.
*
* @static
* @memberOf _
- * @category Chain
+ * @category Seq
* @param {*} value The value to provide to `interceptor`.
* @param {Function} interceptor The function to invoke.
- * @param {*} [thisArg] The `this` binding of `interceptor`.
* @returns {*} Returns `value`.
* @example
*
@@ -23,8 +22,8 @@ define([], function() {
* .value();
* // => [2, 1]
*/
- function tap(value, interceptor, thisArg) {
- interceptor.call(thisArg, value);
+ function tap(value, interceptor) {
+ interceptor(value);
return value;
}
diff --git a/string/template.js b/template.js
similarity index 88%
rename from string/template.js
rename to template.js
index 597f6e7cb..e99aa59a5 100644
--- a/string/template.js
+++ b/template.js
@@ -1,4 +1,4 @@
-define(['../internal/assignOwnDefaults', '../internal/assignWith', '../utility/attempt', '../internal/baseAssign', '../internal/baseToString', '../internal/baseValues', '../internal/escapeStringChar', '../lang/isError', '../internal/isIterateeCall', '../object/keys', '../internal/reInterpolate', './templateSettings'], function(assignOwnDefaults, assignWith, attempt, baseAssign, baseToString, baseValues, escapeStringChar, isError, isIterateeCall, keys, reInterpolate, templateSettings) {
+define(['./internal/assignInDefaults', './assignInWith', './attempt', './internal/baseValues', './internal/escapeStringChar', './isError', './internal/isIterateeCall', './keys', './internal/reInterpolate', './templateSettings', './toString'], function(assignInDefaults, assignInWith, attempt, baseValues, escapeStringChar, isError, isIterateeCall, keys, reInterpolate, templateSettings, toString) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -45,7 +45,7 @@ define(['../internal/assignOwnDefaults', '../internal/assignWith', '../utility/a
* @param {RegExp} [options.interpolate] The "interpolate" delimiter.
* @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
* @param {string} [options.variable] The data object variable name.
- * @param- {Object} [otherOptions] Enables the legacy `options` param signature.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
* @returns {Function} Returns the compiled template function.
* @example
*
@@ -113,18 +113,18 @@ define(['../internal/assignOwnDefaults', '../internal/assignWith', '../utility/a
* };\
* ');
*/
- function template(string, options, otherOptions) {
+ function template(string, options, guard) {
// Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
// and Laura Doktorova's doT.js (https://github.com/olado/doT).
var settings = templateSettings.imports._.templateSettings || templateSettings;
- if (otherOptions && isIterateeCall(string, options, otherOptions)) {
- options = otherOptions = undefined;
+ if (guard && isIterateeCall(string, options, guard)) {
+ options = undefined;
}
- string = baseToString(string);
- options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);
+ string = toString(string);
+ options = assignInWith({}, options, settings, assignInDefaults);
- var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults),
+ var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
importsKeys = keys(imports),
importsValues = baseValues(imports, importsKeys);
@@ -165,8 +165,8 @@ define(['../internal/assignOwnDefaults', '../internal/assignWith', '../utility/a
}
index = offset + match.length;
- // The JS engine embedded in Adobe products requires returning the `match`
- // string in order to produce the correct `offset` value.
+ // The JS engine embedded in Adobe products needs `match` returned in
+ // order to produce the correct `offset` value.
return match;
});
diff --git a/string/templateSettings.js b/templateSettings.js
similarity index 89%
rename from string/templateSettings.js
rename to templateSettings.js
index 4c3758ec5..4fdbf50d3 100644
--- a/string/templateSettings.js
+++ b/templateSettings.js
@@ -1,4 +1,4 @@
-define(['./escape', '../internal/reEscape', '../internal/reEvaluate', '../internal/reInterpolate'], function(escape, reEscape, reEvaluate, reInterpolate) {
+define(['./escape', './internal/reEscape', './internal/reEvaluate', './internal/reInterpolate'], function(escape, reEscape, reEvaluate, reInterpolate) {
/**
* By default, the template delimiters used by lodash are like those in
diff --git a/function/throttle.js b/throttle.js
similarity index 72%
rename from function/throttle.js
rename to throttle.js
index b098bf68b..bafd50d7d 100644
--- a/function/throttle.js
+++ b/throttle.js
@@ -1,4 +1,4 @@
-define(['./debounce', '../lang/isObject'], function(debounce, isObject) {
+define(['./debounce', './isObject'], function(debounce, isObject) {
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -6,10 +6,12 @@ define(['./debounce', '../lang/isObject'], function(debounce, isObject) {
/**
* Creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds. The throttled function comes with a `cancel`
- * method to cancel delayed invocations. Provide an options object to indicate
- * that `func` should be invoked on the leading and/or trailing edge of the
- * `wait` timeout. Subsequent calls to the throttled function return the
- * result of the last `func` call.
+ * method to cancel delayed `func` invocations and a `flush` method to
+ * immediately invoke them. Provide an options object to indicate whether
+ * `func` should be invoked on the leading and/or trailing edge of the `wait`
+ * timeout. The `func` is invoked with the last arguments provided to the
+ * throttled function. Subsequent calls to the throttled function return the
+ * result of the last `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
* on the trailing edge of the timeout only if the the throttled function is
@@ -35,11 +37,10 @@ define(['./debounce', '../lang/isObject'], function(debounce, isObject) {
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
*
* // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
- * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
- * 'trailing': false
- * }));
+ * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
+ * jQuery(element).on('click', throttled);
*
- * // cancel a trailing throttled call
+ * // cancel a trailing throttled invocation
* jQuery(window).on('popstate', throttled.cancel);
*/
function throttle(func, wait, options) {
@@ -49,13 +50,11 @@ define(['./debounce', '../lang/isObject'], function(debounce, isObject) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- if (options === false) {
- leading = false;
- } else if (isObject(options)) {
+ if (isObject(options)) {
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
- return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
+ return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing });
}
return throttle;
diff --git a/chain/thru.js b/thru.js
similarity index 74%
rename from chain/thru.js
rename to thru.js
index 102e019e7..33c4db8ef 100644
--- a/chain/thru.js
+++ b/thru.js
@@ -5,10 +5,9 @@ define([], function() {
*
* @static
* @memberOf _
- * @category Chain
+ * @category Seq
* @param {*} value The value to provide to `interceptor`.
* @param {Function} interceptor The function to invoke.
- * @param {*} [thisArg] The `this` binding of `interceptor`.
* @returns {*} Returns the result of `interceptor`.
* @example
*
@@ -21,8 +20,8 @@ define([], function() {
* .value();
* // => ['abc']
*/
- function thru(value, interceptor, thisArg) {
- return interceptor.call(thisArg, value);
+ function thru(value, interceptor) {
+ return interceptor(value);
}
return thru;
diff --git a/times.js b/times.js
new file mode 100644
index 000000000..f095012f5
--- /dev/null
+++ b/times.js
@@ -0,0 +1,49 @@
+define(['./internal/baseTimes', './internal/toFunction', './toInteger'], function(baseTimes, toFunction, toInteger) {
+
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER = 9007199254740991;
+
+ /** Used as references for the maximum length and index of an array. */
+ var MAX_ARRAY_LENGTH = 4294967295;
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMin = Math.min;
+
+ /**
+ * Invokes the iteratee function `n` times, returning an array of the results
+ * of each invocation. The iteratee is invoked with one argument; (index).
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ * @example
+ *
+ * _.times(3, String);
+ * // => ['0', '1', '2']
+ *
+ * _.times(4, _.constant(true));
+ * // => [true, true, true, true]
+ */
+ function times(n, iteratee) {
+ n = toInteger(n);
+ if (n < 1 || n > MAX_SAFE_INTEGER) {
+ return [];
+ }
+ var index = MAX_ARRAY_LENGTH,
+ length = nativeMin(n, MAX_ARRAY_LENGTH);
+
+ iteratee = toFunction(iteratee);
+ n -= MAX_ARRAY_LENGTH;
+
+ var result = baseTimes(length, iteratee);
+ while (++index < n) {
+ iteratee(index);
+ }
+ return result;
+ }
+
+ return times;
+});
diff --git a/toArray.js b/toArray.js
new file mode 100644
index 000000000..d28ab0764
--- /dev/null
+++ b/toArray.js
@@ -0,0 +1,52 @@
+define(['./internal/_Symbol', './internal/copyArray', './internal/getTag', './isArrayLike', './isString', './internal/iteratorToArray', './internal/mapToArray', './internal/setToArray', './internal/stringToArray', './values'], function(_Symbol, copyArray, getTag, isArrayLike, isString, iteratorToArray, mapToArray, setToArray, stringToArray, values) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** `Object#toString` result references. */
+ var mapTag = '[object Map]',
+ setTag = '[object Set]';
+
+ /** Built-in value references. */
+ var iteratorSymbol = typeof (iteratorSymbol = _Symbol && _Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined;
+
+ /**
+ * Converts `value` to an array.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {Array} Returns the converted array.
+ * @example
+ *
+ * _.toArray({ 'a': 1, 'b': 2 });
+ * // => [1, 2]
+ *
+ * _.toArray('abc');
+ * // => ['a', 'b', 'c']
+ *
+ * _.toArray(1);
+ * // => []
+ *
+ * _.toArray(null);
+ * // => []
+ */
+ function toArray(value) {
+ if (!value) {
+ return [];
+ }
+ if (isArrayLike(value)) {
+ return isString(value) ? stringToArray(value) : copyArray(value);
+ }
+ if (iteratorSymbol && value[iteratorSymbol]) {
+ return iteratorToArray(value[iteratorSymbol]());
+ }
+ var tag = getTag(value),
+ func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
+
+ return func(value);
+ }
+
+ return toArray;
+});
diff --git a/toInteger.js b/toInteger.js
new file mode 100644
index 000000000..b235878b1
--- /dev/null
+++ b/toInteger.js
@@ -0,0 +1,45 @@
+define(['./toNumber'], function(toNumber) {
+
+ /** Used as references for various `Number` constants. */
+ var INFINITY = 1 / 0,
+ MAX_INTEGER = 1.7976931348623157e+308;
+
+ /**
+ * Converts `value` to an integer.
+ *
+ * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toInteger(3);
+ * // => 3
+ *
+ * _.toInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toInteger(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toInteger('3');
+ * // => 3
+ */
+ function toInteger(value) {
+ if (!value) {
+ return value === 0 ? value : 0;
+ }
+ value = toNumber(value);
+ if (value === INFINITY || value === -INFINITY) {
+ var sign = (value < 0 ? -1 : 1);
+ return sign * MAX_INTEGER;
+ }
+ var remainder = value % 1;
+ return value === value ? (remainder ? value - remainder : value) : 0;
+ }
+
+ return toInteger;
+});
diff --git a/toIterator.js b/toIterator.js
new file mode 100644
index 000000000..1785c0db7
--- /dev/null
+++ b/toIterator.js
@@ -0,0 +1,25 @@
+define([], function() {
+
+ /**
+ * Enables the wrapper to be iterable.
+ *
+ * @name Symbol.iterator
+ * @memberOf _
+ * @category Seq
+ * @returns {Object} Returns the wrapper object.
+ * @example
+ *
+ * var wrapped = _([1, 2]);
+ *
+ * wrapped[Symbol.iterator]() === wrapped;
+ * // => true
+ *
+ * Array.from(wrapped);
+ * // => [1, 2]
+ */
+ function wrapperToIterator() {
+ return this;
+ }
+
+ return wrapperToIterator;
+});
diff --git a/chain/toJSON.js b/toJSON.js
similarity index 100%
rename from chain/toJSON.js
rename to toJSON.js
diff --git a/toLength.js b/toLength.js
new file mode 100644
index 000000000..d74663d29
--- /dev/null
+++ b/toLength.js
@@ -0,0 +1,36 @@
+define(['./internal/baseClamp', './toInteger'], function(baseClamp, toInteger) {
+
+ /** Used as references for the maximum length and index of an array. */
+ var MAX_ARRAY_LENGTH = 4294967295;
+
+ /**
+ * Converts `value` to an integer suitable for use as the length of an
+ * array-like object.
+ *
+ * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @return {number} Returns the converted integer.
+ * @example
+ *
+ * _.toLength(3);
+ * // => 3
+ *
+ * _.toLength(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toLength(Infinity);
+ * // => 4294967295
+ *
+ * _.toLength('3');
+ * // => 3
+ */
+ function toLength(value) {
+ return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
+ }
+
+ return toLength;
+});
diff --git a/toLower.js b/toLower.js
new file mode 100644
index 000000000..43170e31e
--- /dev/null
+++ b/toLower.js
@@ -0,0 +1,27 @@
+define(['./toString'], function(toString) {
+
+ /**
+ * Converts `string`, as a whole, to lower case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the lower cased string.
+ * @example
+ *
+ * _.toLower('--Foo-Bar');
+ * // => '--foo-bar'
+ *
+ * _.toLower('fooBar');
+ * // => 'foobar'
+ *
+ * _.toLower('__FOO_BAR__');
+ * // => '__foo_bar__'
+ */
+ function toLower(value) {
+ return toString(value).toLowerCase();
+ }
+
+ return toLower;
+});
diff --git a/toNumber.js b/toNumber.js
new file mode 100644
index 000000000..52c6ae6a2
--- /dev/null
+++ b/toNumber.js
@@ -0,0 +1,59 @@
+define(['./isFunction', './isObject'], function(isFunction, isObject) {
+
+ /** Used as references for various `Number` constants. */
+ var NAN = 0 / 0;
+
+ /** Used to match leading and trailing whitespace. */
+ var reTrim = /^\s+|\s+$/g;
+
+ /** Used to detect bad signed hexadecimal string values. */
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+
+ /** Used to detect binary string values. */
+ var reIsBinary = /^0b[01]+$/i;
+
+ /** Used to detect octal string values. */
+ var reIsOctal = /^0o[0-7]+$/i;
+
+ /** Built-in method references without a dependency on `root`. */
+ var freeParseInt = parseInt;
+
+ /**
+ * Converts `value` to a number.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ * @example
+ *
+ * _.toNumber(3);
+ * // => 3
+ *
+ * _.toNumber(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toNumber(Infinity);
+ * // => Infinity
+ *
+ * _.toNumber('3');
+ * // => 3
+ */
+ function toNumber(value) {
+ if (isObject(value)) {
+ var other = isFunction(value.valueOf) ? value.valueOf() : value;
+ value = isObject(other) ? (other + '') : other;
+ }
+ if (typeof value != 'string') {
+ return value === 0 ? value : +value;
+ }
+ value = value.replace(reTrim, '');
+ var isBinary = reIsBinary.test(value);
+ return (isBinary || reIsOctal.test(value))
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
+ : (reIsBadHex.test(value) ? NAN : +value);
+ }
+
+ return toNumber;
+});
diff --git a/toPairs.js b/toPairs.js
new file mode 100644
index 000000000..d112b6be7
--- /dev/null
+++ b/toPairs.js
@@ -0,0 +1,28 @@
+define(['./internal/baseToPairs', './keys'], function(baseToPairs, keys) {
+
+ /**
+ * Creates an array of own enumerable key-value pairs for `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the new array of key-value pairs.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.toPairs(new Foo);
+ * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
+ */
+ function toPairs(object) {
+ return baseToPairs(object, keys(object));
+ }
+
+ return toPairs;
+});
diff --git a/toPairsIn.js b/toPairsIn.js
new file mode 100644
index 000000000..0275bc114
--- /dev/null
+++ b/toPairsIn.js
@@ -0,0 +1,28 @@
+define(['./internal/baseToPairs', './keysIn'], function(baseToPairs, keysIn) {
+
+ /**
+ * Creates an array of own and inherited enumerable key-value pairs for `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the new array of key-value pairs.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.toPairsIn(new Foo);
+ * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
+ */
+ function toPairsIn(object) {
+ return baseToPairs(object, keysIn(object));
+ }
+
+ return toPairsIn;
+});
diff --git a/toPath.js b/toPath.js
new file mode 100644
index 000000000..7826f4228
--- /dev/null
+++ b/toPath.js
@@ -0,0 +1,33 @@
+define(['./internal/arrayMap', './isArray', './internal/stringToPath'], function(arrayMap, isArray, stringToPath) {
+
+ /**
+ * Converts `value` to a property path array.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {*} value The value to convert.
+ * @returns {Array} Returns the new property path array.
+ * @example
+ *
+ * _.toPath('a.b.c');
+ * // => ['a', 'b', 'c']
+ *
+ * _.toPath('a[0].b.c');
+ * // => ['a', '0', 'b', 'c']
+ *
+ * var path = ['a', 'b', 'c'],
+ * newPath = _.toPath(path);
+ *
+ * console.log(newPath);
+ * // => ['a', 'b', 'c']
+ *
+ * console.log(path === newPath);
+ * // => false
+ */
+ function toPath(value) {
+ return isArray(value) ? arrayMap(value, String) : stringToPath(value);
+ }
+
+ return toPath;
+});
diff --git a/lang/toPlainObject.js b/toPlainObject.js
similarity index 83%
rename from lang/toPlainObject.js
rename to toPlainObject.js
index b5aa6d8e3..21b5f5158 100644
--- a/lang/toPlainObject.js
+++ b/toPlainObject.js
@@ -1,4 +1,4 @@
-define(['../internal/baseCopy', '../object/keysIn'], function(baseCopy, keysIn) {
+define(['./internal/copyObject', './keysIn'], function(copyObject, keysIn) {
/**
* Converts `value` to a plain object flattening inherited enumerable
@@ -24,7 +24,7 @@ define(['../internal/baseCopy', '../object/keysIn'], function(baseCopy, keysIn)
* // => { 'a': 1, 'b': 2, 'c': 3 }
*/
function toPlainObject(value) {
- return baseCopy(value, keysIn(value));
+ return copyObject(value, keysIn(value));
}
return toPlainObject;
diff --git a/toSafeInteger.js b/toSafeInteger.js
new file mode 100644
index 000000000..c4259968f
--- /dev/null
+++ b/toSafeInteger.js
@@ -0,0 +1,34 @@
+define(['./internal/baseClamp', './toInteger'], function(baseClamp, toInteger) {
+
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER = 9007199254740991;
+
+ /**
+ * Converts `value` to a safe integer. A safe integer can be compared and
+ * represented correctly.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toSafeInteger(3);
+ * // => 3
+ *
+ * _.toSafeInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toSafeInteger(Infinity);
+ * // => 9007199254740991
+ *
+ * _.toSafeInteger('3');
+ * // => 3
+ */
+ function toSafeInteger(value) {
+ return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
+ }
+
+ return toSafeInteger;
+});
diff --git a/toString.js b/toString.js
new file mode 100644
index 000000000..855703c69
--- /dev/null
+++ b/toString.js
@@ -0,0 +1,49 @@
+define(['./internal/_Symbol', './isSymbol'], function(_Symbol, isSymbol) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used as references for various `Number` constants. */
+ var INFINITY = 1 / 0;
+
+ /** Used to convert symbols to primitives and strings. */
+ var symbolProto = _Symbol ? _Symbol.prototype : undefined,
+ symbolToString = _Symbol ? symbolProto.toString : undefined;
+
+ /**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+ function toString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
+ }
+ if (value == null) {
+ return '';
+ }
+ if (isSymbol(value)) {
+ return _Symbol ? symbolToString.call(value) : '';
+ }
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+ }
+
+ return toString;
+});
diff --git a/toUpper.js b/toUpper.js
new file mode 100644
index 000000000..af1765cd5
--- /dev/null
+++ b/toUpper.js
@@ -0,0 +1,27 @@
+define(['./toString'], function(toString) {
+
+ /**
+ * Converts `string`, as a whole, to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the upper cased string.
+ * @example
+ *
+ * _.toUpper('--foo-bar');
+ * // => '--FOO-BAR'
+ *
+ * _.toUpper('fooBar');
+ * // => 'FOOBAR'
+ *
+ * _.toUpper('__foo_bar__');
+ * // => '__FOO_BAR__'
+ */
+ function toUpper(value) {
+ return toString(value).toUpperCase();
+ }
+
+ return toUpper;
+});
diff --git a/object/transform.js b/transform.js
similarity index 63%
rename from object/transform.js
rename to transform.js
index 32a1606bb..6d1b4c214 100644
--- a/object/transform.js
+++ b/transform.js
@@ -1,4 +1,4 @@
-define(['../internal/arrayEach', '../internal/baseCallback', '../internal/baseCreate', '../internal/baseForOwn', '../lang/isArray', '../lang/isFunction', '../lang/isObject', '../lang/isTypedArray'], function(arrayEach, baseCallback, baseCreate, baseForOwn, isArray, isFunction, isObject, isTypedArray) {
+define(['./internal/arrayEach', './internal/baseCreate', './internal/baseForOwn', './internal/baseIteratee', './isArray', './isFunction', './isObject', './isTypedArray'], function(arrayEach, baseCreate, baseForOwn, baseIteratee, isArray, isFunction, isObject, isTypedArray) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -7,9 +7,9 @@ define(['../internal/arrayEach', '../internal/baseCallback', '../internal/baseCr
* An alternative to `_.reduce`; this method transforms `object` to a new
* `accumulator` object which is the result of running each of its own enumerable
* properties through `iteratee`, with each invocation potentially mutating
- * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked
- * with four arguments: (accumulator, value, key, object). Iteratee functions
- * may exit iteration early by explicitly returning `false`.
+ * the `accumulator` object. The iteratee is invoked with four arguments:
+ * (accumulator, value, key, object). Iteratee functions may exit iteration
+ * early by explicitly returning `false`.
*
* @static
* @memberOf _
@@ -17,7 +17,6 @@ define(['../internal/arrayEach', '../internal/baseCallback', '../internal/baseCr
* @param {Array|Object} object The object to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The custom accumulator value.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {*} Returns the accumulated value.
* @example
*
@@ -27,14 +26,14 @@ define(['../internal/arrayEach', '../internal/baseCallback', '../internal/baseCr
* });
* // => [4, 9]
*
- * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) {
- * result[key] = n * 3;
+ * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
* });
- * // => { 'a': 3, 'b': 6 }
+ * // => { '1': ['a', 'c'], '2': ['b'] }
*/
- function transform(object, iteratee, accumulator, thisArg) {
+ function transform(object, iteratee, accumulator) {
var isArr = isArray(object) || isTypedArray(object);
- iteratee = baseCallback(iteratee, thisArg, 4);
+ iteratee = baseIteratee(iteratee, 4);
if (accumulator == null) {
if (isArr || isObject(object)) {
diff --git a/trim.js b/trim.js
new file mode 100644
index 000000000..1e338099c
--- /dev/null
+++ b/trim.js
@@ -0,0 +1,49 @@
+define(['./internal/charsEndIndex', './internal/charsStartIndex', './internal/stringToArray', './toString'], function(charsEndIndex, charsStartIndex, stringToArray, toString) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to match leading and trailing whitespace. */
+ var reTrim = /^\s+|\s+$/g;
+
+ /**
+ * Removes leading and trailing whitespace or specified characters from `string`.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to trim.
+ * @param {string} [chars=whitespace] The characters to trim.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {string} Returns the trimmed string.
+ * @example
+ *
+ * _.trim(' abc ');
+ * // => 'abc'
+ *
+ * _.trim('-_-abc-_-', '_-');
+ * // => 'abc'
+ *
+ * _.map([' foo ', ' bar '], _.trim);
+ * // => ['foo', 'bar']
+ */
+ function trim(string, chars, guard) {
+ string = toString(string);
+ if (!string) {
+ return string;
+ }
+ if (guard || chars === undefined) {
+ return string.replace(reTrim, '');
+ }
+ chars = (chars + '');
+ if (!chars) {
+ return string;
+ }
+ var strSymbols = stringToArray(string),
+ chrSymbols = stringToArray(chars);
+
+ return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join('');
+ }
+
+ return trim;
+});
diff --git a/trimEnd.js b/trimEnd.js
new file mode 100644
index 000000000..d3e37e9e5
--- /dev/null
+++ b/trimEnd.js
@@ -0,0 +1,44 @@
+define(['./internal/charsEndIndex', './internal/stringToArray', './toString'], function(charsEndIndex, stringToArray, toString) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to match leading and trailing whitespace. */
+ var reTrimEnd = /\s+$/;
+
+ /**
+ * Removes trailing whitespace or specified characters from `string`.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to trim.
+ * @param {string} [chars=whitespace] The characters to trim.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {string} Returns the trimmed string.
+ * @example
+ *
+ * _.trimEnd(' abc ');
+ * // => ' abc'
+ *
+ * _.trimEnd('-_-abc-_-', '_-');
+ * // => '-_-abc'
+ */
+ function trimEnd(string, chars, guard) {
+ string = toString(string);
+ if (!string) {
+ return string;
+ }
+ if (guard || chars === undefined) {
+ return string.replace(reTrimEnd, '');
+ }
+ chars = (chars + '');
+ if (!chars) {
+ return string;
+ }
+ var strSymbols = stringToArray(string);
+ return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join('');
+ }
+
+ return trimEnd;
+});
diff --git a/trimStart.js b/trimStart.js
new file mode 100644
index 000000000..dd8f761fb
--- /dev/null
+++ b/trimStart.js
@@ -0,0 +1,44 @@
+define(['./internal/charsStartIndex', './internal/stringToArray', './toString'], function(charsStartIndex, stringToArray, toString) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to match leading and trailing whitespace. */
+ var reTrimStart = /^\s+/;
+
+ /**
+ * Removes leading whitespace or specified characters from `string`.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to trim.
+ * @param {string} [chars=whitespace] The characters to trim.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {string} Returns the trimmed string.
+ * @example
+ *
+ * _.trimStart(' abc ');
+ * // => 'abc '
+ *
+ * _.trimStart('-_-abc-_-', '_-');
+ * // => 'abc-_-'
+ */
+ function trimStart(string, chars, guard) {
+ string = toString(string);
+ if (!string) {
+ return string;
+ }
+ if (guard || chars === undefined) {
+ return string.replace(reTrimStart, '');
+ }
+ chars = (chars + '');
+ if (!chars) {
+ return string;
+ }
+ var strSymbols = stringToArray(string);
+ return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join('');
+ }
+
+ return trimStart;
+});
diff --git a/truncate.js b/truncate.js
new file mode 100644
index 000000000..620d66e05
--- /dev/null
+++ b/truncate.js
@@ -0,0 +1,117 @@
+define(['./isObject', './isRegExp', './internal/stringSize', './internal/stringToArray', './toInteger', './toString'], function(isObject, isRegExp, stringSize, stringToArray, toInteger, toString) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used as default options for `_.truncate`. */
+ var DEFAULT_TRUNC_LENGTH = 30,
+ DEFAULT_TRUNC_OMISSION = '...';
+
+ /** Used to match `RegExp` flags from their coerced string values. */
+ var reFlags = /\w*$/;
+
+ /** Used to compose unicode character classes. */
+ var rsAstralRange = '\\ud800-\\udfff',
+ rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsVarRange = '\\ufe0e\\ufe0f';
+
+ /** Used to compose unicode capture groups. */
+ var rsZWJ = '\\u200d';
+
+ /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+ var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+
+ /**
+ * Truncates `string` if it's longer than the given maximum string length.
+ * The last characters of the truncated string are replaced with the omission
+ * string which defaults to "...".
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to truncate.
+ * @param {Object} [options] The options object.
+ * @param {number} [options.length=30] The maximum string length.
+ * @param {string} [options.omission='...'] The string to indicate text is omitted.
+ * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
+ * @returns {string} Returns the truncated string.
+ * @example
+ *
+ * _.truncate('hi-diddly-ho there, neighborino');
+ * // => 'hi-diddly-ho there, neighbo...'
+ *
+ * _.truncate('hi-diddly-ho there, neighborino', {
+ * 'length': 24,
+ * 'separator': ' '
+ * });
+ * // => 'hi-diddly-ho there,...'
+ *
+ * _.truncate('hi-diddly-ho there, neighborino', {
+ * 'length': 24,
+ * 'separator': /,? +/
+ * });
+ * // => 'hi-diddly-ho there...'
+ *
+ * _.truncate('hi-diddly-ho there, neighborino', {
+ * 'omission': ' [...]'
+ * });
+ * // => 'hi-diddly-ho there, neig [...]'
+ */
+ function truncate(string, options) {
+ var length = DEFAULT_TRUNC_LENGTH,
+ omission = DEFAULT_TRUNC_OMISSION;
+
+ if (isObject(options)) {
+ var separator = 'separator' in options ? options.separator : separator;
+ length = 'length' in options ? toInteger(options.length) : length;
+ omission = 'omission' in options ? toString(options.omission) : omission;
+ }
+ string = toString(string);
+
+ var strLength = string.length;
+ if (reHasComplexSymbol.test(string)) {
+ var strSymbols = stringToArray(string);
+ strLength = strSymbols.length;
+ }
+ if (length >= strLength) {
+ return string;
+ }
+ var end = length - stringSize(omission);
+ if (end < 1) {
+ return omission;
+ }
+ var result = strSymbols
+ ? strSymbols.slice(0, end).join('')
+ : string.slice(0, end);
+
+ if (separator === undefined) {
+ return result + omission;
+ }
+ if (strSymbols) {
+ end += (result.length - end);
+ }
+ if (isRegExp(separator)) {
+ if (string.slice(end).search(separator)) {
+ var match,
+ substring = result;
+
+ if (!separator.global) {
+ separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
+ }
+ separator.lastIndex = 0;
+ while ((match = separator.exec(substring))) {
+ var newEnd = match.index;
+ }
+ result = result.slice(0, newEnd === undefined ? end : newEnd);
+ }
+ } else if (string.indexOf(separator, end) != end) {
+ var index = result.lastIndexOf(separator);
+ if (index > -1) {
+ result = result.slice(0, index);
+ }
+ }
+ return result + omission;
+ }
+
+ return truncate;
+});
diff --git a/unary.js b/unary.js
new file mode 100644
index 000000000..2c62cf27c
--- /dev/null
+++ b/unary.js
@@ -0,0 +1,22 @@
+define(['./ary'], function(ary) {
+
+ /**
+ * Creates a function that accepts up to one argument, ignoring any
+ * additional arguments.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to cap arguments for.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * _.map(['6', '8', '10'], _.unary(parseInt));
+ * // => [6, 8, 10]
+ */
+ function unary(func) {
+ return ary(func, 1);
+ }
+
+ return unary;
+});
diff --git a/string/unescape.js b/unescape.js
similarity index 86%
rename from string/unescape.js
rename to unescape.js
index faad15307..5336ed732 100644
--- a/string/unescape.js
+++ b/unescape.js
@@ -1,4 +1,4 @@
-define(['../internal/baseToString', '../internal/unescapeHtmlChar'], function(baseToString, unescapeHtmlChar) {
+define(['./toString', './internal/unescapeHtmlChar'], function(toString, unescapeHtmlChar) {
/** Used to match HTML entities and HTML characters. */
var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
@@ -23,7 +23,7 @@ define(['../internal/baseToString', '../internal/unescapeHtmlChar'], function(ba
* // => 'fred, barney, & pebbles'
*/
function unescape(string) {
- string = baseToString(string);
+ string = toString(string);
return (string && reHasEscapedHtml.test(string))
? string.replace(reEscapedHtml, unescapeHtmlChar)
: string;
diff --git a/array/union.js b/union.js
similarity index 68%
rename from array/union.js
rename to union.js
index 1dd3f0b5e..4451d888b 100644
--- a/array/union.js
+++ b/union.js
@@ -1,4 +1,4 @@
-define(['../internal/baseFlatten', '../internal/baseUniq', '../function/restParam'], function(baseFlatten, baseUniq, restParam) {
+define(['./internal/baseFlatten', './internal/baseUniq', './rest'], function(baseFlatten, baseUniq, rest) {
/**
* Creates an array of unique values, in order, from all of the provided arrays
@@ -12,10 +12,10 @@ define(['../internal/baseFlatten', '../internal/baseUniq', '../function/restPara
* @returns {Array} Returns the new array of combined values.
* @example
*
- * _.union([1, 2], [4, 2], [2, 1]);
- * // => [1, 2, 4]
+ * _.union([2, 1], [4, 2], [1, 2]);
+ * // => [2, 1, 4]
*/
- var union = restParam(function(arrays) {
+ var union = rest(function(arrays) {
return baseUniq(baseFlatten(arrays, false, true));
});
diff --git a/unionBy.js b/unionBy.js
new file mode 100644
index 000000000..2f4f2254f
--- /dev/null
+++ b/unionBy.js
@@ -0,0 +1,35 @@
+define(['./internal/baseFlatten', './internal/baseIteratee', './internal/baseUniq', './isArrayLikeObject', './last', './rest'], function(baseFlatten, baseIteratee, baseUniq, isArrayLikeObject, last, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.union` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+ * // => [2.1, 1.2, 4.3]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }, { 'x': 2 }]
+ */
+ var unionBy = rest(function(arrays) {
+ var iteratee = last(arrays);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
+ }
+ return baseUniq(baseFlatten(arrays, false, true), baseIteratee(iteratee));
+ });
+
+ return unionBy;
+});
diff --git a/unionWith.js b/unionWith.js
new file mode 100644
index 000000000..152b0fcdf
--- /dev/null
+++ b/unionWith.js
@@ -0,0 +1,34 @@
+define(['./internal/baseFlatten', './internal/baseUniq', './isArrayLikeObject', './last', './rest'], function(baseFlatten, baseUniq, isArrayLikeObject, last, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.union` except that it accepts `comparator` which
+ * is invoked to compare elements of `arrays`. The comparator is invoked
+ * with two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.unionWith(objects, others, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+ */
+ var unionWith = rest(function(arrays) {
+ var comparator = last(arrays);
+ if (isArrayLikeObject(comparator)) {
+ comparator = undefined;
+ }
+ return baseUniq(baseFlatten(arrays, false, true), undefined, comparator);
+ });
+
+ return unionWith;
+});
diff --git a/uniq.js b/uniq.js
new file mode 100644
index 000000000..77df6d176
--- /dev/null
+++ b/uniq.js
@@ -0,0 +1,26 @@
+define(['./internal/baseUniq'], function(baseUniq) {
+
+ /**
+ * Creates a duplicate-free version of an array, using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons, in which only the first occurrence of each element
+ * is kept.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.uniq([2, 1, 2]);
+ * // => [2, 1]
+ */
+ function uniq(array) {
+ return (array && array.length)
+ ? baseUniq(array)
+ : [];
+ }
+
+ return uniq;
+});
diff --git a/uniqBy.js b/uniqBy.js
new file mode 100644
index 000000000..e589ea2d1
--- /dev/null
+++ b/uniqBy.js
@@ -0,0 +1,30 @@
+define(['./internal/baseIteratee', './internal/baseUniq'], function(baseIteratee, baseUniq) {
+
+ /**
+ * This method is like `_.uniq` except that it accepts `iteratee` which is
+ * invoked for each element in `array` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
+ * // => [2.1, 1.2]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 1 }, { 'x': 2 }]
+ */
+ function uniqBy(array, iteratee) {
+ return (array && array.length)
+ ? baseUniq(array, baseIteratee(iteratee))
+ : [];
+ }
+
+ return uniqBy;
+});
diff --git a/uniqWith.js b/uniqWith.js
new file mode 100644
index 000000000..d86c27b2a
--- /dev/null
+++ b/uniqWith.js
@@ -0,0 +1,31 @@
+define(['./internal/baseUniq'], function(baseUniq) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.uniq` except that it accepts `comparator` which
+ * is invoked to compare elements of `array`. The comparator is invoked with
+ * two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new duplicate free array.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.uniqWith(objects, _.isEqual);
+ * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
+ */
+ function uniqWith(array, comparator) {
+ return (array && array.length)
+ ? baseUniq(array, undefined, comparator)
+ : [];
+ }
+
+ return uniqWith;
+});
diff --git a/utility/uniqueId.js b/uniqueId.js
similarity index 80%
rename from utility/uniqueId.js
rename to uniqueId.js
index 833fecacb..debf6d106 100644
--- a/utility/uniqueId.js
+++ b/uniqueId.js
@@ -1,4 +1,4 @@
-define(['../internal/baseToString'], function(baseToString) {
+define(['./toString'], function(toString) {
/** Used to generate unique IDs. */
var idCounter = 0;
@@ -8,7 +8,7 @@ define(['../internal/baseToString'], function(baseToString) {
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {string} [prefix] The value to prefix the ID with.
* @returns {string} Returns the unique ID.
* @example
@@ -21,7 +21,7 @@ define(['../internal/baseToString'], function(baseToString) {
*/
function uniqueId(prefix) {
var id = ++idCounter;
- return baseToString(prefix) + id;
+ return toString(prefix) + id;
}
return uniqueId;
diff --git a/unset.js b/unset.js
new file mode 100644
index 000000000..4f0a7f4f0
--- /dev/null
+++ b/unset.js
@@ -0,0 +1,32 @@
+define(['./internal/baseUnset'], function(baseUnset) {
+
+ /**
+ * Removes the property at `path` of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to modify.
+ * @param {Array|string} path The path of the property to unset.
+ * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 7 } }] };
+ * _.unset(object, 'a[0].b.c');
+ * // => true
+ *
+ * console.log(object);
+ * // => { 'a': [{ 'b': {} }] };
+ *
+ * _.unset(object, 'a[0].b.c');
+ * // => true
+ *
+ * console.log(object);
+ * // => { 'a': [{ 'b': {} }] };
+ */
+ function unset(object, path) {
+ return object == null ? true : baseUnset(object, path);
+ }
+
+ return unset;
+});
diff --git a/array/unzip.js b/unzip.js
similarity index 64%
rename from array/unzip.js
rename to unzip.js
index de8e39f93..24c483276 100644
--- a/array/unzip.js
+++ b/unzip.js
@@ -1,6 +1,6 @@
-define(['../internal/arrayFilter', '../internal/arrayMap', '../internal/baseProperty', '../internal/isArrayLike'], function(arrayFilter, arrayMap, baseProperty, isArrayLike) {
+define(['./internal/arrayFilter', './internal/arrayMap', './internal/baseProperty', './internal/baseTimes', './isArrayLikeObject'], function(arrayFilter, arrayMap, baseProperty, baseTimes, isArrayLikeObject) {
- /* Native method references for those with the same name as other `lodash` methods. */
+ /* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
@@ -25,20 +25,16 @@ define(['../internal/arrayFilter', '../internal/arrayMap', '../internal/baseProp
if (!(array && array.length)) {
return [];
}
- var index = -1,
- length = 0;
-
+ var length = 0;
array = arrayFilter(array, function(group) {
- if (isArrayLike(group)) {
+ if (isArrayLikeObject(group)) {
length = nativeMax(group.length, length);
return true;
}
});
- var result = Array(length);
- while (++index < length) {
- result[index] = arrayMap(array, baseProperty(index));
- }
- return result;
+ return baseTimes(length, function(index) {
+ return arrayMap(array, baseProperty(index));
+ });
}
return unzip;
diff --git a/unzipWith.js b/unzipWith.js
new file mode 100644
index 000000000..53d0b1f93
--- /dev/null
+++ b/unzipWith.js
@@ -0,0 +1,39 @@
+define(['./internal/apply', './internal/arrayMap', './unzip'], function(apply, arrayMap, unzip) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.unzip` except that it accepts `iteratee` to specify
+ * how regrouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array of grouped elements to process.
+ * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
+ * @returns {Array} Returns the new array of regrouped elements.
+ * @example
+ *
+ * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
+ * // => [[1, 10, 100], [2, 20, 200]]
+ *
+ * _.unzipWith(zipped, _.add);
+ * // => [3, 30, 300]
+ */
+ function unzipWith(array, iteratee) {
+ if (!(array && array.length)) {
+ return [];
+ }
+ var result = unzip(array);
+ if (iteratee == null) {
+ return result;
+ }
+ return arrayMap(result, function(group) {
+ return apply(iteratee, undefined, group);
+ });
+ }
+
+ return unzipWith;
+});
diff --git a/upperCase.js b/upperCase.js
new file mode 100644
index 000000000..ed318e5c4
--- /dev/null
+++ b/upperCase.js
@@ -0,0 +1,27 @@
+define(['./internal/createCompounder'], function(createCompounder) {
+
+ /**
+ * Converts `string`, as space separated words, to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the upper cased string.
+ * @example
+ *
+ * _.upperCase('--foo-bar');
+ * // => 'FOO BAR'
+ *
+ * _.upperCase('fooBar');
+ * // => 'FOO BAR'
+ *
+ * _.upperCase('__foo_bar__');
+ * // => 'FOO BAR'
+ */
+ var upperCase = createCompounder(function(result, word, index) {
+ return result + (index ? ' ' : '') + word.toUpperCase();
+ });
+
+ return upperCase;
+});
diff --git a/upperFirst.js b/upperFirst.js
new file mode 100644
index 000000000..385ff4b18
--- /dev/null
+++ b/upperFirst.js
@@ -0,0 +1,22 @@
+define(['./internal/createCaseFirst'], function(createCaseFirst) {
+
+ /**
+ * Converts the first character of `string` to upper case.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the converted string.
+ * @example
+ *
+ * _.upperFirst('fred');
+ * // => 'Fred'
+ *
+ * _.upperFirst('FRED');
+ * // => 'FRED'
+ */
+ var upperFirst = createCaseFirst('toUpperCase');
+
+ return upperFirst;
+});
diff --git a/util.js b/util.js
new file mode 100644
index 000000000..ffc4c0a42
--- /dev/null
+++ b/util.js
@@ -0,0 +1,30 @@
+define(['./attempt', './bindAll', './cond', './conforms', './constant', './flow', './flowRight', './identity', './iteratee', './matches', './matchesProperty', './method', './methodOf', './mixin', './noop', './nthArg', './over', './overEvery', './overSome', './property', './propertyOf', './range', './rangeRight', './times', './toPath', './uniqueId'], function(attempt, bindAll, cond, conforms, constant, flow, flowRight, identity, iteratee, matches, matchesProperty, method, methodOf, mixin, noop, nthArg, over, overEvery, overSome, property, propertyOf, range, rangeRight, times, toPath, uniqueId) {
+ return {
+ 'attempt': attempt,
+ 'bindAll': bindAll,
+ 'cond': cond,
+ 'conforms': conforms,
+ 'constant': constant,
+ 'flow': flow,
+ 'flowRight': flowRight,
+ 'identity': identity,
+ 'iteratee': iteratee,
+ 'matches': matches,
+ 'matchesProperty': matchesProperty,
+ 'method': method,
+ 'methodOf': methodOf,
+ 'mixin': mixin,
+ 'noop': noop,
+ 'nthArg': nthArg,
+ 'over': over,
+ 'overEvery': overEvery,
+ 'overSome': overSome,
+ 'property': property,
+ 'propertyOf': propertyOf,
+ 'range': range,
+ 'rangeRight': rangeRight,
+ 'times': times,
+ 'toPath': toPath,
+ 'uniqueId': uniqueId
+ };
+});
diff --git a/utility.js b/utility.js
deleted file mode 100644
index 7a4b74e1a..000000000
--- a/utility.js
+++ /dev/null
@@ -1,20 +0,0 @@
-define(['./utility/attempt', './utility/callback', './utility/constant', './utility/identity', './utility/iteratee', './utility/matches', './utility/matchesProperty', './utility/method', './utility/methodOf', './utility/mixin', './utility/noop', './utility/property', './utility/propertyOf', './utility/range', './utility/times', './utility/uniqueId'], function(attempt, callback, constant, identity, iteratee, matches, matchesProperty, method, methodOf, mixin, noop, property, propertyOf, range, times, uniqueId) {
- return {
- 'attempt': attempt,
- 'callback': callback,
- 'constant': constant,
- 'identity': identity,
- 'iteratee': iteratee,
- 'matches': matches,
- 'matchesProperty': matchesProperty,
- 'method': method,
- 'methodOf': methodOf,
- 'mixin': mixin,
- 'noop': noop,
- 'property': property,
- 'propertyOf': propertyOf,
- 'range': range,
- 'times': times,
- 'uniqueId': uniqueId
- };
-});
diff --git a/utility/callback.js b/utility/callback.js
deleted file mode 100644
index a1aeb7a9c..000000000
--- a/utility/callback.js
+++ /dev/null
@@ -1,54 +0,0 @@
-define(['../internal/baseCallback', '../internal/isIterateeCall', '../internal/isObjectLike', './matches'], function(baseCallback, isIterateeCall, isObjectLike, matches) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /**
- * Creates a function that invokes `func` with the `this` binding of `thisArg`
- * and arguments of the created function. If `func` is a property name the
- * created callback returns the property value for a given element. If `func`
- * is an object the created callback returns `true` for elements that contain
- * the equivalent object properties, otherwise it returns `false`.
- *
- * @static
- * @memberOf _
- * @alias iteratee
- * @category Utility
- * @param {*} [func=_.identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
- * @returns {Function} Returns the callback.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36 },
- * { 'user': 'fred', 'age': 40 }
- * ];
- *
- * // wrap to create custom callback shorthands
- * _.callback = _.wrap(_.callback, function(callback, func, thisArg) {
- * var match = /^(.+?)__([gl]t)(.+)$/.exec(func);
- * if (!match) {
- * return callback(func, thisArg);
- * }
- * return function(object) {
- * return match[2] == 'gt'
- * ? object[match[1]] > match[3]
- * : object[match[1]] < match[3];
- * };
- * });
- *
- * _.filter(users, 'age__gt36');
- * // => [{ 'user': 'fred', 'age': 40 }]
- */
- function callback(func, thisArg, guard) {
- if (guard && isIterateeCall(func, thisArg, guard)) {
- thisArg = undefined;
- }
- return isObjectLike(func)
- ? matches(func)
- : baseCallback(func, thisArg);
- }
-
- return callback;
-});
diff --git a/utility/iteratee.js b/utility/iteratee.js
deleted file mode 100644
index 00b214e1f..000000000
--- a/utility/iteratee.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define(["./callback"], function(callback) {
- return callback;
-});
diff --git a/utility/matches.js b/utility/matches.js
deleted file mode 100644
index e3bed477e..000000000
--- a/utility/matches.js
+++ /dev/null
@@ -1,33 +0,0 @@
-define(['../internal/baseClone', '../internal/baseMatches'], function(baseClone, baseMatches) {
-
- /**
- * Creates a function that performs a deep comparison between a given object
- * and `source`, returning `true` if the given object has equivalent property
- * values, else `false`.
- *
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
- * their own, not inherited, enumerable properties. For comparing a single
- * own or inherited property value see `_.matchesProperty`.
- *
- * @static
- * @memberOf _
- * @category Utility
- * @param {Object} source The object of property values to match.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var users = [
- * { 'user': 'barney', 'age': 36, 'active': true },
- * { 'user': 'fred', 'age': 40, 'active': false }
- * ];
- *
- * _.filter(users, _.matches({ 'age': 40, 'active': false }));
- * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
- */
- function matches(source) {
- return baseMatches(baseClone(source, true));
- }
-
- return matches;
-});
diff --git a/utility/mixin.js b/utility/mixin.js
deleted file mode 100644
index 7589357d9..000000000
--- a/utility/mixin.js
+++ /dev/null
@@ -1,78 +0,0 @@
-define(['../internal/arrayCopy', '../internal/arrayPush', '../internal/baseFunctions', '../lang/isFunction', '../lang/isObject', '../object/keys'], function(arrayCopy, arrayPush, baseFunctions, isFunction, isObject, keys) {
-
- /**
- * Adds all own enumerable function properties of a source object to the
- * destination object. If `object` is a function then methods are added to
- * its prototype as well.
- *
- * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
- * avoid conflicts caused by modifying the original.
- *
- * @static
- * @memberOf _
- * @category Utility
- * @param {Function|Object} [object=lodash] The destination object.
- * @param {Object} source The object of functions to add.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.chain=true] Specify whether the functions added
- * are chainable.
- * @returns {Function|Object} Returns `object`.
- * @example
- *
- * function vowels(string) {
- * return _.filter(string, function(v) {
- * return /[aeiou]/i.test(v);
- * });
- * }
- *
- * _.mixin({ 'vowels': vowels });
- * _.vowels('fred');
- * // => ['e']
- *
- * _('fred').vowels().value();
- * // => ['e']
- *
- * _.mixin({ 'vowels': vowels }, { 'chain': false });
- * _('fred').vowels();
- * // => ['e']
- */
- function mixin(object, source, options) {
- var methodNames = baseFunctions(source, keys(source));
-
- var chain = true,
- index = -1,
- isFunc = isFunction(object),
- length = methodNames.length;
-
- if (options === false) {
- chain = false;
- } else if (isObject(options) && 'chain' in options) {
- chain = options.chain;
- }
- while (++index < length) {
- var methodName = methodNames[index],
- func = source[methodName];
-
- object[methodName] = func;
- if (isFunc) {
- object.prototype[methodName] = (function(func) {
- return function() {
- var chainAll = this.__chain__;
- if (chain || chainAll) {
- var result = object(this.__wrapped__),
- actions = result.__actions__ = arrayCopy(this.__actions__);
-
- actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
- result.__chain__ = chainAll;
- return result;
- }
- return func.apply(object, arrayPush([this.value()], arguments));
- };
- }(func));
- }
- }
- return object;
- }
-
- return mixin;
-});
diff --git a/utility/range.js b/utility/range.js
deleted file mode 100644
index 644f2b780..000000000
--- a/utility/range.js
+++ /dev/null
@@ -1,70 +0,0 @@
-define(['../internal/isIterateeCall'], function(isIterateeCall) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeCeil = Math.ceil,
- nativeMax = Math.max;
-
- /**
- * Creates an array of numbers (positive and/or negative) progressing from
- * `start` up to, but not including, `end`. If `end` is not specified it's
- * set to `start` with `start` then set to `0`. If `end` is less than `start`
- * a zero-length range is created unless a negative `step` is specified.
- *
- * @static
- * @memberOf _
- * @category Utility
- * @param {number} [start=0] The start of the range.
- * @param {number} end The end of the range.
- * @param {number} [step=1] The value to increment or decrement by.
- * @returns {Array} Returns the new array of numbers.
- * @example
- *
- * _.range(4);
- * // => [0, 1, 2, 3]
- *
- * _.range(1, 5);
- * // => [1, 2, 3, 4]
- *
- * _.range(0, 20, 5);
- * // => [0, 5, 10, 15]
- *
- * _.range(0, -4, -1);
- * // => [0, -1, -2, -3]
- *
- * _.range(1, 4, 0);
- * // => [1, 1, 1]
- *
- * _.range(0);
- * // => []
- */
- function range(start, end, step) {
- if (step && isIterateeCall(start, end, step)) {
- end = step = undefined;
- }
- start = +start || 0;
- step = step == null ? 1 : (+step || 0);
-
- if (end == null) {
- end = start;
- start = 0;
- } else {
- end = +end || 0;
- }
- // 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(nativeCeil((end - start) / (step || 1)), 0),
- result = Array(length);
-
- while (++index < length) {
- result[index] = start;
- start += step;
- }
- return result;
- }
-
- return range;
-});
diff --git a/utility/times.js b/utility/times.js
deleted file mode 100644
index a2c8f427a..000000000
--- a/utility/times.js
+++ /dev/null
@@ -1,61 +0,0 @@
-define(['../internal/bindCallback', '../internal/root'], function(bindCallback, root) {
-
- /* Native method references for those with the same name as other `lodash` methods. */
- var nativeFloor = Math.floor,
- nativeIsFinite = root.isFinite,
- nativeMin = Math.min;
-
- /** Used as references for the maximum length and index of an array. */
- var MAX_ARRAY_LENGTH = 4294967295;
-
- /**
- * Invokes the iteratee function `n` times, returning an array of the results
- * of each invocation. The `iteratee` is bound to `thisArg` and invoked with
- * one argument; (index).
- *
- * @static
- * @memberOf _
- * @category Utility
- * @param {number} n The number of times to invoke `iteratee`.
- * @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
- * @returns {Array} Returns the array of results.
- * @example
- *
- * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false));
- * // => [3, 6, 4]
- *
- * _.times(3, function(n) {
- * mage.castSpell(n);
- * });
- * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2`
- *
- * _.times(3, function(n) {
- * this.cast(n);
- * }, mage);
- * // => also invokes `mage.castSpell(n)` three times
- */
- function times(n, iteratee, thisArg) {
- n = nativeFloor(n);
-
- // Exit early to avoid a JSC JIT bug in Safari 8
- // where `Array(0)` is treated as `Array(1)`.
- if (n < 1 || !nativeIsFinite(n)) {
- return [];
- }
- var index = -1,
- result = Array(nativeMin(n, MAX_ARRAY_LENGTH));
-
- iteratee = bindCallback(iteratee, thisArg, 1);
- while (++index < n) {
- if (index < MAX_ARRAY_LENGTH) {
- result[index] = iteratee(index);
- } else {
- iteratee(index);
- }
- }
- return result;
- }
-
- return times;
-});
diff --git a/chain/value.js b/value.js
similarity index 100%
rename from chain/value.js
rename to value.js
diff --git a/chain/valueOf.js b/valueOf.js
similarity index 100%
rename from chain/valueOf.js
rename to valueOf.js
diff --git a/object/values.js b/values.js
similarity index 82%
rename from object/values.js
rename to values.js
index dc602b3ae..31c4e21b2 100644
--- a/object/values.js
+++ b/values.js
@@ -1,4 +1,4 @@
-define(['../internal/baseValues', './keys'], function(baseValues, keys) {
+define(['./internal/baseValues', './keys'], function(baseValues, keys) {
/**
* Creates an array of the own enumerable property values of `object`.
@@ -26,7 +26,7 @@ define(['../internal/baseValues', './keys'], function(baseValues, keys) {
* // => ['h', 'i']
*/
function values(object) {
- return baseValues(object, keys(object));
+ return object ? baseValues(object, keys(object)) : [];
}
return values;
diff --git a/object/valuesIn.js b/valuesIn.js
similarity index 77%
rename from object/valuesIn.js
rename to valuesIn.js
index 37c74a455..c3cc7f483 100644
--- a/object/valuesIn.js
+++ b/valuesIn.js
@@ -1,8 +1,7 @@
-define(['../internal/baseValues', './keysIn'], function(baseValues, keysIn) {
+define(['./internal/baseValues', './keysIn'], function(baseValues, keysIn) {
/**
- * Creates an array of the own and inherited enumerable property values
- * of `object`.
+ * Creates an array of the own and inherited enumerable property values of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
@@ -24,7 +23,7 @@ define(['../internal/baseValues', './keysIn'], function(baseValues, keysIn) {
* // => [1, 2, 3] (iteration order is not guaranteed)
*/
function valuesIn(object) {
- return baseValues(object, keysIn(object));
+ return object == null ? baseValues(object, keysIn(object)) : [];
}
return valuesIn;
diff --git a/array/without.js b/without.js
similarity index 71%
rename from array/without.js
rename to without.js
index 8bc4aa52d..0877c143b 100644
--- a/array/without.js
+++ b/without.js
@@ -1,4 +1,4 @@
-define(['../internal/baseDifference', '../internal/isArrayLike', '../function/restParam'], function(baseDifference, isArrayLike, restParam) {
+define(['./internal/baseDifference', './isArrayLikeObject', './rest'], function(baseDifference, isArrayLikeObject, rest) {
/**
* Creates an array excluding all provided values using
@@ -16,8 +16,8 @@ define(['../internal/baseDifference', '../internal/isArrayLike', '../function/re
* _.without([1, 2, 1, 3], 1, 2);
* // => [3]
*/
- var without = restParam(function(array, values) {
- return isArrayLike(array)
+ var without = rest(function(array, values) {
+ return isArrayLikeObject(array)
? baseDifference(array, values)
: [];
});
diff --git a/words.js b/words.js
new file mode 100644
index 000000000..53cc30a8c
--- /dev/null
+++ b/words.js
@@ -0,0 +1,84 @@
+define(['./toString'], function(toString) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used to compose unicode character classes. */
+ var rsAstralRange = '\\ud800-\\udfff',
+ rsDingbatRange = '\\u2700-\\u27bf',
+ rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
+ rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
+ rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
+ rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
+ rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
+ rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
+ rsVarRange = '\\ufe0e\\ufe0f',
+ rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
+
+ /** Used to compose unicode capture groups. */
+ var rsBreak = '[' + rsBreakRange + ']',
+ rsDigits = '\\d+',
+ rsDingbat = '[' + rsDingbatRange + ']',
+ rsLower = '[' + rsLowerRange + ']',
+ rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
+ rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
+ rsNonAstral = '[^' + rsAstralRange + ']',
+ rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+ rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+ rsUpper = '[' + rsUpperRange + ']',
+ rsZWJ = '\\u200d';
+
+ /** Used to compose unicode regexes. */
+ var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
+ rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
+ reOptMod = rsModifier + '?',
+ rsOptVar = '[' + rsVarRange + ']?',
+ rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+ rsSeq = rsOptVar + reOptMod + rsOptJoin,
+ rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq;
+
+ /** Used to match non-compound words composed of alphanumeric characters. */
+ var reBasicWord = /[a-zA-Z0-9]+/g;
+
+ /** Used to match complex or compound words. */
+ var reComplexWord = RegExp([
+ rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
+ rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
+ rsUpper + '?' + rsLowerMisc + '+',
+ rsDigits + '(?:' + rsLowerMisc + '+)?',
+ rsEmoji
+ ].join('|'), 'g');
+
+ /** Used to detect strings that need a more robust regexp to match words. */
+ var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
+
+ /**
+ * Splits `string` into an array of its words.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to inspect.
+ * @param {RegExp|string} [pattern] The pattern to match words.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {Array} Returns the words of `string`.
+ * @example
+ *
+ * _.words('fred, barney, & pebbles');
+ * // => ['fred', 'barney', 'pebbles']
+ *
+ * _.words('fred, barney, & pebbles', /[^, ]+/g);
+ * // => ['fred', 'barney', '&', 'pebbles']
+ */
+ function words(string, pattern, guard) {
+ string = toString(string);
+ pattern = guard ? undefined : pattern;
+
+ if (pattern === undefined) {
+ pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
+ }
+ return string.match(pattern) || [];
+ }
+
+ return words;
+});
diff --git a/function/wrap.js b/wrap.js
similarity index 70%
rename from function/wrap.js
rename to wrap.js
index 8d7156ded..a41df99d3 100644
--- a/function/wrap.js
+++ b/wrap.js
@@ -1,10 +1,4 @@
-define(['../internal/createWrapper', '../utility/identity'], function(createWrapper, identity) {
-
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
- var undefined;
-
- /** Used to compose bitmasks for wrapper metadata. */
- var PARTIAL_FLAG = 32;
+define(['./identity', './partial'], function(identity, partial) {
/**
* Creates a function that provides `value` to the wrapper function as its
@@ -29,7 +23,7 @@ define(['../internal/createWrapper', '../utility/identity'], function(createWrap
*/
function wrap(value, wrapper) {
wrapper = wrapper == null ? identity : wrapper;
- return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);
+ return partial(wrapper, value);
}
return wrap;
diff --git a/wrapperAt.js b/wrapperAt.js
new file mode 100644
index 000000000..49109edf3
--- /dev/null
+++ b/wrapperAt.js
@@ -0,0 +1,46 @@
+define(['./internal/LazyWrapper', './internal/LodashWrapper', './internal/baseAt', './internal/baseFlatten', './internal/isIndex', './rest', './thru'], function(LazyWrapper, LodashWrapper, baseAt, baseFlatten, isIndex, rest, thru) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is the wrapper version of `_.at`.
+ *
+ * @name at
+ * @memberOf _
+ * @category Seq
+ * @param {...(string|string[])} [paths] The property paths of elements to pick,
+ * specified individually or in arrays.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+ *
+ * _(object).at(['a[0].b.c', 'a[1]']).value();
+ * // => [3, 4]
+ *
+ * _(['a', 'b', 'c']).at(0, 2).value();
+ * // => ['a', 'c']
+ */
+ var wrapperAt = rest(function(paths) {
+ paths = baseFlatten(paths);
+ var length = paths.length,
+ start = length ? paths[0] : 0,
+ value = this.__wrapped__,
+ interceptor = function(object) { return baseAt(object, paths); };
+
+ if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) {
+ return this.thru(interceptor);
+ }
+ value = value.slice(start, +start + (length ? 1 : 0));
+ value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
+ return new LodashWrapper(value, this.__chain__).thru(function(array) {
+ if (length && !array.length) {
+ array.push(undefined);
+ }
+ return array;
+ });
+ });
+
+ return wrapperAt;
+});
diff --git a/chain/wrapperChain.js b/wrapperChain.js
similarity index 87%
rename from chain/wrapperChain.js
rename to wrapperChain.js
index 9d6e6fbd0..850507c64 100644
--- a/chain/wrapperChain.js
+++ b/wrapperChain.js
@@ -5,7 +5,7 @@ define(['./chain'], function(chain) {
*
* @name chain
* @memberOf _
- * @category Chain
+ * @category Seq
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
@@ -15,12 +15,13 @@ define(['./chain'], function(chain) {
* ];
*
* // without explicit chaining
- * _(users).first();
+ * _(users).head();
* // => { 'user': 'barney', 'age': 36 }
*
* // with explicit chaining
- * _(users).chain()
- * .first()
+ * _(users)
+ * .chain()
+ * .head()
* .pick('user')
* .value();
* // => { 'user': 'barney' }
diff --git a/wrapperFlatMap.js b/wrapperFlatMap.js
new file mode 100644
index 000000000..3bf19290b
--- /dev/null
+++ b/wrapperFlatMap.js
@@ -0,0 +1,25 @@
+define([], function() {
+
+ /**
+ * This method is the wrapper version of `_.flatMap`.
+ *
+ * @static
+ * @memberOf _
+ * @category Seq
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function duplicate(n) {
+ * return [n, n];
+ * }
+ *
+ * _([1, 2]).flatMap(duplicate).value();
+ * // => [1, 1, 2, 2]
+ */
+ function wrapperFlatMap(iteratee) {
+ return this.map(iteratee).flatten();
+ }
+
+ return wrapperFlatMap;
+});
diff --git a/wrapperLodash.js b/wrapperLodash.js
new file mode 100644
index 000000000..66911d39c
--- /dev/null
+++ b/wrapperLodash.js
@@ -0,0 +1,135 @@
+define(['./internal/LazyWrapper', './internal/LodashWrapper', './internal/baseLodash', './isArray', './isObjectLike', './internal/wrapperClone'], function(LazyWrapper, LodashWrapper, baseLodash, isArray, isObjectLike, wrapperClone) {
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /**
+ * Creates a `lodash` object which wraps `value` to enable implicit method
+ * chaining. Methods that operate on and return arrays, collections, and
+ * functions can be chained together. Methods that retrieve a single value or
+ * may return a primitive value will automatically end the chain sequence and
+ * return the unwrapped value. Otherwise, the value must be unwrapped with
+ * `_#value`.
+ *
+ * Explicit chaining, which must be unwrapped with `_#value` in all cases,
+ * may be enabled using `_.chain`.
+ *
+ * The execution of chained methods is lazy, that is, it's deferred until
+ * `_#value` is implicitly or explicitly called.
+ *
+ * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
+ * fusion is an optimization to merge iteratee calls; this avoids the creation
+ * of intermediate arrays and can greatly reduce the number of iteratee executions.
+ * Sections of a chain sequence qualify for shortcut fusion if the section is
+ * applied to an array of at least two hundred elements and any iteratees
+ * accept only one argument. The heuristic for whether a section qualifies
+ * for shortcut fusion is subject to change.
+ *
+ * Chaining is supported in custom builds as long as the `_#value` method is
+ * directly or indirectly included in the build.
+ *
+ * In addition to lodash methods, wrappers have `Array` and `String` methods.
+ *
+ * The wrapper `Array` methods are:
+ * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
+ *
+ * The wrapper `String` methods are:
+ * `replace` and `split`
+ *
+ * The wrapper methods that support shortcut fusion are:
+ * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
+ * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
+ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
+ *
+ * The chainable wrapper methods are:
+ * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
+ * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
+ * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
+ * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
+ * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
+ * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
+ * `flowRight`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
+ * `forOwnRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
+ * `intersection`, `intersectionBy`, `intersectionWith`, invert`, `invokeMap`,
+ * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`,
+ * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`,
+ * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`,
+ * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`,
+ * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`,
+ * `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`,
+ * `reject`, `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`,
+ * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`,
+ * `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`,
+ * `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`,
+ * `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`,
+ * `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `without`,
+ * `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, and `zipWith`
+ *
+ * The wrapper methods that are **not** chainable by default are:
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
+ * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
+ * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
+ * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `get`, `gt`, `gte`,
+ * `has`, `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`,
+ * `invoke`, `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`,
+ * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
+ * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`,
+ * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
+ * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
+ * `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, `last`,
+ * `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`,
+ * `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, `padEnd`,
+ * `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`,
+ * `result`, `round`, `runInContext`, `sample`, `shift`, `size`, `snakeCase`,
+ * `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`,
+ * `startCase`, `startsWith`, `subtract`, `sum`, sumBy`, `template`, `times`,
+ * `toLower`, `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, toString`,
+ * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
+ * `upperCase`, `upperFirst`, `value`, and `words`
+ *
+ * @name _
+ * @constructor
+ * @category Seq
+ * @param {*} value The value to wrap in a `lodash` instance.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var wrapped = _([1, 2, 3]);
+ *
+ * // returns an unwrapped value
+ * wrapped.reduce(_.add);
+ * // => 6
+ *
+ * // returns a wrapped value
+ * var squares = wrapped.map(square);
+ *
+ * _.isArray(squares);
+ * // => false
+ *
+ * _.isArray(squares.value());
+ * // => true
+ */
+ function lodash(value) {
+ if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
+ if (value instanceof LodashWrapper) {
+ return value;
+ }
+ if (hasOwnProperty.call(value, '__wrapped__')) {
+ return wrapperClone(value);
+ }
+ }
+ return new LodashWrapper(value);
+ }
+
+ // Ensure wrappers are instances of `baseLodash`.
+ lodash.prototype = baseLodash.prototype;
+
+ return lodash;
+});
diff --git a/chain/wrapperReverse.js b/wrapperReverse.js
similarity index 56%
rename from chain/wrapperReverse.js
rename to wrapperReverse.js
index 3ea279ea8..443e8374c 100644
--- a/chain/wrapperReverse.js
+++ b/wrapperReverse.js
@@ -1,18 +1,17 @@
-define(['../internal/LazyWrapper', '../internal/LodashWrapper', './thru'], function(LazyWrapper, LodashWrapper, thru) {
+define(['./internal/LazyWrapper', './internal/LodashWrapper', './reverse', './thru'], function(LazyWrapper, LodashWrapper, reverse, thru) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/**
- * Reverses the wrapped array so the first element becomes the last, the
- * second element becomes the second to last, and so on.
+ * This method is the wrapper version of `_.reverse`.
*
* **Note:** This method mutates the wrapped array.
*
* @name reverse
* @memberOf _
- * @category Chain
- * @returns {Object} Returns the new reversed `lodash` wrapper instance.
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
* var array = [1, 2, 3];
@@ -25,20 +24,16 @@ define(['../internal/LazyWrapper', '../internal/LodashWrapper', './thru'], funct
*/
function wrapperReverse() {
var value = this.__wrapped__;
-
- var interceptor = function(value) {
- return value.reverse();
- };
if (value instanceof LazyWrapper) {
var wrapped = value;
if (this.__actions__.length) {
wrapped = new LazyWrapper(this);
}
wrapped = wrapped.reverse();
- wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
+ wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined });
return new LodashWrapper(wrapped, this.__chain__);
}
- return this.thru(interceptor);
+ return this.thru(reverse);
}
return wrapperReverse;
diff --git a/chain/wrapperValue.js b/wrapperValue.js
similarity index 81%
rename from chain/wrapperValue.js
rename to wrapperValue.js
index 21b4f974d..ab58313f3 100644
--- a/chain/wrapperValue.js
+++ b/wrapperValue.js
@@ -1,4 +1,4 @@
-define(['../internal/baseWrapperValue'], function(baseWrapperValue) {
+define(['./internal/baseWrapperValue'], function(baseWrapperValue) {
/**
* Executes the chained sequence to extract the unwrapped value.
@@ -6,7 +6,7 @@ define(['../internal/baseWrapperValue'], function(baseWrapperValue) {
* @name value
* @memberOf _
* @alias run, toJSON, valueOf
- * @category Chain
+ * @category Seq
* @returns {*} Returns the resolved unwrapped value.
* @example
*
diff --git a/xor.js b/xor.js
new file mode 100644
index 000000000..fb318d3ae
--- /dev/null
+++ b/xor.js
@@ -0,0 +1,22 @@
+define(['./internal/arrayFilter', './internal/baseXor', './isArrayLikeObject', './rest'], function(arrayFilter, baseXor, isArrayLikeObject, rest) {
+
+ /**
+ * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
+ * of the provided arrays.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of values.
+ * @example
+ *
+ * _.xor([2, 1], [4, 2]);
+ * // => [1, 4]
+ */
+ var xor = rest(function(arrays) {
+ return baseXor(arrayFilter(arrays, isArrayLikeObject));
+ });
+
+ return xor;
+});
diff --git a/xorBy.js b/xorBy.js
new file mode 100644
index 000000000..8d0905d09
--- /dev/null
+++ b/xorBy.js
@@ -0,0 +1,35 @@
+define(['./internal/arrayFilter', './internal/baseIteratee', './internal/baseXor', './isArrayLikeObject', './last', './rest'], function(arrayFilter, baseIteratee, baseXor, isArrayLikeObject, last, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.xor` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @returns {Array} Returns the new array of values.
+ * @example
+ *
+ * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+ * // => [1.2, 4.3]
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+ * // => [{ 'x': 2 }]
+ */
+ var xorBy = rest(function(arrays) {
+ var iteratee = last(arrays);
+ if (isArrayLikeObject(iteratee)) {
+ iteratee = undefined;
+ }
+ return baseXor(arrayFilter(arrays, isArrayLikeObject), baseIteratee(iteratee));
+ });
+
+ return xorBy;
+});
diff --git a/xorWith.js b/xorWith.js
new file mode 100644
index 000000000..fce94ca13
--- /dev/null
+++ b/xorWith.js
@@ -0,0 +1,34 @@
+define(['./internal/arrayFilter', './internal/baseXor', './isArrayLikeObject', './last', './rest'], function(arrayFilter, baseXor, isArrayLikeObject, last, rest) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.xor` except that it accepts `comparator` which is
+ * invoked to compare elements of `arrays`. The comparator is invoked with
+ * two arguments: (arrVal, othVal).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @param {Function} [comparator] The comparator invoked per element.
+ * @returns {Array} Returns the new array of values.
+ * @example
+ *
+ * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+ * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+ *
+ * _.xorWith(objects, others, _.isEqual);
+ * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+ */
+ var xorWith = rest(function(arrays) {
+ var comparator = last(arrays);
+ if (isArrayLikeObject(comparator)) {
+ comparator = undefined;
+ }
+ return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
+ });
+
+ return xorWith;
+});
diff --git a/array/zip.js b/zip.js
similarity index 83%
rename from array/zip.js
rename to zip.js
index ef9add3be..212a628bf 100644
--- a/array/zip.js
+++ b/zip.js
@@ -1,4 +1,4 @@
-define(['../function/restParam', './unzip'], function(restParam, unzip) {
+define(['./rest', './unzip'], function(rest, unzip) {
/**
* Creates an array of grouped elements, the first of which contains the first
@@ -15,7 +15,7 @@ define(['../function/restParam', './unzip'], function(restParam, unzip) {
* _.zip(['fred', 'barney'], [30, 40], [true, false]);
* // => [['fred', 30, true], ['barney', 40, false]]
*/
- var zip = restParam(unzip);
+ var zip = rest(unzip);
return zip;
});
diff --git a/zipObject.js b/zipObject.js
new file mode 100644
index 000000000..1dab8293e
--- /dev/null
+++ b/zipObject.js
@@ -0,0 +1,34 @@
+define(['./internal/baseSet'], function(baseSet) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.fromPairs` except that it accepts two arrays,
+ * one of property names and one of corresponding values.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} [props=[]] The property names.
+ * @param {Array} [values=[]] The property values.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * _.zipObject(['fred', 'barney'], [30, 40]);
+ * // => { 'fred': 30, 'barney': 40 }
+ */
+ function zipObject(props, values) {
+ var index = -1,
+ length = props ? props.length : 0,
+ valsLength = values ? values.length : 0,
+ result = {};
+
+ while (++index < length) {
+ baseSet(result, props[index], index < valsLength ? values[index] : undefined);
+ }
+ return result;
+ }
+
+ return zipObject;
+});
diff --git a/zipWith.js b/zipWith.js
new file mode 100644
index 000000000..ee3ab533f
--- /dev/null
+++ b/zipWith.js
@@ -0,0 +1,33 @@
+define(['./rest', './unzipWith'], function(rest, unzipWith) {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /**
+ * This method is like `_.zip` except that it accepts `iteratee` to specify
+ * how grouped values should be combined. The iteratee is invoked with the
+ * elements of each group: (...group).
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to process.
+ * @param {Function} [iteratee=_.identity] The function to combine grouped values.
+ * @returns {Array} Returns the new array of grouped elements.
+ * @example
+ *
+ * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
+ * return a + b + c;
+ * });
+ * // => [111, 222]
+ */
+ var zipWith = rest(function(arrays) {
+ var length = arrays.length,
+ iteratee = length > 1 ? arrays[length - 1] : undefined;
+
+ iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
+ return unzipWith(arrays, iteratee);
+ });
+
+ return zipWith;
+});