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 240120651..ccfaa3d45 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# lodash-es v3.10.1
+# lodash-es v4.0.0
-The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [ES](https://people.mozilla.org/~jorendorff/es6-draft.html) modules.
+The [lodash](https://lodash.com/) library exported as [ES](http://www.ecma-international.org/ecma-262/6.0/) modules.
Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli):
```bash
-$ lodash modularize modern exports=es -o ./
+$ lodash modularize exports=es -o ./
```
-See the [package source](https://github.com/lodash/lodash/tree/3.10.1-es) for more details.
+See the [package source](https://github.com/lodash/lodash/tree/4.0.0-es) for more details.
diff --git a/add.js b/add.js
new file mode 100644
index 000000000..2a6fcb142
--- /dev/null
+++ b/add.js
@@ -0,0 +1,26 @@
+/**
+ * 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;
+}
+
+export default add;
diff --git a/function/after.js b/after.js
similarity index 73%
rename from function/after.js
rename to after.js
index ab87ab206..4878c7b6f 100644
--- a/function/after.js
+++ b/after.js
@@ -1,11 +1,8 @@
-import root from '../internal/root';
+import toInteger from './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 @@ var nativeIsFinite = root.isFinite;
*/
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.default.js b/array.default.js
new file mode 100644
index 000000000..38a07bdc4
--- /dev/null
+++ b/array.default.js
@@ -0,0 +1,77 @@
+import chunk from './chunk';
+import compact from './compact';
+import concat from './concat';
+import difference from './difference';
+import differenceBy from './differenceBy';
+import differenceWith from './differenceWith';
+import drop from './drop';
+import dropRight from './dropRight';
+import dropRightWhile from './dropRightWhile';
+import dropWhile from './dropWhile';
+import fill from './fill';
+import findIndex from './findIndex';
+import findLastIndex from './findLastIndex';
+import flatMap from './flatMap';
+import flatten from './flatten';
+import flattenDeep from './flattenDeep';
+import fromPairs from './fromPairs';
+import head from './head';
+import indexOf from './indexOf';
+import initial from './initial';
+import intersection from './intersection';
+import intersectionBy from './intersectionBy';
+import intersectionWith from './intersectionWith';
+import join from './join';
+import last from './last';
+import lastIndexOf from './lastIndexOf';
+import pull from './pull';
+import pullAll from './pullAll';
+import pullAllBy from './pullAllBy';
+import pullAt from './pullAt';
+import remove from './remove';
+import reverse from './reverse';
+import slice from './slice';
+import sortedIndex from './sortedIndex';
+import sortedIndexBy from './sortedIndexBy';
+import sortedIndexOf from './sortedIndexOf';
+import sortedLastIndex from './sortedLastIndex';
+import sortedLastIndexBy from './sortedLastIndexBy';
+import sortedLastIndexOf from './sortedLastIndexOf';
+import sortedUniq from './sortedUniq';
+import sortedUniqBy from './sortedUniqBy';
+import tail from './tail';
+import take from './take';
+import takeRight from './takeRight';
+import takeRightWhile from './takeRightWhile';
+import takeWhile from './takeWhile';
+import union from './union';
+import unionBy from './unionBy';
+import unionWith from './unionWith';
+import uniq from './uniq';
+import uniqBy from './uniqBy';
+import uniqWith from './uniqWith';
+import unzip from './unzip';
+import unzipWith from './unzipWith';
+import without from './without';
+import xor from './xor';
+import xorBy from './xorBy';
+import xorWith from './xorWith';
+import zip from './zip';
+import zipObject from './zipObject';
+import zipWith from './zipWith';
+
+export default {
+ 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
+};
diff --git a/array.js b/array.js
index b1f14a58d..56cd7d9ab 100644
--- a/array.js
+++ b/array.js
@@ -1,87 +1,62 @@
-import chunk from './array/chunk';
-import compact from './array/compact';
-import difference from './array/difference';
-import drop from './array/drop';
-import dropRight from './array/dropRight';
-import dropRightWhile from './array/dropRightWhile';
-import dropWhile from './array/dropWhile';
-import fill from './array/fill';
-import findIndex from './array/findIndex';
-import findLastIndex from './array/findLastIndex';
-import first from './array/first';
-import flatten from './array/flatten';
-import flattenDeep from './array/flattenDeep';
-import head from './array/head';
-import indexOf from './array/indexOf';
-import initial from './array/initial';
-import intersection from './array/intersection';
-import last from './array/last';
-import lastIndexOf from './array/lastIndexOf';
-import object from './array/object';
-import pull from './array/pull';
-import pullAt from './array/pullAt';
-import remove from './array/remove';
-import rest from './array/rest';
-import slice from './array/slice';
-import sortedIndex from './array/sortedIndex';
-import sortedLastIndex from './array/sortedLastIndex';
-import tail from './array/tail';
-import take from './array/take';
-import takeRight from './array/takeRight';
-import takeRightWhile from './array/takeRightWhile';
-import takeWhile from './array/takeWhile';
-import union from './array/union';
-import uniq from './array/uniq';
-import unique from './array/unique';
-import unzip from './array/unzip';
-import unzipWith from './array/unzipWith';
-import without from './array/without';
-import xor from './array/xor';
-import zip from './array/zip';
-import zipObject from './array/zipObject';
-import zipWith from './array/zipWith';
-
-export default {
- 'chunk': chunk,
- 'compact': compact,
- 'difference': difference,
- 'drop': drop,
- 'dropRight': dropRight,
- 'dropRightWhile': dropRightWhile,
- 'dropWhile': dropWhile,
- 'fill': fill,
- 'findIndex': findIndex,
- 'findLastIndex': findLastIndex,
- 'first': first,
- 'flatten': flatten,
- 'flattenDeep': flattenDeep,
- 'head': head,
- 'indexOf': indexOf,
- 'initial': initial,
- 'intersection': intersection,
- 'last': last,
- 'lastIndexOf': lastIndexOf,
- 'object': object,
- 'pull': pull,
- 'pullAt': pullAt,
- 'remove': remove,
- 'rest': rest,
- 'slice': slice,
- 'sortedIndex': sortedIndex,
- 'sortedLastIndex': sortedLastIndex,
- 'tail': tail,
- 'take': take,
- 'takeRight': takeRight,
- 'takeRightWhile': takeRightWhile,
- 'takeWhile': takeWhile,
- 'union': union,
- 'uniq': uniq,
- 'unique': unique,
- 'unzip': unzip,
- 'unzipWith': unzipWith,
- 'without': without,
- 'xor': xor,
- 'zip': zip,
- 'zipObject': zipObject,
- 'zipWith': zipWith
-};
+export { default as chunk } from './chunk';
+export { default as compact } from './compact';
+export { default as concat } from './concat';
+export { default as difference } from './difference';
+export { default as differenceBy } from './differenceBy';
+export { default as differenceWith } from './differenceWith';
+export { default as drop } from './drop';
+export { default as dropRight } from './dropRight';
+export { default as dropRightWhile } from './dropRightWhile';
+export { default as dropWhile } from './dropWhile';
+export { default as fill } from './fill';
+export { default as findIndex } from './findIndex';
+export { default as findLastIndex } from './findLastIndex';
+export { default as flatMap } from './flatMap';
+export { default as flatten } from './flatten';
+export { default as flattenDeep } from './flattenDeep';
+export { default as fromPairs } from './fromPairs';
+export { default as head } from './head';
+export { default as indexOf } from './indexOf';
+export { default as initial } from './initial';
+export { default as intersection } from './intersection';
+export { default as intersectionBy } from './intersectionBy';
+export { default as intersectionWith } from './intersectionWith';
+export { default as join } from './join';
+export { default as last } from './last';
+export { default as lastIndexOf } from './lastIndexOf';
+export { default as pull } from './pull';
+export { default as pullAll } from './pullAll';
+export { default as pullAllBy } from './pullAllBy';
+export { default as pullAt } from './pullAt';
+export { default as remove } from './remove';
+export { default as reverse } from './reverse';
+export { default as slice } from './slice';
+export { default as sortedIndex } from './sortedIndex';
+export { default as sortedIndexBy } from './sortedIndexBy';
+export { default as sortedIndexOf } from './sortedIndexOf';
+export { default as sortedLastIndex } from './sortedLastIndex';
+export { default as sortedLastIndexBy } from './sortedLastIndexBy';
+export { default as sortedLastIndexOf } from './sortedLastIndexOf';
+export { default as sortedUniq } from './sortedUniq';
+export { default as sortedUniqBy } from './sortedUniqBy';
+export { default as tail } from './tail';
+export { default as take } from './take';
+export { default as takeRight } from './takeRight';
+export { default as takeRightWhile } from './takeRightWhile';
+export { default as takeWhile } from './takeWhile';
+export { default as union } from './union';
+export { default as unionBy } from './unionBy';
+export { default as unionWith } from './unionWith';
+export { default as uniq } from './uniq';
+export { default as uniqBy } from './uniqBy';
+export { default as uniqWith } from './uniqWith';
+export { default as unzip } from './unzip';
+export { default as unzipWith } from './unzipWith';
+export { default as without } from './without';
+export { default as xor } from './xor';
+export { default as xorBy } from './xorBy';
+export { default as xorWith } from './xorWith';
+export { default as zip } from './zip';
+export { default as zipObject } from './zipObject';
+export { default as zipWith } from './zipWith';
+export { default as default } from './array.default';
diff --git a/array/dropRightWhile.js b/array/dropRightWhile.js
deleted file mode 100644
index a3e52158d..000000000
--- a/array/dropRightWhile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import baseCallback from '../internal/baseCallback';
-import baseWhile from '../internal/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)
- : [];
-}
-
-export default dropRightWhile;
diff --git a/array/dropWhile.js b/array/dropWhile.js
deleted file mode 100644
index 289897670..000000000
--- a/array/dropWhile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import baseCallback from '../internal/baseCallback';
-import baseWhile from '../internal/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)
- : [];
-}
-
-export default dropWhile;
diff --git a/array/findIndex.js b/array/findIndex.js
deleted file mode 100644
index 1c42d41f5..000000000
--- a/array/findIndex.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import createFindIndex from '../internal/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();
-
-export default findIndex;
diff --git a/array/findLastIndex.js b/array/findLastIndex.js
deleted file mode 100644
index a34e60821..000000000
--- a/array/findLastIndex.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import createFindIndex from '../internal/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);
-
-export default findLastIndex;
diff --git a/array/flatten.js b/array/flatten.js
deleted file mode 100644
index 813e1afd2..000000000
--- a/array/flatten.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import baseFlatten from '../internal/baseFlatten';
-import isIterateeCall from '../internal/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) : [];
-}
-
-export default flatten;
diff --git a/array/head.js b/array/head.js
deleted file mode 100644
index d29f16904..000000000
--- a/array/head.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import first from './first'
-export default first;
diff --git a/array/intersection.js b/array/intersection.js
deleted file mode 100644
index 9c883ecb0..000000000
--- a/array/intersection.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import baseIndexOf from '../internal/baseIndexOf';
-import cacheIndexOf from '../internal/cacheIndexOf';
-import createCache from '../internal/createCache';
-import isArrayLike from '../internal/isArrayLike';
-import restParam from '../function/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;
-});
-
-export default intersection;
diff --git a/array/object.js b/array/object.js
deleted file mode 100644
index ac9db159c..000000000
--- a/array/object.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import zipObject from './zipObject'
-export default zipObject;
diff --git a/array/pull.js b/array/pull.js
deleted file mode 100644
index bbb8a1a11..000000000
--- a/array/pull.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import baseIndexOf from '../internal/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;
-}
-
-export default pull;
diff --git a/array/pullAt.js b/array/pullAt.js
deleted file mode 100644
index 92ee3553b..000000000
--- a/array/pullAt.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import baseAt from '../internal/baseAt';
-import baseCompareAscending from '../internal/baseCompareAscending';
-import baseFlatten from '../internal/baseFlatten';
-import basePullAt from '../internal/basePullAt';
-import restParam from '../function/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;
-});
-
-export default pullAt;
diff --git a/array/sortedIndex.js b/array/sortedIndex.js
deleted file mode 100644
index 720ed633e..000000000
--- a/array/sortedIndex.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import createSortedIndex from '../internal/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();
-
-export default sortedIndex;
diff --git a/array/tail.js b/array/tail.js
deleted file mode 100644
index 450e81b13..000000000
--- a/array/tail.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import rest from './rest'
-export default rest;
diff --git a/array/takeRightWhile.js b/array/takeRightWhile.js
deleted file mode 100644
index 1c29ef73e..000000000
--- a/array/takeRightWhile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import baseCallback from '../internal/baseCallback';
-import baseWhile from '../internal/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)
- : [];
-}
-
-export default takeRightWhile;
diff --git a/array/takeWhile.js b/array/takeWhile.js
deleted file mode 100644
index f87169190..000000000
--- a/array/takeWhile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import baseCallback from '../internal/baseCallback';
-import baseWhile from '../internal/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))
- : [];
-}
-
-export default takeWhile;
diff --git a/array/uniq.js b/array/uniq.js
deleted file mode 100644
index 2975e023b..000000000
--- a/array/uniq.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import baseCallback from '../internal/baseCallback';
-import baseUniq from '../internal/baseUniq';
-import isIterateeCall from '../internal/isIterateeCall';
-import sortedUniq from '../internal/sortedUniq';
-
-/**
- * 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);
-}
-
-export default uniq;
diff --git a/array/unique.js b/array/unique.js
deleted file mode 100644
index bca50d3cd..000000000
--- a/array/unique.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import uniq from './uniq'
-export default uniq;
diff --git a/array/unzipWith.js b/array/unzipWith.js
deleted file mode 100644
index 3c623a764..000000000
--- a/array/unzipWith.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import arrayMap from '../internal/arrayMap';
-import arrayReduce from '../internal/arrayReduce';
-import bindCallback from '../internal/bindCallback';
-import unzip from './unzip';
-
-/**
- * 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);
- });
-}
-
-export default unzipWith;
diff --git a/array/xor.js b/array/xor.js
deleted file mode 100644
index e1fdf86fe..000000000
--- a/array/xor.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import arrayPush from '../internal/arrayPush';
-import baseDifference from '../internal/baseDifference';
-import baseUniq from '../internal/baseUniq';
-import isArrayLike from '../internal/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) : [];
-}
-
-export default xor;
diff --git a/array/zipObject.js b/array/zipObject.js
deleted file mode 100644
index 619d4984a..000000000
--- a/array/zipObject.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import isArray from '../lang/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;
-}
-
-export default zipObject;
diff --git a/array/zipWith.js b/array/zipWith.js
deleted file mode 100644
index 3823c7cca..000000000
--- a/array/zipWith.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import restParam from '../function/restParam';
-import unzipWith from './unzipWith';
-
-/**
- * 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);
-});
-
-export default zipWith;
diff --git a/function/ary.js b/ary.js
similarity index 51%
rename from function/ary.js
rename to ary.js
index f0f7ef209..092d31797 100644
--- a/function/ary.js
+++ b/ary.js
@@ -1,14 +1,10 @@
-import createWrapper from '../internal/createWrapper';
-import isIterateeCall from '../internal/isIterateeCall';
+import createWrapper from './internal/createWrapper';
/** 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
@@ -16,7 +12,7 @@ var nativeMax = Math.max;
* @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
*
@@ -24,10 +20,8 @@ var nativeMax = Math.max;
* // => [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..6d7af5ede
--- /dev/null
+++ b/assign.js
@@ -0,0 +1,39 @@
+import copyObject from './internal/copyObject';
+import createAssigner from './internal/createAssigner';
+import keys from './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);
+});
+
+export default assign;
diff --git a/assignIn.js b/assignIn.js
new file mode 100644
index 000000000..a0ead9eda
--- /dev/null
+++ b/assignIn.js
@@ -0,0 +1,38 @@
+import copyObject from './internal/copyObject';
+import createAssigner from './internal/createAssigner';
+import keysIn from './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);
+});
+
+export default assignIn;
diff --git a/assignInWith.js b/assignInWith.js
new file mode 100644
index 000000000..b477a655c
--- /dev/null
+++ b/assignInWith.js
@@ -0,0 +1,36 @@
+import copyObjectWith from './internal/copyObjectWith';
+import createAssigner from './internal/createAssigner';
+import keysIn from './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);
+});
+
+export default assignInWith;
diff --git a/assignWith.js b/assignWith.js
new file mode 100644
index 000000000..410a641c7
--- /dev/null
+++ b/assignWith.js
@@ -0,0 +1,35 @@
+import copyObjectWith from './internal/copyObjectWith';
+import createAssigner from './internal/createAssigner';
+import keys from './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);
+});
+
+export default assignWith;
diff --git a/at.js b/at.js
new file mode 100644
index 000000000..686d950d7
--- /dev/null
+++ b/at.js
@@ -0,0 +1,29 @@
+import baseAt from './internal/baseAt';
+import baseFlatten from './internal/baseFlatten';
+import rest from './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));
+});
+
+export default at;
diff --git a/utility/attempt.js b/attempt.js
similarity index 74%
rename from utility/attempt.js
rename to attempt.js
index 022dc5675..4ff7bd591 100644
--- a/utility/attempt.js
+++ b/attempt.js
@@ -1,5 +1,6 @@
-import isError from '../lang/isError';
-import restParam from '../function/restParam';
+import apply from './internal/apply';
+import isError from './isError';
+import rest from './rest';
/**
* Attempts to invoke `func`, returning either the result or the caught error
@@ -7,7 +8,7 @@ import restParam from '../function/restParam';
*
* @static
* @memberOf _
- * @category Utility
+ * @category Util
* @param {Function} func The function to attempt.
* @returns {*} Returns the `func` result or error object.
* @example
@@ -21,10 +22,10 @@ import restParam from '../function/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 cc830d056..39ace0f53 100644
--- a/function/before.js
+++ b/before.js
@@ -1,3 +1,5 @@
+import toInteger from './toInteger';
+
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -14,20 +16,15 @@ var FUNC_ERROR_TEXT = 'Expected a 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 79%
rename from function/bind.js
rename to bind.js
index fe0adb9e8..157a8ec74 100644
--- a/function/bind.js
+++ b/bind.js
@@ -1,6 +1,6 @@
-import createWrapper from '../internal/createWrapper';
-import replaceHolders from '../internal/replaceHolders';
-import restParam from './restParam';
+import createWrapper from './internal/createWrapper';
+import replaceHolders from './internal/replaceHolders';
+import rest from './rest';
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -14,7 +14,7 @@ var BIND_FLAG = 1,
* 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
@@ -41,7 +41,7 @@ var BIND_FLAG = 1,
* 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);
@@ -50,7 +50,4 @@ var bind = restParam(function(func, thisArg, partials) {
return createWrapper(func, bitmask, thisArg, partials, holders);
});
-// Assign default placeholders.
-bind.placeholder = {};
-
export default bind;
diff --git a/bindAll.js b/bindAll.js
new file mode 100644
index 000000000..eb5229dc3
--- /dev/null
+++ b/bindAll.js
@@ -0,0 +1,39 @@
+import arrayEach from './internal/arrayEach';
+import baseFlatten from './internal/baseFlatten';
+import bind from './bind';
+import rest from './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;
+});
+
+export default bindAll;
diff --git a/function/bindKey.js b/bindKey.js
similarity index 83%
rename from function/bindKey.js
rename to bindKey.js
index 20c6a4441..3af317bf5 100644
--- a/function/bindKey.js
+++ b/bindKey.js
@@ -1,6 +1,6 @@
-import createWrapper from '../internal/createWrapper';
-import replaceHolders from '../internal/replaceHolders';
-import restParam from './restParam';
+import createWrapper from './internal/createWrapper';
+import replaceHolders from './internal/replaceHolders';
+import rest from './rest';
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -22,7 +22,7 @@ var BIND_FLAG = 1,
* @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.
@@ -51,7 +51,7 @@ var BIND_FLAG = 1,
* 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);
@@ -60,7 +60,4 @@ var bindKey = restParam(function(object, key, partials) {
return createWrapper(key, bitmask, object, partials, holders);
});
-// Assign default placeholders.
-bindKey.placeholder = {};
-
export default bindKey;
diff --git a/string/camelCase.js b/camelCase.js
similarity index 77%
rename from string/camelCase.js
rename to camelCase.js
index e1ff211dc..ca3c15f0d 100644
--- a/string/camelCase.js
+++ b/camelCase.js
@@ -1,4 +1,5 @@
-import createCompounder from '../internal/createCompounder';
+import capitalize from './capitalize';
+import createCompounder from './internal/createCompounder';
/**
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
@@ -21,7 +22,7 @@ import createCompounder from '../internal/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);
});
export default camelCase;
diff --git a/string/capitalize.js b/capitalize.js
similarity index 51%
rename from string/capitalize.js
rename to capitalize.js
index 307f66324..828dcc6da 100644
--- a/string/capitalize.js
+++ b/capitalize.js
@@ -1,7 +1,9 @@
-import baseToString from '../internal/baseToString';
+import toString from './toString';
+import upperFirst from './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 +12,11 @@ import baseToString from '../internal/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());
}
export default capitalize;
diff --git a/math/ceil.js b/ceil.js
similarity index 69%
rename from math/ceil.js
rename to ceil.js
index 7ffa2b423..8a0ff4afd 100644
--- a/math/ceil.js
+++ b/ceil.js
@@ -1,12 +1,12 @@
-import createRound from '../internal/createRound';
+import createRound from './internal/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 e029e2b8f..7d4ae2de6 100644
--- a/chain.js
+++ b/chain.js
@@ -1,31 +1,36 @@
-import chain from './chain/chain';
-import commit from './chain/commit';
-import concat from './chain/concat';
-import lodash from './chain/lodash';
-import plant from './chain/plant';
-import reverse from './chain/reverse';
-import run from './chain/run';
-import tap from './chain/tap';
-import thru from './chain/thru';
-import toJSON from './chain/toJSON';
-import toString from './chain/toString';
-import value from './chain/value';
-import valueOf from './chain/valueOf';
-import wrapperChain from './chain/wrapperChain';
+import lodash from './wrapperLodash';
-export default {
- '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
-};
+/**
+ * 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;
+}
+
+export default chain;
diff --git a/chain/chain.js b/chain/chain.js
deleted file mode 100644
index 03b9999c9..000000000
--- a/chain/chain.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import lodash from './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;
-}
-
-export default chain;
diff --git a/chain/commit.js b/chain/commit.js
deleted file mode 100644
index 3a1110c5a..000000000
--- a/chain/commit.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperCommit from './wrapperCommit'
-export default wrapperCommit;
diff --git a/chain/concat.js b/chain/concat.js
deleted file mode 100644
index 2fabc0707..000000000
--- a/chain/concat.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperConcat from './wrapperConcat'
-export default wrapperConcat;
diff --git a/chain/lodash.js b/chain/lodash.js
deleted file mode 100644
index 958e64f85..000000000
--- a/chain/lodash.js
+++ /dev/null
@@ -1,125 +0,0 @@
-import LazyWrapper from '../internal/LazyWrapper';
-import LodashWrapper from '../internal/LodashWrapper';
-import baseLodash from '../internal/baseLodash';
-import isArray from '../lang/isArray';
-import isObjectLike from '../internal/isObjectLike';
-import wrapperClone from '../internal/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;
-
-export default lodash;
diff --git a/chain/plant.js b/chain/plant.js
deleted file mode 100644
index 6ccd45ee5..000000000
--- a/chain/plant.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperPlant from './wrapperPlant'
-export default wrapperPlant;
diff --git a/chain/reverse.js b/chain/reverse.js
deleted file mode 100644
index 5602fa286..000000000
--- a/chain/reverse.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperReverse from './wrapperReverse'
-export default wrapperReverse;
diff --git a/chain/run.js b/chain/run.js
deleted file mode 100644
index 59ae6ce2a..000000000
--- a/chain/run.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperValue from './wrapperValue'
-export default wrapperValue;
diff --git a/chain/toJSON.js b/chain/toJSON.js
deleted file mode 100644
index 59ae6ce2a..000000000
--- a/chain/toJSON.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperValue from './wrapperValue'
-export default wrapperValue;
diff --git a/chain/toString.js b/chain/toString.js
deleted file mode 100644
index 2600cac23..000000000
--- a/chain/toString.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperToString from './wrapperToString'
-export default wrapperToString;
diff --git a/chain/value.js b/chain/value.js
deleted file mode 100644
index 59ae6ce2a..000000000
--- a/chain/value.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperValue from './wrapperValue'
-export default wrapperValue;
diff --git a/chain/valueOf.js b/chain/valueOf.js
deleted file mode 100644
index 59ae6ce2a..000000000
--- a/chain/valueOf.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import wrapperValue from './wrapperValue'
-export default wrapperValue;
diff --git a/chain/wrapperConcat.js b/chain/wrapperConcat.js
deleted file mode 100644
index 944e2c96f..000000000
--- a/chain/wrapperConcat.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import arrayConcat from '../internal/arrayConcat';
-import baseFlatten from '../internal/baseFlatten';
-import isArray from '../lang/isArray';
-import restParam from '../function/restParam';
-import toObject from '../internal/toObject';
-
-/**
- * Creates a new array joining a wrapped array with any additional arrays
- * and/or values.
- *
- * @name concat
- * @memberOf _
- * @category Chain
- * @param {...*} [values] The values to concatenate.
- * @returns {Array} Returns the new concatenated array.
- * @example
- *
- * var array = [1];
- * var wrapped = _(array).concat(2, [3], [[4]]);
- *
- * console.log(wrapped.value());
- * // => [1, 2, 3, [4]]
- *
- * console.log(array);
- * // => [1]
- */
-var wrapperConcat = restParam(function(values) {
- values = baseFlatten(values);
- return this.thru(function(array) {
- return arrayConcat(isArray(array) ? array : [toObject(array)], values);
- });
-});
-
-export default wrapperConcat;
diff --git a/chain/wrapperToString.js b/chain/wrapperToString.js
deleted file mode 100644
index 21f6db4a5..000000000
--- a/chain/wrapperToString.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * 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() + '');
-}
-
-export default wrapperToString;
diff --git a/array/chunk.js b/chunk.js
similarity index 51%
rename from array/chunk.js
rename to chunk.js
index 3bde8716f..698ddc165 100644
--- a/array/chunk.js
+++ b/chunk.js
@@ -1,22 +1,20 @@
-import baseSlice from '../internal/baseSlice';
-import isIterateeCall from '../internal/isIterateeCall';
+import baseSlice from './internal/baseSlice';
+import toInteger from './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
*
@@ -26,14 +24,14 @@ var nativeCeil = Math.ceil,
* _.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..59c63d30e
--- /dev/null
+++ b/clamp.js
@@ -0,0 +1,38 @@
+import baseClamp from './internal/baseClamp';
+import toNumber from './toNumber';
+
+/**
+ * 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);
+}
+
+export default clamp;
diff --git a/clone.js b/clone.js
new file mode 100644
index 000000000..4bbda5540
--- /dev/null
+++ b/clone.js
@@ -0,0 +1,31 @@
+import baseClone from './internal/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);
+}
+
+export default clone;
diff --git a/cloneDeep.js b/cloneDeep.js
new file mode 100644
index 000000000..7bfd3eb48
--- /dev/null
+++ b/cloneDeep.js
@@ -0,0 +1,23 @@
+import baseClone from './internal/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);
+}
+
+export default cloneDeep;
diff --git a/cloneDeepWith.js b/cloneDeepWith.js
new file mode 100644
index 000000000..dce45adf1
--- /dev/null
+++ b/cloneDeepWith.js
@@ -0,0 +1,33 @@
+import baseClone from './internal/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);
+}
+
+export default cloneDeepWith;
diff --git a/cloneWith.js b/cloneWith.js
new file mode 100644
index 000000000..628579923
--- /dev/null
+++ b/cloneWith.js
@@ -0,0 +1,36 @@
+import baseClone from './internal/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);
+}
+
+export default cloneWith;
diff --git a/collection.default.js b/collection.default.js
new file mode 100644
index 000000000..6b5cec830
--- /dev/null
+++ b/collection.default.js
@@ -0,0 +1,35 @@
+import at from './at';
+import countBy from './countBy';
+import each from './each';
+import eachRight from './eachRight';
+import every from './every';
+import filter from './filter';
+import find from './find';
+import findLast from './findLast';
+import forEach from './forEach';
+import forEachRight from './forEachRight';
+import groupBy from './groupBy';
+import includes from './includes';
+import invokeMap from './invokeMap';
+import keyBy from './keyBy';
+import map from './map';
+import orderBy from './orderBy';
+import partition from './partition';
+import reduce from './reduce';
+import reduceRight from './reduceRight';
+import reject from './reject';
+import sample from './sample';
+import sampleSize from './sampleSize';
+import shuffle from './shuffle';
+import size from './size';
+import some from './some';
+import sortBy from './sortBy';
+
+export default {
+ 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
+};
diff --git a/collection.js b/collection.js
index d1a94a5cb..8dad26274 100644
--- a/collection.js
+++ b/collection.js
@@ -1,87 +1,27 @@
-import all from './collection/all';
-import any from './collection/any';
-import at from './collection/at';
-import collect from './collection/collect';
-import contains from './collection/contains';
-import countBy from './collection/countBy';
-import detect from './collection/detect';
-import each from './collection/each';
-import eachRight from './collection/eachRight';
-import every from './collection/every';
-import filter from './collection/filter';
-import find from './collection/find';
-import findLast from './collection/findLast';
-import findWhere from './collection/findWhere';
-import foldl from './collection/foldl';
-import foldr from './collection/foldr';
-import forEach from './collection/forEach';
-import forEachRight from './collection/forEachRight';
-import groupBy from './collection/groupBy';
-import include from './collection/include';
-import includes from './collection/includes';
-import indexBy from './collection/indexBy';
-import inject from './collection/inject';
-import invoke from './collection/invoke';
-import map from './collection/map';
-import max from './math/max';
-import min from './math/min';
-import partition from './collection/partition';
-import pluck from './collection/pluck';
-import reduce from './collection/reduce';
-import reduceRight from './collection/reduceRight';
-import reject from './collection/reject';
-import sample from './collection/sample';
-import select from './collection/select';
-import shuffle from './collection/shuffle';
-import size from './collection/size';
-import some from './collection/some';
-import sortBy from './collection/sortBy';
-import sortByAll from './collection/sortByAll';
-import sortByOrder from './collection/sortByOrder';
-import sum from './math/sum';
-import where from './collection/where';
-
-export default {
- '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,
- 'map': map,
- 'max': max,
- 'min': min,
- 'partition': partition,
- 'pluck': pluck,
- 'reduce': reduce,
- 'reduceRight': reduceRight,
- 'reject': reject,
- 'sample': sample,
- 'select': select,
- 'shuffle': shuffle,
- 'size': size,
- 'some': some,
- 'sortBy': sortBy,
- 'sortByAll': sortByAll,
- 'sortByOrder': sortByOrder,
- 'sum': sum,
- 'where': where
-};
+export { default as at } from './at';
+export { default as countBy } from './countBy';
+export { default as each } from './each';
+export { default as eachRight } from './eachRight';
+export { default as every } from './every';
+export { default as filter } from './filter';
+export { default as find } from './find';
+export { default as findLast } from './findLast';
+export { default as forEach } from './forEach';
+export { default as forEachRight } from './forEachRight';
+export { default as groupBy } from './groupBy';
+export { default as includes } from './includes';
+export { default as invokeMap } from './invokeMap';
+export { default as keyBy } from './keyBy';
+export { default as map } from './map';
+export { default as orderBy } from './orderBy';
+export { default as partition } from './partition';
+export { default as reduce } from './reduce';
+export { default as reduceRight } from './reduceRight';
+export { default as reject } from './reject';
+export { default as sample } from './sample';
+export { default as sampleSize } from './sampleSize';
+export { default as shuffle } from './shuffle';
+export { default as size } from './size';
+export { default as some } from './some';
+export { default as sortBy } from './sortBy';
+export { default as default } from './collection.default';
diff --git a/collection/all.js b/collection/all.js
deleted file mode 100644
index 723b5f8e5..000000000
--- a/collection/all.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import every from './every'
-export default every;
diff --git a/collection/any.js b/collection/any.js
deleted file mode 100644
index 2da88029b..000000000
--- a/collection/any.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import some from './some'
-export default some;
diff --git a/collection/at.js b/collection/at.js
deleted file mode 100644
index a0135c59e..000000000
--- a/collection/at.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import baseAt from '../internal/baseAt';
-import baseFlatten from '../internal/baseFlatten';
-import restParam from '../function/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));
-});
-
-export default at;
diff --git a/collection/collect.js b/collection/collect.js
deleted file mode 100644
index 982f50a4c..000000000
--- a/collection/collect.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import map from './map'
-export default map;
diff --git a/collection/contains.js b/collection/contains.js
deleted file mode 100644
index a1520e467..000000000
--- a/collection/contains.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import includes from './includes'
-export default includes;
diff --git a/collection/countBy.js b/collection/countBy.js
deleted file mode 100644
index 3f5253a5c..000000000
--- a/collection/countBy.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import createAggregator from '../internal/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);
-});
-
-export default countBy;
diff --git a/collection/detect.js b/collection/detect.js
deleted file mode 100644
index 3496fdc3e..000000000
--- a/collection/detect.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import find from './find'
-export default find;
diff --git a/collection/each.js b/collection/each.js
deleted file mode 100644
index 182b7b709..000000000
--- a/collection/each.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import forEach from './forEach'
-export default forEach;
diff --git a/collection/eachRight.js b/collection/eachRight.js
deleted file mode 100644
index 24047ca09..000000000
--- a/collection/eachRight.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import forEachRight from './forEachRight'
-export default forEachRight;
diff --git a/collection/every.js b/collection/every.js
deleted file mode 100644
index 9d48de9af..000000000
--- a/collection/every.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import arrayEvery from '../internal/arrayEvery';
-import baseCallback from '../internal/baseCallback';
-import baseEvery from '../internal/baseEvery';
-import isArray from '../lang/isArray';
-import isIterateeCall from '../internal/isIterateeCall';
-
-/**
- * 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);
-}
-
-export default every;
diff --git a/collection/filter.js b/collection/filter.js
deleted file mode 100644
index 2d90dbb1c..000000000
--- a/collection/filter.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import arrayFilter from '../internal/arrayFilter';
-import baseCallback from '../internal/baseCallback';
-import baseFilter from '../internal/baseFilter';
-import isArray from '../lang/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);
-}
-
-export default filter;
diff --git a/collection/find.js b/collection/find.js
deleted file mode 100644
index 66df162e7..000000000
--- a/collection/find.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import baseEach from '../internal/baseEach';
-import createFind from '../internal/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);
-
-export default find;
diff --git a/collection/findLast.js b/collection/findLast.js
deleted file mode 100644
index 1fc980e71..000000000
--- a/collection/findLast.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import baseEachRight from '../internal/baseEachRight';
-import createFind from '../internal/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);
-
-export default findLast;
diff --git a/collection/findWhere.js b/collection/findWhere.js
deleted file mode 100644
index ac4b6bde9..000000000
--- a/collection/findWhere.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import baseMatches from '../internal/baseMatches';
-import find from './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));
-}
-
-export default findWhere;
diff --git a/collection/foldl.js b/collection/foldl.js
deleted file mode 100644
index 83cfab772..000000000
--- a/collection/foldl.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import reduce from './reduce'
-export default reduce;
diff --git a/collection/foldr.js b/collection/foldr.js
deleted file mode 100644
index cbd7db3fa..000000000
--- a/collection/foldr.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import reduceRight from './reduceRight'
-export default reduceRight;
diff --git a/collection/forEach.js b/collection/forEach.js
deleted file mode 100644
index 8202a9ac2..000000000
--- a/collection/forEach.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import arrayEach from '../internal/arrayEach';
-import baseEach from '../internal/baseEach';
-import createForEach from '../internal/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);
-
-export default forEach;
diff --git a/collection/forEachRight.js b/collection/forEachRight.js
deleted file mode 100644
index 896b00a1b..000000000
--- a/collection/forEachRight.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import arrayEachRight from '../internal/arrayEachRight';
-import baseEachRight from '../internal/baseEachRight';
-import createForEach from '../internal/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);
-
-export default forEachRight;
diff --git a/collection/groupBy.js b/collection/groupBy.js
deleted file mode 100644
index 9cc51a745..000000000
--- a/collection/groupBy.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import createAggregator from '../internal/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];
- }
-});
-
-export default groupBy;
diff --git a/collection/include.js b/collection/include.js
deleted file mode 100644
index a1520e467..000000000
--- a/collection/include.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import includes from './includes'
-export default includes;
diff --git a/collection/includes.js b/collection/includes.js
deleted file mode 100644
index e72e35e8d..000000000
--- a/collection/includes.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import baseIndexOf from '../internal/baseIndexOf';
-import getLength from '../internal/getLength';
-import isArray from '../lang/isArray';
-import isIterateeCall from '../internal/isIterateeCall';
-import isLength from '../internal/isLength';
-import isString from '../lang/isString';
-import values from '../object/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);
-}
-
-export default includes;
diff --git a/collection/indexBy.js b/collection/indexBy.js
deleted file mode 100644
index c848586b5..000000000
--- a/collection/indexBy.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import createAggregator from '../internal/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;
-});
-
-export default indexBy;
diff --git a/collection/inject.js b/collection/inject.js
deleted file mode 100644
index 83cfab772..000000000
--- a/collection/inject.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import reduce from './reduce'
-export default reduce;
diff --git a/collection/map.js b/collection/map.js
deleted file mode 100644
index fb4bc37ff..000000000
--- a/collection/map.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import arrayMap from '../internal/arrayMap';
-import baseCallback from '../internal/baseCallback';
-import baseMap from '../internal/baseMap';
-import isArray from '../lang/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);
-}
-
-export default map;
diff --git a/collection/max.js b/collection/max.js
deleted file mode 100644
index 29b9656bb..000000000
--- a/collection/max.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import max from '../math/max'
-export default max;
diff --git a/collection/min.js b/collection/min.js
deleted file mode 100644
index 9c8a91efd..000000000
--- a/collection/min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import min from '../math/min'
-export default min;
diff --git a/collection/partition.js b/collection/partition.js
deleted file mode 100644
index df7438246..000000000
--- a/collection/partition.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import createAggregator from '../internal/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 [[], []]; });
-
-export default partition;
diff --git a/collection/pluck.js b/collection/pluck.js
deleted file mode 100644
index ffc64c861..000000000
--- a/collection/pluck.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import map from './map';
-import property from '../utility/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));
-}
-
-export default pluck;
diff --git a/collection/reduce.js b/collection/reduce.js
deleted file mode 100644
index 86d53b603..000000000
--- a/collection/reduce.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import arrayReduce from '../internal/arrayReduce';
-import baseEach from '../internal/baseEach';
-import createReduce from '../internal/createReduce';
-
-/**
- * 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:
- * (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`
- *
- * @static
- * @memberOf _
- * @alias foldl, inject
- * @category Collection
- * @param {Array|Object|string} 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;
- * });
- * // => 3
- *
- * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) {
- * result[key] = n * 3;
- * return result;
- * }, {});
- * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)
- */
-var reduce = createReduce(arrayReduce, baseEach);
-
-export default reduce;
diff --git a/collection/reduceRight.js b/collection/reduceRight.js
deleted file mode 100644
index df78324f1..000000000
--- a/collection/reduceRight.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import arrayReduceRight from '../internal/arrayReduceRight';
-import baseEachRight from '../internal/baseEachRight';
-import createReduce from '../internal/createReduce';
-
-/**
- * This method is like `_.reduce` except that it iterates over elements of
- * `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias foldr
- * @category Collection
- * @param {Array|Object|string} 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
- *
- * var array = [[0, 1], [2, 3], [4, 5]];
- *
- * _.reduceRight(array, function(flattened, other) {
- * return flattened.concat(other);
- * }, []);
- * // => [4, 5, 2, 3, 0, 1]
- */
-var reduceRight = createReduce(arrayReduceRight, baseEachRight);
-
-export default reduceRight;
diff --git a/collection/reject.js b/collection/reject.js
deleted file mode 100644
index 2eba4273d..000000000
--- a/collection/reject.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import arrayFilter from '../internal/arrayFilter';
-import baseCallback from '../internal/baseCallback';
-import baseFilter from '../internal/baseFilter';
-import isArray from '../lang/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);
- });
-}
-
-export default reject;
diff --git a/collection/sample.js b/collection/sample.js
deleted file mode 100644
index f18dccd69..000000000
--- a/collection/sample.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import baseRandom from '../internal/baseRandom';
-import isIterateeCall from '../internal/isIterateeCall';
-import toArray from '../lang/toArray';
-import toIterable from '../internal/toIterable';
-
-/* 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;
-}
-
-export default sample;
diff --git a/collection/select.js b/collection/select.js
deleted file mode 100644
index ccc6e071f..000000000
--- a/collection/select.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import filter from './filter'
-export default filter;
diff --git a/collection/size.js b/collection/size.js
deleted file mode 100644
index cb386c7c0..000000000
--- a/collection/size.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import getLength from '../internal/getLength';
-import isLength from '../internal/isLength';
-import keys from '../object/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;
-}
-
-export default size;
diff --git a/collection/some.js b/collection/some.js
deleted file mode 100644
index 6cf382a53..000000000
--- a/collection/some.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import arraySome from '../internal/arraySome';
-import baseCallback from '../internal/baseCallback';
-import baseSome from '../internal/baseSome';
-import isArray from '../lang/isArray';
-import isIterateeCall from '../internal/isIterateeCall';
-
-/**
- * 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);
-}
-
-export default some;
diff --git a/collection/sortBy.js b/collection/sortBy.js
deleted file mode 100644
index 717f03851..000000000
--- a/collection/sortBy.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import baseCallback from '../internal/baseCallback';
-import baseMap from '../internal/baseMap';
-import baseSortBy from '../internal/baseSortBy';
-import compareAscending from '../internal/compareAscending';
-import isIterateeCall from '../internal/isIterateeCall';
-
-/**
- * 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);
-}
-
-export default sortBy;
diff --git a/collection/sortByAll.js b/collection/sortByAll.js
deleted file mode 100644
index 49bb71141..000000000
--- a/collection/sortByAll.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import baseFlatten from '../internal/baseFlatten';
-import baseSortByOrder from '../internal/baseSortByOrder';
-import isIterateeCall from '../internal/isIterateeCall';
-import restParam from '../function/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), []);
-});
-
-export default sortByAll;
diff --git a/collection/sortByOrder.js b/collection/sortByOrder.js
deleted file mode 100644
index ac30330f5..000000000
--- a/collection/sortByOrder.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import baseSortByOrder from '../internal/baseSortByOrder';
-import isArray from '../lang/isArray';
-import isIterateeCall from '../internal/isIterateeCall';
-
-/**
- * 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);
-}
-
-export default sortByOrder;
diff --git a/collection/sum.js b/collection/sum.js
deleted file mode 100644
index f4ad00270..000000000
--- a/collection/sum.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import sum from '../math/sum'
-export default sum;
diff --git a/collection/where.js b/collection/where.js
deleted file mode 100644
index f0dc1a3d9..000000000
--- a/collection/where.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import baseMatches from '../internal/baseMatches';
-import filter from './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));
-}
-
-export default where;
diff --git a/chain/wrapperCommit.js b/commit.js
similarity index 88%
rename from chain/wrapperCommit.js
rename to commit.js
index 9341c5ab2..c7f250229 100644
--- a/chain/wrapperCommit.js
+++ b/commit.js
@@ -1,11 +1,11 @@
-import LodashWrapper from '../internal/LodashWrapper';
+import LodashWrapper from './internal/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..1cd2dab4e
--- /dev/null
+++ b/concat.js
@@ -0,0 +1,32 @@
+import arrayConcat from './internal/arrayConcat';
+import baseFlatten from './internal/baseFlatten';
+import isArray from './isArray';
+import rest from './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);
+});
+
+export default concat;
diff --git a/cond.js b/cond.js
new file mode 100644
index 000000000..402859c90
--- /dev/null
+++ b/cond.js
@@ -0,0 +1,58 @@
+import apply from './internal/apply';
+import arrayMap from './internal/arrayMap';
+import baseIteratee from './internal/baseIteratee';
+import rest from './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);
+ }
+ }
+ });
+}
+
+export default cond;
diff --git a/conforms.js b/conforms.js
new file mode 100644
index 000000000..e90dca164
--- /dev/null
+++ b/conforms.js
@@ -0,0 +1,28 @@
+import baseClone from './internal/baseClone';
+import baseConforms from './internal/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));
+}
+
+export default conforms;
diff --git a/utility/constant.js b/constant.js
similarity index 95%
rename from utility/constant.js
rename to constant.js
index 910042b4e..6392cde9f 100644
--- a/utility/constant.js
+++ b/constant.js
@@ -3,7 +3,7 @@
*
* @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..23d81a76b
--- /dev/null
+++ b/countBy.js
@@ -0,0 +1,33 @@
+import createAggregator from './internal/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);
+});
+
+export default countBy;
diff --git a/object/create.js b/create.js
similarity index 55%
rename from object/create.js
rename to create.js
index 2cec13935..ef18b9074 100644
--- a/object/create.js
+++ b/create.js
@@ -1,18 +1,15 @@
-import baseAssign from '../internal/baseAssign';
-import baseCreate from '../internal/baseCreate';
-import isIterateeCall from '../internal/isIterateeCall';
+import baseAssign from './internal/baseAssign';
+import baseCreate from './internal/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
*
@@ -36,11 +33,8 @@ import isIterateeCall from '../internal/isIterateeCall';
* 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..318864915
--- /dev/null
+++ b/curry.js
@@ -0,0 +1,53 @@
+import createWrapper from './internal/createWrapper';
+
+/** 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;
+}
+
+export default curry;
diff --git a/function/curryRight.js b/curryRight.js
similarity index 66%
rename from function/curryRight.js
rename to curryRight.js
index 8cd0edac0..05d230cad 100644
--- a/function/curryRight.js
+++ b/curryRight.js
@@ -1,4 +1,4 @@
-import createCurry from '../internal/createCurry';
+import createWrapper from './internal/createWrapper';
/** Used to compose bitmasks for wrapper metadata. */
var CURRY_RIGHT_FLAG = 16;
@@ -10,14 +10,14 @@ var CURRY_RIGHT_FLAG = 16;
* 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,9 +40,11 @@ var CURRY_RIGHT_FLAG = 16;
* 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;
+}
export default curryRight;
diff --git a/date.default.js b/date.default.js
new file mode 100644
index 000000000..d03070153
--- /dev/null
+++ b/date.default.js
@@ -0,0 +1,5 @@
+import now from './now';
+
+export default {
+ now
+};
diff --git a/date.js b/date.js
index 9fa88963c..d5c560b51 100644
--- a/date.js
+++ b/date.js
@@ -1,5 +1,2 @@
-import now from './date/now';
-
-export default {
- 'now': now
-};
+export { default as now } from './now';
+export { default as default } from './date.default';
diff --git a/date/now.js b/date/now.js
deleted file mode 100644
index 7c94a3021..000000000
--- a/date/now.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import getNative from '../internal/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();
-};
-
-export default now;
diff --git a/function/debounce.js b/debounce.js
similarity index 73%
rename from function/debounce.js
rename to debounce.js
index 88083f271..8d2a325a6 100644
--- a/function/debounce.js
+++ b/debounce.js
@@ -1,20 +1,22 @@
-import isObject from '../lang/isObject';
-import now from '../date/now';
+import isObject from './isObject';
+import now from './now';
+import toNumber from './toNumber';
/** 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
@@ -41,34 +43,19 @@ var nativeMax = Math.max;
* // 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,
@@ -79,19 +66,17 @@ function debounce(func, wait, options) {
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;
}
@@ -103,7 +88,7 @@ function debounce(func, wait, options) {
clearTimeout(maxTimeoutId);
}
lastCalled = 0;
- maxTimeoutId = timeoutId = trailingCall = undefined;
+ args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
}
function complete(isCalled, id) {
@@ -129,6 +114,14 @@ function debounce(func, wait, options) {
}
}
+ function flush() {
+ if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
+ result = func.apply(thisArg, args);
+ }
+ cancel();
+ return result;
+ }
+
function maxDelayed() {
complete(trailing, timeoutId);
}
@@ -175,6 +168,7 @@ function debounce(func, wait, options) {
return result;
}
debounced.cancel = cancel;
+ debounced.flush = flush;
return debounced;
}
diff --git a/string/deburr.js b/deburr.js
similarity index 71%
rename from string/deburr.js
rename to deburr.js
index 88d3573e8..36569e4c3 100644
--- a/string/deburr.js
+++ b/deburr.js
@@ -1,12 +1,18 @@
-import baseToString from '../internal/baseToString';
-import deburrLetter from '../internal/deburrLetter';
-
-/** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
-var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g;
+import deburrLetter from './internal/deburrLetter';
+import toString from './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).
@@ -22,7 +28,7 @@ var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
* // => '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..63e3df637
--- /dev/null
+++ b/defaults.js
@@ -0,0 +1,30 @@
+import apply from './internal/apply';
+import assignInDefaults from './internal/assignInDefaults';
+import assignInWith from './assignInWith';
+import rest from './rest';
+
+/**
+ * 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);
+});
+
+export default defaults;
diff --git a/object/defaultsDeep.js b/defaultsDeep.js
similarity index 65%
rename from object/defaultsDeep.js
rename to defaultsDeep.js
index 21c73b3b5..f7f8d4bc9 100644
--- a/object/defaultsDeep.js
+++ b/defaultsDeep.js
@@ -1,6 +1,7 @@
-import createDefaults from '../internal/createDefaults';
-import merge from './merge';
-import mergeDefaults from '../internal/mergeDefaults';
+import apply from './internal/apply';
+import mergeDefaults from './internal/mergeDefaults';
+import mergeWith from './mergeWith';
+import rest from './rest';
/**
* This method is like `_.defaults` except that it recursively assigns
@@ -20,6 +21,9 @@ import mergeDefaults from '../internal/mergeDefaults';
* // => { 'user': { 'name': 'barney', 'age': 36 } }
*
*/
-var defaultsDeep = createDefaults(merge, mergeDefaults);
+var defaultsDeep = rest(function(args) {
+ args.push(undefined, mergeDefaults);
+ return apply(mergeWith, undefined, args);
+});
export default defaultsDeep;
diff --git a/function/defer.js b/defer.js
similarity index 71%
rename from function/defer.js
rename to defer.js
index 757de6de0..ed4f5e343 100644
--- a/function/defer.js
+++ b/defer.js
@@ -1,5 +1,5 @@
-import baseDelay from '../internal/baseDelay';
-import restParam from './restParam';
+import baseDelay from './internal/baseDelay';
+import rest from './rest';
/**
* Defers invoking the `func` until the current call stack has cleared. Any
@@ -9,7 +9,7 @@ import restParam from './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
*
@@ -18,7 +18,7 @@ import restParam from './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 64%
rename from function/delay.js
rename to delay.js
index 5b34c6912..9112fb5de 100644
--- a/function/delay.js
+++ b/delay.js
@@ -1,5 +1,6 @@
-import baseDelay from '../internal/baseDelay';
-import restParam from './restParam';
+import baseDelay from './internal/baseDelay';
+import rest from './rest';
+import toNumber from './toNumber';
/**
* Invokes `func` after `wait` milliseconds. Any additional arguments are
@@ -10,7 +11,7 @@ import restParam from './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
*
@@ -19,8 +20,8 @@ import restParam from './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);
});
export default delay;
diff --git a/array/difference.js b/difference.js
similarity index 50%
rename from array/difference.js
rename to difference.js
index 64a541bd7..53bbe28ae 100644
--- a/array/difference.js
+++ b/difference.js
@@ -1,8 +1,7 @@
-import baseDifference from '../internal/baseDifference';
-import baseFlatten from '../internal/baseFlatten';
-import isArrayLike from '../internal/isArrayLike';
-import isObjectLike from '../internal/isObjectLike';
-import restParam from '../function/restParam';
+import baseDifference from './internal/baseDifference';
+import baseFlatten from './internal/baseFlatten';
+import isArrayLikeObject from './isArrayLikeObject';
+import rest from './rest';
/**
* Creates an array of unique `array` values not included in the other
@@ -13,15 +12,15 @@ import restParam from '../function/restParam';
* @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..d101dd25e
--- /dev/null
+++ b/differenceBy.js
@@ -0,0 +1,39 @@
+import baseDifference from './internal/baseDifference';
+import baseFlatten from './internal/baseFlatten';
+import baseIteratee from './internal/baseIteratee';
+import isArrayLikeObject from './isArrayLikeObject';
+import last from './last';
+import rest from './rest';
+
+/**
+ * This method is like `_.difference` except that it accepts `iteratee` which
+ * is invoked for each element of `array` and `values` to generate the criterion
+ * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @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))
+ : [];
+});
+
+export default differenceBy;
diff --git a/differenceWith.js b/differenceWith.js
new file mode 100644
index 000000000..7f573cc62
--- /dev/null
+++ b/differenceWith.js
@@ -0,0 +1,36 @@
+import baseDifference from './internal/baseDifference';
+import baseFlatten from './internal/baseFlatten';
+import isArrayLikeObject from './isArrayLikeObject';
+import last from './last';
+import rest from './rest';
+
+/**
+ * This method is like `_.difference` except that it accepts `comparator`
+ * which is invoked to compare elements of `array` to `values`. The comparator
+ * is invoked with two arguments: (arrVal, othVal).
+ *
+ * @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)
+ : [];
+});
+
+export default differenceWith;
diff --git a/array/drop.js b/drop.js
similarity index 66%
rename from array/drop.js
rename to drop.js
index bbb1cc162..3afb5d785 100644
--- a/array/drop.js
+++ b/drop.js
@@ -1,5 +1,5 @@
-import baseSlice from '../internal/baseSlice';
-import isIterateeCall from '../internal/isIterateeCall';
+import baseSlice from './internal/baseSlice';
+import toInteger from './toInteger';
/**
* Creates a slice of `array` with `n` elements dropped from the beginning.
@@ -9,7 +9,7 @@ import isIterateeCall from '../internal/isIterateeCall';
* @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
*
@@ -30,10 +30,8 @@ function drop(array, n, guard) {
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);
}
export default drop;
diff --git a/array/dropRight.js b/dropRight.js
similarity index 69%
rename from array/dropRight.js
rename to dropRight.js
index 96dfebb1f..67b3b32fe 100644
--- a/array/dropRight.js
+++ b/dropRight.js
@@ -1,5 +1,5 @@
-import baseSlice from '../internal/baseSlice';
-import isIterateeCall from '../internal/isIterateeCall';
+import baseSlice from './internal/baseSlice';
+import toInteger from './toInteger';
/**
* Creates a slice of `array` with `n` elements dropped from the end.
@@ -9,7 +9,7 @@ import isIterateeCall from '../internal/isIterateeCall';
* @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
*
@@ -30,10 +30,8 @@ function dropRight(array, n, guard) {
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..43067e75e
--- /dev/null
+++ b/dropRightWhile.js
@@ -0,0 +1,44 @@
+import baseIteratee from './internal/baseIteratee';
+import baseWhile from './internal/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)
+ : [];
+}
+
+export default dropRightWhile;
diff --git a/dropWhile.js b/dropWhile.js
new file mode 100644
index 000000000..211ad3c82
--- /dev/null
+++ b/dropWhile.js
@@ -0,0 +1,44 @@
+import baseIteratee from './internal/baseIteratee';
+import baseWhile from './internal/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)
+ : [];
+}
+
+export default dropWhile;
diff --git a/each.js b/each.js
new file mode 100644
index 000000000..388824242
--- /dev/null
+++ b/each.js
@@ -0,0 +1 @@
+export { default } from './forEach'
diff --git a/eachRight.js b/eachRight.js
new file mode 100644
index 000000000..72ac72ab9
--- /dev/null
+++ b/eachRight.js
@@ -0,0 +1 @@
+export { default } from './forEachRight'
diff --git a/string/endsWith.js b/endsWith.js
similarity index 73%
rename from string/endsWith.js
rename to endsWith.js
index 217efb714..851d42664 100644
--- a/string/endsWith.js
+++ b/endsWith.js
@@ -1,7 +1,6 @@
-import baseToString from '../internal/baseToString';
-
-/* Native method references for those with the same name as other `lodash` methods. */
-var nativeMin = Math.min;
+import baseClamp from './internal/baseClamp';
+import toInteger from './toInteger';
+import toString from './toString';
/**
* Checks if `string` ends with the given target string.
@@ -25,13 +24,13 @@ var nativeMin = Math.min;
* // => 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..f3cb7ea4a
--- /dev/null
+++ b/eq.js
@@ -0,0 +1,35 @@
+/**
+ * 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);
+}
+
+export default eq;
diff --git a/string/escape.js b/escape.js
similarity index 72%
rename from string/escape.js
rename to escape.js
index feaa8f7a7..5ca549509 100644
--- a/string/escape.js
+++ b/escape.js
@@ -1,16 +1,16 @@
-import baseToString from '../internal/baseToString';
-import escapeHtmlChar from '../internal/escapeHtmlChar';
+import escapeHtmlChar from './internal/escapeHtmlChar';
+import toString from './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
@@ -18,8 +18,8 @@ var reUnescapedHtml = /[&<>"'`]/g,
* 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.
@@ -38,8 +38,7 @@ var reUnescapedHtml = /[&<>"'`]/g,
* // => '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..47fec43f6
--- /dev/null
+++ b/escapeRegExp.js
@@ -0,0 +1,28 @@
+import toString from './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;
+}
+
+export default escapeRegExp;
diff --git a/every.js b/every.js
new file mode 100644
index 000000000..ebaafe05e
--- /dev/null
+++ b/every.js
@@ -0,0 +1,49 @@
+import arrayEvery from './internal/arrayEvery';
+import baseEvery from './internal/baseEvery';
+import baseIteratee from './internal/baseIteratee';
+import isArray from './isArray';
+import isIterateeCall from './internal/isIterateeCall';
+
+/**
+ * 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));
+}
+
+export default every;
diff --git a/array/fill.js b/fill.js
similarity index 84%
rename from array/fill.js
rename to fill.js
index dc8d4fa90..2a337d1d6 100644
--- a/array/fill.js
+++ b/fill.js
@@ -1,5 +1,5 @@
-import baseFill from '../internal/baseFill';
-import isIterateeCall from '../internal/isIterateeCall';
+import baseFill from './internal/baseFill';
+import isIterateeCall from './internal/isIterateeCall';
/**
* Fills elements of `array` with `value` from `start` up to, but not
@@ -26,8 +26,8 @@ import isIterateeCall from '../internal/isIterateeCall';
* _.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..cfa0844ae
--- /dev/null
+++ b/filter.js
@@ -0,0 +1,44 @@
+import arrayFilter from './internal/arrayFilter';
+import baseFilter from './internal/baseFilter';
+import baseIteratee from './internal/baseIteratee';
+import isArray from './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));
+}
+
+export default filter;
diff --git a/find.js b/find.js
new file mode 100644
index 000000000..bfabb403d
--- /dev/null
+++ b/find.js
@@ -0,0 +1,50 @@
+import baseEach from './internal/baseEach';
+import baseFind from './internal/baseFind';
+import baseFindIndex from './internal/baseFindIndex';
+import baseIteratee from './internal/baseIteratee';
+import isArray from './isArray';
+
+/**
+ * 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);
+}
+
+export default find;
diff --git a/findIndex.js b/findIndex.js
new file mode 100644
index 000000000..73a133d90
--- /dev/null
+++ b/findIndex.js
@@ -0,0 +1,43 @@
+import baseFindIndex from './internal/baseFindIndex';
+import baseIteratee from './internal/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;
+}
+
+export default findIndex;
diff --git a/findKey.js b/findKey.js
new file mode 100644
index 000000000..c7b1b31ca
--- /dev/null
+++ b/findKey.js
@@ -0,0 +1,42 @@
+import baseFind from './internal/baseFind';
+import baseForOwn from './internal/baseForOwn';
+import baseIteratee from './internal/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);
+}
+
+export default findKey;
diff --git a/findLast.js b/findLast.js
new file mode 100644
index 000000000..5ada5d872
--- /dev/null
+++ b/findLast.js
@@ -0,0 +1,33 @@
+import baseEachRight from './internal/baseEachRight';
+import baseFind from './internal/baseFind';
+import baseFindIndex from './internal/baseFindIndex';
+import baseIteratee from './internal/baseIteratee';
+import isArray from './isArray';
+
+/**
+ * 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);
+}
+
+export default findLast;
diff --git a/findLastIndex.js b/findLastIndex.js
new file mode 100644
index 000000000..51cb671fd
--- /dev/null
+++ b/findLastIndex.js
@@ -0,0 +1,43 @@
+import baseFindIndex from './internal/baseFindIndex';
+import baseIteratee from './internal/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;
+}
+
+export default findLastIndex;
diff --git a/findLastKey.js b/findLastKey.js
new file mode 100644
index 000000000..4d59c9131
--- /dev/null
+++ b/findLastKey.js
@@ -0,0 +1,42 @@
+import baseFind from './internal/baseFind';
+import baseForOwnRight from './internal/baseForOwnRight';
+import baseIteratee from './internal/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);
+}
+
+export default findLastKey;
diff --git a/flatMap.js b/flatMap.js
new file mode 100644
index 000000000..c3e08d8ee
--- /dev/null
+++ b/flatMap.js
@@ -0,0 +1,30 @@
+import arrayMap from './internal/arrayMap';
+import baseFlatten from './internal/baseFlatten';
+import baseIteratee from './internal/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))) : [];
+}
+
+export default flatMap;
diff --git a/flatten.js b/flatten.js
new file mode 100644
index 000000000..bbf0d8698
--- /dev/null
+++ b/flatten.js
@@ -0,0 +1,21 @@
+import baseFlatten from './internal/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) : [];
+}
+
+export default flatten;
diff --git a/array/flattenDeep.js b/flattenDeep.js
similarity index 75%
rename from array/flattenDeep.js
rename to flattenDeep.js
index c9e3a9172..b617d7233 100644
--- a/array/flattenDeep.js
+++ b/flattenDeep.js
@@ -1,7 +1,7 @@
-import baseFlatten from '../internal/baseFlatten';
+import baseFlatten from './internal/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..0972af36d
--- /dev/null
+++ b/flip.js
@@ -0,0 +1,27 @@
+import createWrapper from './internal/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);
+}
+
+export default flip;
diff --git a/math/floor.js b/floor.js
similarity index 70%
rename from math/floor.js
rename to floor.js
index bfb24e660..93f895f58 100644
--- a/math/floor.js
+++ b/floor.js
@@ -1,12 +1,12 @@
-import createRound from '../internal/createRound';
+import createRound from './internal/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 e5edf51f2..50ebf7ec6 100644
--- a/function/flow.js
+++ b/flow.js
@@ -1,4 +1,4 @@
-import createFlow from '../internal/createFlow';
+import createFlow from './internal/createFlow';
/**
* Creates a function that returns the result of invoking the provided
@@ -7,8 +7,8 @@ import createFlow from '../internal/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 73%
rename from function/flowRight.js
rename to flowRight.js
index 861995144..26c0c8321 100644
--- a/function/flowRight.js
+++ b/flowRight.js
@@ -1,4 +1,4 @@
-import createFlow from '../internal/createFlow';
+import createFlow from './internal/createFlow';
/**
* This method is like `_.flow` except that it creates a function that
@@ -6,9 +6,8 @@ import createFlow from '../internal/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..e8bd1f136
--- /dev/null
+++ b/forEach.js
@@ -0,0 +1,40 @@
+import arrayEach from './internal/arrayEach';
+import baseEach from './internal/baseEach';
+import isArray from './isArray';
+import toFunction from './internal/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));
+}
+
+export default forEach;
diff --git a/forEachRight.js b/forEachRight.js
new file mode 100644
index 000000000..7cc4270c8
--- /dev/null
+++ b/forEachRight.js
@@ -0,0 +1,30 @@
+import arrayEachRight from './internal/arrayEachRight';
+import baseEachRight from './internal/baseEachRight';
+import isArray from './isArray';
+import toFunction from './internal/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));
+}
+
+export default forEachRight;
diff --git a/object/forIn.js b/forIn.js
similarity index 50%
rename from object/forIn.js
rename to forIn.js
index 4ac5fdfe3..28551a061 100644
--- a/object/forIn.js
+++ b/forIn.js
@@ -1,18 +1,18 @@
-import baseFor from '../internal/baseFor';
-import createForIn from '../internal/createForIn';
+import baseFor from './internal/baseFor';
+import keysIn from './keysIn';
+import toFunction from './internal/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
*
@@ -26,8 +26,10 @@ import createForIn from '../internal/createForIn';
* _.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);
+}
export default forIn;
diff --git a/object/forInRight.js b/forInRight.js
similarity index 62%
rename from object/forInRight.js
rename to forInRight.js
index f9d368342..14e88c04a 100644
--- a/object/forInRight.js
+++ b/forInRight.js
@@ -1,5 +1,6 @@
-import baseForRight from '../internal/baseForRight';
-import createForIn from '../internal/createForIn';
+import baseForRight from './internal/baseForRight';
+import keysIn from './keysIn';
+import toFunction from './internal/toFunction';
/**
* This method is like `_.forIn` except that it iterates over properties of
@@ -10,7 +11,6 @@ import createForIn from '../internal/createForIn';
* @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
*
@@ -24,8 +24,10 @@ import createForIn from '../internal/createForIn';
* _.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);
+}
export default forInRight;
diff --git a/object/forOwn.js b/forOwn.js
similarity index 52%
rename from object/forOwn.js
rename to forOwn.js
index 096b25ee9..f667ea2d1 100644
--- a/object/forOwn.js
+++ b/forOwn.js
@@ -1,18 +1,17 @@
-import baseForOwn from '../internal/baseForOwn';
-import createForOwn from '../internal/createForOwn';
+import baseForOwn from './internal/baseForOwn';
+import toFunction from './internal/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
*
@@ -26,8 +25,10 @@ import createForOwn from '../internal/createForOwn';
* _.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));
+}
export default forOwn;
diff --git a/object/forOwnRight.js b/forOwnRight.js
similarity index 66%
rename from object/forOwnRight.js
rename to forOwnRight.js
index 8d05a6948..58fc38cf9 100644
--- a/object/forOwnRight.js
+++ b/forOwnRight.js
@@ -1,5 +1,5 @@
-import baseForOwnRight from '../internal/baseForOwnRight';
-import createForOwn from '../internal/createForOwn';
+import baseForOwnRight from './internal/baseForOwnRight';
+import toFunction from './internal/toFunction';
/**
* This method is like `_.forOwn` except that it iterates over properties of
@@ -10,7 +10,6 @@ import createForOwn from '../internal/createForOwn';
* @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
*
@@ -24,8 +23,10 @@ import createForOwn from '../internal/createForOwn';
* _.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));
+}
export default forOwnRight;
diff --git a/fromPairs.js b/fromPairs.js
new file mode 100644
index 000000000..86bb0da1f
--- /dev/null
+++ b/fromPairs.js
@@ -0,0 +1,29 @@
+import baseSet from './internal/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;
+}
+
+export default fromPairs;
diff --git a/function.default.js b/function.default.js
new file mode 100644
index 000000000..34fe1ffa8
--- /dev/null
+++ b/function.default.js
@@ -0,0 +1,31 @@
+import after from './after';
+import ary from './ary';
+import before from './before';
+import bind from './bind';
+import bindKey from './bindKey';
+import curry from './curry';
+import curryRight from './curryRight';
+import debounce from './debounce';
+import defer from './defer';
+import delay from './delay';
+import flip from './flip';
+import memoize from './memoize';
+import negate from './negate';
+import once from './once';
+import overArgs from './overArgs';
+import partial from './partial';
+import partialRight from './partialRight';
+import rearg from './rearg';
+import rest from './rest';
+import spread from './spread';
+import throttle from './throttle';
+import unary from './unary';
+import wrap from './wrap';
+
+export default {
+ after, ary, before, bind, bindKey,
+ curry, curryRight, debounce, defer, delay,
+ flip, memoize, negate, once, overArgs,
+ partial, partialRight, rearg, rest, spread,
+ throttle, unary, wrap
+};
diff --git a/function.js b/function.js
index f0de61d6a..7e3fc192c 100644
--- a/function.js
+++ b/function.js
@@ -1,55 +1,24 @@
-import after from './function/after';
-import ary from './function/ary';
-import backflow from './function/backflow';
-import before from './function/before';
-import bind from './function/bind';
-import bindAll from './function/bindAll';
-import bindKey from './function/bindKey';
-import compose from './function/compose';
-import curry from './function/curry';
-import curryRight from './function/curryRight';
-import debounce from './function/debounce';
-import defer from './function/defer';
-import delay from './function/delay';
-import flow from './function/flow';
-import flowRight from './function/flowRight';
-import memoize from './function/memoize';
-import modArgs from './function/modArgs';
-import negate from './function/negate';
-import once from './function/once';
-import partial from './function/partial';
-import partialRight from './function/partialRight';
-import rearg from './function/rearg';
-import restParam from './function/restParam';
-import spread from './function/spread';
-import throttle from './function/throttle';
-import wrap from './function/wrap';
-
-export default {
- '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,
- 'memoize': memoize,
- 'modArgs': modArgs,
- 'negate': negate,
- 'once': once,
- 'partial': partial,
- 'partialRight': partialRight,
- 'rearg': rearg,
- 'restParam': restParam,
- 'spread': spread,
- 'throttle': throttle,
- 'wrap': wrap
-};
+export { default as after } from './after';
+export { default as ary } from './ary';
+export { default as before } from './before';
+export { default as bind } from './bind';
+export { default as bindKey } from './bindKey';
+export { default as curry } from './curry';
+export { default as curryRight } from './curryRight';
+export { default as debounce } from './debounce';
+export { default as defer } from './defer';
+export { default as delay } from './delay';
+export { default as flip } from './flip';
+export { default as memoize } from './memoize';
+export { default as negate } from './negate';
+export { default as once } from './once';
+export { default as overArgs } from './overArgs';
+export { default as partial } from './partial';
+export { default as partialRight } from './partialRight';
+export { default as rearg } from './rearg';
+export { default as rest } from './rest';
+export { default as spread } from './spread';
+export { default as throttle } from './throttle';
+export { default as unary } from './unary';
+export { default as wrap } from './wrap';
+export { default as default } from './function.default';
diff --git a/function/backflow.js b/function/backflow.js
deleted file mode 100644
index 69295194f..000000000
--- a/function/backflow.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import flowRight from './flowRight'
-export default flowRight;
diff --git a/function/bindAll.js b/function/bindAll.js
deleted file mode 100644
index 2346f6349..000000000
--- a/function/bindAll.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import baseFlatten from '../internal/baseFlatten';
-import createWrapper from '../internal/createWrapper';
-import functions from '../object/functions';
-import restParam from './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;
-});
-
-export default bindAll;
diff --git a/function/compose.js b/function/compose.js
deleted file mode 100644
index 69295194f..000000000
--- a/function/compose.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import flowRight from './flowRight'
-export default flowRight;
diff --git a/function/curry.js b/function/curry.js
deleted file mode 100644
index fd170a5ff..000000000
--- a/function/curry.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import createCurry from '../internal/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 = {};
-
-export default curry;
diff --git a/function/modArgs.js b/function/modArgs.js
deleted file mode 100644
index d52a58596..000000000
--- a/function/modArgs.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import arrayEvery from '../internal/arrayEvery';
-import baseFlatten from '../internal/baseFlatten';
-import baseIsFunction from '../internal/baseIsFunction';
-import restParam from './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);
- });
-});
-
-export default modArgs;
diff --git a/functions.js b/functions.js
new file mode 100644
index 000000000..dd76adcde
--- /dev/null
+++ b/functions.js
@@ -0,0 +1,29 @@
+import baseFunctions from './internal/baseFunctions';
+import keys from './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));
+}
+
+export default functions;
diff --git a/functionsIn.js b/functionsIn.js
new file mode 100644
index 000000000..f88c57e95
--- /dev/null
+++ b/functionsIn.js
@@ -0,0 +1,29 @@
+import baseFunctions from './internal/baseFunctions';
+import keysIn from './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));
+}
+
+export default functionsIn;
diff --git a/object/get.js b/get.js
similarity index 73%
rename from object/get.js
rename to get.js
index de9489008..6a863a557 100644
--- a/object/get.js
+++ b/get.js
@@ -1,8 +1,7 @@
-import baseGet from '../internal/baseGet';
-import toPath from '../internal/toPath';
+import baseGet from './internal/baseGet';
/**
- * 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
@@ -26,7 +25,7 @@ import toPath from '../internal/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..b7e03d3da
--- /dev/null
+++ b/groupBy.js
@@ -0,0 +1,38 @@
+import createAggregator from './internal/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];
+ }
+});
+
+export default 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..438179059
--- /dev/null
+++ b/has.js
@@ -0,0 +1,34 @@
+import baseHas from './internal/baseHas';
+import hasPath from './internal/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);
+}
+
+export default has;
diff --git a/hasIn.js b/hasIn.js
new file mode 100644
index 000000000..a700e43d6
--- /dev/null
+++ b/hasIn.js
@@ -0,0 +1,33 @@
+import baseHasIn from './internal/baseHasIn';
+import hasPath from './internal/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);
+}
+
+export default hasIn;
diff --git a/array/first.js b/head.js
similarity index 73%
rename from array/first.js
rename to head.js
index e5f259842..5ae4f6364 100644
--- a/array/first.js
+++ b/head.js
@@ -3,20 +3,20 @@
*
* @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;
}
-export default first;
+export default head;
diff --git a/utility/identity.js b/identity.js
similarity index 94%
rename from utility/identity.js
rename to identity.js
index 0c9c17de3..c6101d9d7 100644
--- a/utility/identity.js
+++ b/identity.js
@@ -3,7 +3,7 @@
*
* @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 55%
rename from number/inRange.js
rename to inRange.js
index 1db32d688..face7d88c 100644
--- a/number/inRange.js
+++ b/inRange.js
@@ -1,18 +1,19 @@
-/* Native method references for those with the same name as other `lodash` methods. */
-var nativeMax = Math.max,
- nativeMin = Math.min;
+import baseInRange from './internal/baseInRange';
+import toNumber from './toNumber';
/**
* 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);
@@ -32,16 +33,20 @@ var nativeMax = Math.max,
*
* _.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);
}
export default inRange;
diff --git a/includes.js b/includes.js
new file mode 100644
index 000000000..a7f03cdd9
--- /dev/null
+++ b/includes.js
@@ -0,0 +1,51 @@
+import baseIndexOf from './internal/baseIndexOf';
+import isArrayLike from './isArrayLike';
+import isString from './isString';
+import toInteger from './toInteger';
+import values from './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);
+}
+
+export default includes;
diff --git a/array/indexOf.js b/indexOf.js
similarity index 53%
rename from array/indexOf.js
rename to indexOf.js
index dad65c144..25126230b 100644
--- a/array/indexOf.js
+++ b/indexOf.js
@@ -1,7 +1,7 @@
-import baseIndexOf from '../internal/baseIndexOf';
-import binaryIndex from '../internal/binaryIndex';
+import baseIndexOf from './internal/baseIndexOf';
+import toInteger from './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;
/**
@@ -16,8 +16,7 @@ var nativeMax = Math.max;
* @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
*
@@ -27,27 +26,17 @@ var nativeMax = Math.max;
* // 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);
}
export default 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..0fba9376c
--- /dev/null
+++ b/internal/Hash.js
@@ -0,0 +1,17 @@
+import nativeCreate from './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;
+
+export default Hash;
diff --git a/internal/LazyWrapper.js b/internal/LazyWrapper.js
index 4c8e5b420..e93e4a1ec 100644
--- a/internal/LazyWrapper.js
+++ b/internal/LazyWrapper.js
@@ -1,8 +1,8 @@
import baseCreate from './baseCreate';
import baseLodash from './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.
@@ -16,7 +16,7 @@ function LazyWrapper(value) {
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 adfc689c3..08a1cdd4a 100644
--- a/internal/LodashWrapper.js
+++ b/internal/LodashWrapper.js
@@ -7,12 +7,13 @@ import baseLodash from './baseLodash';
* @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..846355c16
--- /dev/null
+++ b/internal/Map.js
@@ -0,0 +1,7 @@
+import getNative from './getNative';
+import root from './root';
+
+/* Built-in method references that are verified to be native. */
+var Map = getNative(root, 'Map');
+
+export default Map;
diff --git a/internal/MapCache.js b/internal/MapCache.js
index d4a55adf9..13ee61db3 100644
--- a/internal/MapCache.js
+++ b/internal/MapCache.js
@@ -1,21 +1,28 @@
+import mapClear from './mapClear';
import mapDelete from './mapDelete';
import mapGet from './mapGet';
import mapHas from './mapHas';
import mapSet from './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..89162b591
--- /dev/null
+++ b/internal/Reflect.js
@@ -0,0 +1,6 @@
+import root from './root';
+
+/** Built-in value references. */
+var Reflect = root.Reflect;
+
+export default Reflect;
diff --git a/internal/Set.js b/internal/Set.js
new file mode 100644
index 000000000..23a328016
--- /dev/null
+++ b/internal/Set.js
@@ -0,0 +1,7 @@
+import getNative from './getNative';
+import root from './root';
+
+/* Built-in method references that are verified to be native. */
+var Set = getNative(root, 'Set');
+
+export default Set;
diff --git a/internal/SetCache.js b/internal/SetCache.js
index 016612116..eca84426f 100644
--- a/internal/SetCache.js
+++ b/internal/SetCache.js
@@ -1,30 +1,24 @@
+import MapCache from './MapCache';
import cachePush from './cachePush';
-import getNative from './getNative';
-import root from './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 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;
export default SetCache;
diff --git a/internal/Stack.js b/internal/Stack.js
new file mode 100644
index 000000000..821153dc3
--- /dev/null
+++ b/internal/Stack.js
@@ -0,0 +1,31 @@
+import stackClear from './stackClear';
+import stackDelete from './stackDelete';
+import stackGet from './stackGet';
+import stackHas from './stackHas';
+import stackSet from './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;
+
+export default Stack;
diff --git a/internal/Uint8Array.js b/internal/Uint8Array.js
new file mode 100644
index 000000000..cabbb800d
--- /dev/null
+++ b/internal/Uint8Array.js
@@ -0,0 +1,6 @@
+import root from './root';
+
+/** Built-in value references. */
+var Uint8Array = root.Uint8Array;
+
+export default Uint8Array;
diff --git a/internal/WeakMap.js b/internal/WeakMap.js
new file mode 100644
index 000000000..e0410c589
--- /dev/null
+++ b/internal/WeakMap.js
@@ -0,0 +1,7 @@
+import getNative from './getNative';
+import root from './root';
+
+/* Built-in method references that are verified to be native. */
+var WeakMap = getNative(root, 'WeakMap');
+
+export default WeakMap;
diff --git a/internal/_Symbol.js b/internal/_Symbol.js
new file mode 100644
index 000000000..bffed6a80
--- /dev/null
+++ b/internal/_Symbol.js
@@ -0,0 +1,6 @@
+import root from './root';
+
+/** Built-in value references. */
+var _Symbol = root.Symbol;
+
+export default _Symbol;
diff --git a/internal/addMapEntry.js b/internal/addMapEntry.js
new file mode 100644
index 000000000..486c184ff
--- /dev/null
+++ b/internal/addMapEntry.js
@@ -0,0 +1,14 @@
+/**
+ * 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;
+}
+
+export default addMapEntry;
diff --git a/internal/addSetEntry.js b/internal/addSetEntry.js
new file mode 100644
index 000000000..a999aed9c
--- /dev/null
+++ b/internal/addSetEntry.js
@@ -0,0 +1,14 @@
+/**
+ * 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;
+}
+
+export default addSetEntry;
diff --git a/internal/apply.js b/internal/apply.js
new file mode 100644
index 000000000..28994b185
--- /dev/null
+++ b/internal/apply.js
@@ -0,0 +1,22 @@
+/**
+ * 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);
+}
+
+export default apply;
diff --git a/internal/arrayConcat.js b/internal/arrayConcat.js
index 9d5e23dd4..61a7df31c 100644
--- a/internal/arrayConcat.js
+++ b/internal/arrayConcat.js
@@ -1,9 +1,9 @@
/**
- * 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 7bf245dca..142993ecd 100644
--- a/internal/arrayEach.js
+++ b/internal/arrayEach.js
@@ -1,6 +1,6 @@
/**
- * 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 8d39f733c..d39a69a94 100644
--- a/internal/arrayEachRight.js
+++ b/internal/arrayEachRight.js
@@ -1,6 +1,6 @@
/**
* 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 92da7c0d6..dcf4460ef 100644
--- a/internal/arrayEvery.js
+++ b/internal/arrayEvery.js
@@ -1,12 +1,11 @@
/**
- * 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 1c77ac368..000000000
--- a/internal/arrayExtremum.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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;
-}
-
-export default arrayExtremum;
diff --git a/internal/arrayFilter.js b/internal/arrayFilter.js
index d9ae85782..247b29891 100644
--- a/internal/arrayFilter.js
+++ b/internal/arrayFilter.js
@@ -1,6 +1,6 @@
/**
- * 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..9a99b17ce
--- /dev/null
+++ b/internal/arrayIncludes.js
@@ -0,0 +1,16 @@
+import baseIndexOf from './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;
+}
+
+export default arrayIncludes;
diff --git a/internal/arrayIncludesWith.js b/internal/arrayIncludesWith.js
new file mode 100644
index 000000000..b84117693
--- /dev/null
+++ b/internal/arrayIncludesWith.js
@@ -0,0 +1,23 @@
+/**
+ * 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;
+}
+
+export default arrayIncludesWith;
diff --git a/internal/arrayMap.js b/internal/arrayMap.js
index 59c3920b9..eb475cc15 100644
--- a/internal/arrayMap.js
+++ b/internal/arrayMap.js
@@ -1,6 +1,6 @@
/**
- * 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 5e2cc9ac0..25d17865c 100644
--- a/internal/arrayReduce.js
+++ b/internal/arrayReduce.js
@@ -1,13 +1,12 @@
/**
- * 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 98be5537a..f7549633b 100644
--- a/internal/arrayReduceRight.js
+++ b/internal/arrayReduceRight.js
@@ -1,13 +1,12 @@
/**
* 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 48c767d9d..0e3f1850f 100644
--- a/internal/arraySome.js
+++ b/internal/arraySome.js
@@ -1,12 +1,11 @@
/**
- * 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 27ff80517..000000000
--- a/internal/arraySum.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * 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;
-}
-
-export default arraySum;
diff --git a/internal/assignDefaults.js b/internal/assignDefaults.js
deleted file mode 100644
index f91ee0b41..000000000
--- a/internal/assignDefaults.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * 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;
-}
-
-export default assignDefaults;
diff --git a/internal/assignInDefaults.js b/internal/assignInDefaults.js
new file mode 100644
index 000000000..b3af762e7
--- /dev/null
+++ b/internal/assignInDefaults.js
@@ -0,0 +1,27 @@
+import eq from '../eq';
+
+/** 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;
+}
+
+export default assignInDefaults;
diff --git a/internal/assignMergeValue.js b/internal/assignMergeValue.js
new file mode 100644
index 000000000..56486df21
--- /dev/null
+++ b/internal/assignMergeValue.js
@@ -0,0 +1,18 @@
+import eq from '../eq';
+
+/**
+ * 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;
+ }
+}
+
+export default assignMergeValue;
diff --git a/internal/assignOwnDefaults.js b/internal/assignOwnDefaults.js
deleted file mode 100644
index 5cd1af27f..000000000
--- a/internal/assignOwnDefaults.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/** 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;
-}
-
-export default assignOwnDefaults;
diff --git a/internal/assignValue.js b/internal/assignValue.js
new file mode 100644
index 000000000..b7d2b3e52
--- /dev/null
+++ b/internal/assignValue.js
@@ -0,0 +1,28 @@
+import eq from '../eq';
+
+/** 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;
+ }
+}
+
+export default assignValue;
diff --git a/internal/assignWith.js b/internal/assignWith.js
deleted file mode 100644
index 9343e6f16..000000000
--- a/internal/assignWith.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import keys from '../object/keys';
-
-/**
- * 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;
-}
-
-export default assignWith;
diff --git a/internal/assocDelete.js b/internal/assocDelete.js
new file mode 100644
index 000000000..206d7d8e9
--- /dev/null
+++ b/internal/assocDelete.js
@@ -0,0 +1,31 @@
+import assocIndexOf from './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;
+}
+
+export default assocDelete;
diff --git a/internal/assocGet.js b/internal/assocGet.js
new file mode 100644
index 000000000..a171e8486
--- /dev/null
+++ b/internal/assocGet.js
@@ -0,0 +1,16 @@
+import assocIndexOf from './assocIndexOf';
+
+/**
+ * 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];
+}
+
+export default assocGet;
diff --git a/internal/assocHas.js b/internal/assocHas.js
new file mode 100644
index 000000000..9691dbc2c
--- /dev/null
+++ b/internal/assocHas.js
@@ -0,0 +1,15 @@
+import assocIndexOf from './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;
+}
+
+export default assocHas;
diff --git a/internal/assocIndexOf.js b/internal/assocIndexOf.js
new file mode 100644
index 000000000..969b9a8ec
--- /dev/null
+++ b/internal/assocIndexOf.js
@@ -0,0 +1,22 @@
+import eq from '../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;
+}
+
+export default assocIndexOf;
diff --git a/internal/assocSet.js b/internal/assocSet.js
new file mode 100644
index 000000000..8adf34e99
--- /dev/null
+++ b/internal/assocSet.js
@@ -0,0 +1,20 @@
+import assocIndexOf from './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;
+ }
+}
+
+export default assocSet;
diff --git a/internal/baseAssign.js b/internal/baseAssign.js
index 98aa91b09..30097379f 100644
--- a/internal/baseAssign.js
+++ b/internal/baseAssign.js
@@ -1,9 +1,9 @@
-import baseCopy from './baseCopy';
-import keys from '../object/keys';
+import copyObject from './copyObject';
+import keys from '../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.
@@ -11,9 +11,7 @@ import keys from '../object/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);
}
export default baseAssign;
diff --git a/internal/baseAt.js b/internal/baseAt.js
index dcc302831..135ca2f04 100644
--- a/internal/baseAt.js
+++ b/internal/baseAt.js
@@ -1,30 +1,21 @@
-import isArrayLike from './isArrayLike';
-import isIndex from './isIndex';
+import get from '../get';
/**
- * 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 1d05a5ffd..000000000
--- a/internal/baseCallback.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import baseMatches from './baseMatches';
-import baseMatchesProperty from './baseMatchesProperty';
-import bindCallback from './bindCallback';
-import identity from '../utility/identity';
-import property from '../utility/property';
-
-/**
- * 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);
-}
-
-export default baseCallback;
diff --git a/internal/baseClamp.js b/internal/baseClamp.js
new file mode 100644
index 000000000..bb05ec270
--- /dev/null
+++ b/internal/baseClamp.js
@@ -0,0 +1,22 @@
+/**
+ * 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;
+}
+
+export default baseClamp;
diff --git a/internal/baseClone.js b/internal/baseClone.js
index 0679f34d5..bcc3299b2 100644
--- a/internal/baseClone.js
+++ b/internal/baseClone.js
@@ -1,12 +1,17 @@
-import arrayCopy from './arrayCopy';
+import Stack from './Stack';
import arrayEach from './arrayEach';
+import assignValue from './assignValue';
import baseAssign from './baseAssign';
import baseForOwn from './baseForOwn';
+import copyArray from './copyArray';
+import copySymbols from './copySymbols';
+import getTag from './getTag';
import initCloneArray from './initCloneArray';
import initCloneByTag from './initCloneByTag';
import initCloneObject from './initCloneObject';
-import isArray from '../lang/isArray';
-import isObject from '../lang/isObject';
+import isArray from '../isArray';
+import isHostObject from './isHostObject';
+import isObject from '../isObject';
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
@@ -15,12 +20,14 @@ var argsTag = '[object Arguments]',
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]',
@@ -41,41 +48,32 @@ cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
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;
@@ -87,16 +85,19 @@ function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
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]
@@ -105,24 +106,18 @@ function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
}
}
// 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);
}
export default baseClone;
diff --git a/internal/baseCompareAscending.js b/internal/baseCompareAscending.js
deleted file mode 100644
index 113811a1e..000000000
--- a/internal/baseCompareAscending.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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;
-}
-
-export default baseCompareAscending;
diff --git a/internal/baseConforms.js b/internal/baseConforms.js
new file mode 100644
index 000000000..5560bb8cf
--- /dev/null
+++ b/internal/baseConforms.js
@@ -0,0 +1,32 @@
+import keys from '../keys';
+
+/**
+ * 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;
+ };
+}
+
+export default baseConforms;
diff --git a/internal/baseCreate.js b/internal/baseCreate.js
index b95d4a016..4ea485da6 100644
--- a/internal/baseCreate.js
+++ b/internal/baseCreate.js
@@ -1,4 +1,4 @@
-import isObject from '../lang/isObject';
+import isObject from '../isObject';
/**
* The base implementation of `_.create` without support for assigning
diff --git a/internal/baseDelay.js b/internal/baseDelay.js
index 19cde60f9..f674ec780 100644
--- a/internal/baseDelay.js
+++ b/internal/baseDelay.js
@@ -2,8 +2,8 @@
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 967360ef3..a2f73009e 100644
--- a/internal/baseDifference.js
+++ b/internal/baseDifference.js
@@ -1,51 +1,62 @@
-import baseIndexOf from './baseIndexOf';
-import cacheIndexOf from './cacheIndexOf';
-import createCache from './createCache';
+import SetCache from './SetCache';
+import arrayIncludes from './arrayIncludes';
+import arrayIncludesWith from './arrayIncludesWith';
+import arrayMap from './arrayMap';
+import baseUnary from './baseUnary';
+import cacheHas from './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 d81a68762..76cf1f2f4 100644
--- a/internal/baseEach.js
+++ b/internal/baseEach.js
@@ -2,13 +2,12 @@ import baseForOwn from './baseForOwn';
import createBaseEach from './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 f3af975ff..8b100a6d6 100644
--- a/internal/baseEachRight.js
+++ b/internal/baseEachRight.js
@@ -2,13 +2,12 @@ import baseForOwnRight from './baseForOwnRight';
import createBaseEach from './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 6abb845da..e978a4bec 100644
--- a/internal/baseEvery.js
+++ b/internal/baseEvery.js
@@ -1,14 +1,12 @@
import baseEach from './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 e17dc3637..78cab39c7 100644
--- a/internal/baseExtremum.js
+++ b/internal/baseExtremum.js
@@ -1,28 +1,29 @@
-import baseEach from './baseEach';
-
/**
- * 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 bbb3e8506..57e524501 100644
--- a/internal/baseFill.js
+++ b/internal/baseFill.js
@@ -1,3 +1,6 @@
+import toInteger from '../toInteger';
+import toLength from '../toLength';
+
/**
* The base implementation of `_.fill` without an iteratee call guard.
*
@@ -11,18 +14,16 @@
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 278293591..5855cb5d3 100644
--- a/internal/baseFilter.js
+++ b/internal/baseFilter.js
@@ -1,11 +1,10 @@
import baseEach from './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 dcd576a7a..d229d8161 100644
--- a/internal/baseFind.js
+++ b/internal/baseFind.js
@@ -1,14 +1,13 @@
/**
- * 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 7beb32bc6..b40ce3a4d 100644
--- a/internal/baseFindIndex.js
+++ b/internal/baseFindIndex.js
@@ -1,6 +1,6 @@
/**
* 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 35025edde..4327be6e3 100644
--- a/internal/baseFlatten.js
+++ b/internal/baseFlatten.js
@@ -1,12 +1,10 @@
import arrayPush from './arrayPush';
-import isArguments from '../lang/isArguments';
-import isArray from '../lang/isArray';
-import isArrayLike from './isArrayLike';
-import isObjectLike from './isObjectLike';
+import isArguments from '../isArguments';
+import isArray from '../isArray';
+import isArrayLikeObject from '../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.
@@ -23,7 +21,7 @@ function baseFlatten(array, isDeep, isStrict, result) {
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 b9b56f82d..f152367fe 100644
--- a/internal/baseForIn.js
+++ b/internal/baseForIn.js
@@ -1,9 +1,8 @@
import baseFor from './baseFor';
-import keysIn from '../object/keysIn';
+import keysIn from '../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.
@@ -11,7 +10,7 @@ import keysIn from '../object/keysIn';
* @returns {Object} Returns `object`.
*/
function baseForIn(object, iteratee) {
- return baseFor(object, iteratee, keysIn);
+ return object == null ? object : baseFor(object, iteratee, keysIn);
}
export default baseForIn;
diff --git a/internal/baseForOwn.js b/internal/baseForOwn.js
index 2b60b8bb4..4ec8880ea 100644
--- a/internal/baseForOwn.js
+++ b/internal/baseForOwn.js
@@ -1,9 +1,8 @@
import baseFor from './baseFor';
-import keys from '../object/keys';
+import keys from '../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.
@@ -11,7 +10,7 @@ import keys from '../object/keys';
* @returns {Object} Returns `object`.
*/
function baseForOwn(object, iteratee) {
- return baseFor(object, iteratee, keys);
+ return object && baseFor(object, iteratee, keys);
}
export default baseForOwn;
diff --git a/internal/baseForOwnRight.js b/internal/baseForOwnRight.js
index 00dcc3734..ad5fd8f04 100644
--- a/internal/baseForOwnRight.js
+++ b/internal/baseForOwnRight.js
@@ -1,9 +1,8 @@
import baseForRight from './baseForRight';
-import keys from '../object/keys';
+import keys from '../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.
@@ -11,7 +10,7 @@ import keys from '../object/keys';
* @returns {Object} Returns `object`.
*/
function baseForOwnRight(object, iteratee) {
- return baseForRight(object, iteratee, keys);
+ return object && baseForRight(object, iteratee, keys);
}
export default baseForOwnRight;
diff --git a/internal/baseFunctions.js b/internal/baseFunctions.js
index 924748204..ef2d79140 100644
--- a/internal/baseFunctions.js
+++ b/internal/baseFunctions.js
@@ -1,4 +1,5 @@
-import isFunction from '../lang/isFunction';
+import arrayFilter from './arrayFilter';
+import isFunction from '../isFunction';
/**
* The base implementation of `_.functions` which creates an array of
@@ -10,18 +11,9 @@ import isFunction from '../lang/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]);
+ });
}
export default baseFunctions;
diff --git a/internal/baseGet.js b/internal/baseGet.js
index 8034d6db1..4292ed916 100644
--- a/internal/baseGet.js
+++ b/internal/baseGet.js
@@ -1,22 +1,17 @@
-import toObject from './toObject';
+import baseToPath from './baseToPath';
+import isKey from './isKey';
/**
- * 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..a2e44f345
--- /dev/null
+++ b/internal/baseHas.js
@@ -0,0 +1,26 @@
+/** 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);
+}
+
+export default baseHas;
diff --git a/internal/baseHasIn.js b/internal/baseHasIn.js
new file mode 100644
index 000000000..62ab0391c
--- /dev/null
+++ b/internal/baseHasIn.js
@@ -0,0 +1,13 @@
+/**
+ * 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);
+}
+
+export default baseHasIn;
diff --git a/internal/baseInRange.js b/internal/baseInRange.js
new file mode 100644
index 000000000..82636b272
--- /dev/null
+++ b/internal/baseInRange.js
@@ -0,0 +1,18 @@
+/* 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);
+}
+
+export default baseInRange;
diff --git a/internal/baseIndexOf.js b/internal/baseIndexOf.js
index 3e14bfefb..f23611cbf 100644
--- a/internal/baseIndexOf.js
+++ b/internal/baseIndexOf.js
@@ -1,7 +1,7 @@
import indexOfNaN from './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..980087c60
--- /dev/null
+++ b/internal/baseIntersection.js
@@ -0,0 +1,62 @@
+import SetCache from './SetCache';
+import arrayIncludes from './arrayIncludes';
+import arrayIncludesWith from './arrayIncludesWith';
+import arrayMap from './arrayMap';
+import baseUnary from './baseUnary';
+import cacheHas from './cacheHas';
+
+/**
+ * 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;
+}
+
+export default baseIntersection;
diff --git a/internal/baseInvoke.js b/internal/baseInvoke.js
new file mode 100644
index 000000000..ce6fc1665
--- /dev/null
+++ b/internal/baseInvoke.js
@@ -0,0 +1,28 @@
+import apply from './apply';
+import baseToPath from './baseToPath';
+import isKey from './isKey';
+import last from '../last';
+import parent from './parent';
+
+/**
+ * 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);
+}
+
+export default baseInvoke;
diff --git a/internal/baseIsEqual.js b/internal/baseIsEqual.js
index b594fc13f..7f06bb1e8 100644
--- a/internal/baseIsEqual.js
+++ b/internal/baseIsEqual.js
@@ -1,28 +1,30 @@
import baseIsEqualDeep from './baseIsEqualDeep';
-import isObject from '../lang/isObject';
-import isObjectLike from './isObjectLike';
+import isObject from '../isObject';
+import isObjectLike from '../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);
}
export default baseIsEqual;
diff --git a/internal/baseIsEqualDeep.js b/internal/baseIsEqualDeep.js
index 639f2a731..b6054bf83 100644
--- a/internal/baseIsEqualDeep.js
+++ b/internal/baseIsEqualDeep.js
@@ -1,26 +1,26 @@
+import Stack from './Stack';
import equalArrays from './equalArrays';
import equalByTag from './equalByTag';
import equalObjects from './equalObjects';
-import isArray from '../lang/isArray';
-import isTypedArray from '../lang/isTypedArray';
+import getTag from './getTag';
+import isArray from '../isArray';
+import isHostObject from './isHostObject';
+import isTypedArray from '../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
@@ -30,20 +30,19 @@ var objToString = objectProto.toString;
* @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) {
@@ -51,52 +50,34 @@ function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA,
}
}
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);
}
export default baseIsEqualDeep;
diff --git a/internal/baseIsFunction.js b/internal/baseIsFunction.js
deleted file mode 100644
index d0facc551..000000000
--- a/internal/baseIsFunction.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * 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;
-}
-
-export default baseIsFunction;
diff --git a/internal/baseIsMatch.js b/internal/baseIsMatch.js
index a47a8d29d..8b68cdcd2 100644
--- a/internal/baseIsMatch.js
+++ b/internal/baseIsMatch.js
@@ -1,17 +1,21 @@
+import Stack from './Stack';
import baseIsEqual from './baseIsEqual';
-import toObject from './toObject';
+
+/** 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;
@@ -19,7 +23,7 @@ function baseIsMatch(object, matchData, customizer) {
if (object == null) {
return !length;
}
- object = toObject(object);
+ object = Object(object);
while (index--) {
var data = matchData[index];
if ((noCustomizer && data[2])
@@ -40,8 +44,10 @@ function baseIsMatch(object, matchData, customizer) {
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..324184ba9
--- /dev/null
+++ b/internal/baseIteratee.js
@@ -0,0 +1,30 @@
+import baseMatches from './baseMatches';
+import baseMatchesProperty from './baseMatchesProperty';
+import identity from '../identity';
+import isArray from '../isArray';
+import property from '../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);
+}
+
+export default baseIteratee;
diff --git a/internal/baseKeys.js b/internal/baseKeys.js
new file mode 100644
index 000000000..a683bc126
--- /dev/null
+++ b/internal/baseKeys.js
@@ -0,0 +1,17 @@
+/* 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));
+}
+
+export default baseKeys;
diff --git a/internal/baseKeysIn.js b/internal/baseKeysIn.js
new file mode 100644
index 000000000..0b0979794
--- /dev/null
+++ b/internal/baseKeysIn.js
@@ -0,0 +1,36 @@
+import Reflect from './Reflect';
+import iteratorToArray from './iteratorToArray';
+
+/** 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));
+ };
+}
+
+export default baseKeysIn;
diff --git a/internal/baseMap.js b/internal/baseMap.js
index 6f6cd346f..3b7d357ee 100644
--- a/internal/baseMap.js
+++ b/internal/baseMap.js
@@ -1,12 +1,11 @@
import baseEach from './baseEach';
-import isArrayLike from './isArrayLike';
+import isArrayLike from '../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 d7b108455..93df4341d 100644
--- a/internal/baseMatches.js
+++ b/internal/baseMatches.js
@@ -1,9 +1,8 @@
import baseIsMatch from './baseIsMatch';
import getMatchData from './getMatchData';
-import toObject from './toObject';
/**
- * 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.
@@ -19,11 +18,12 @@ function baseMatches(source) {
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 7f423546b..0bec4280f 100644
--- a/internal/baseMatchesProperty.js
+++ b/internal/baseMatchesProperty.js
@@ -1,44 +1,25 @@
-import baseGet from './baseGet';
import baseIsEqual from './baseIsEqual';
-import baseSlice from './baseSlice';
-import isArray from '../lang/isArray';
-import isKey from './isKey';
-import isStrictComparable from './isStrictComparable';
-import last from '../array/last';
-import toObject from './toObject';
-import toPath from './toPath';
+import get from '../get';
+import hasIn from '../hasIn';
+
+/** 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 703002da4..93202a71d 100644
--- a/internal/baseMerge.js
+++ b/internal/baseMerge.js
@@ -1,56 +1,43 @@
+import Stack from './Stack';
import arrayEach from './arrayEach';
+import assignMergeValue from './assignMergeValue';
import baseMergeDeep from './baseMergeDeep';
-import isArray from '../lang/isArray';
-import isArrayLike from './isArrayLike';
-import isObject from '../lang/isObject';
-import isObjectLike from './isObjectLike';
-import isTypedArray from '../lang/isTypedArray';
-import keys from '../object/keys';
+import isArray from '../isArray';
+import isObject from '../isObject';
+import isTypedArray from '../isTypedArray';
+import keysIn from '../keysIn';
/**
- * 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;
}
export default baseMerge;
diff --git a/internal/baseMergeDeep.js b/internal/baseMergeDeep.js
index 3545db5cb..9da5de47a 100644
--- a/internal/baseMergeDeep.js
+++ b/internal/baseMergeDeep.js
@@ -1,10 +1,14 @@
-import arrayCopy from './arrayCopy';
-import isArguments from '../lang/isArguments';
-import isArray from '../lang/isArray';
-import isArrayLike from './isArrayLike';
-import isPlainObject from '../lang/isPlainObject';
-import isTypedArray from '../lang/isTypedArray';
-import toPlainObject from '../lang/toPlainObject';
+import assignMergeValue from './assignMergeValue';
+import baseClone from './baseClone';
+import copyArray from './copyArray';
+import isArguments from '../isArguments';
+import isArray from '../isArray';
+import isArrayLikeObject from '../isArrayLikeObject';
+import isFunction from '../isFunction';
+import isObject from '../isObject';
+import isPlainObject from '../isPlainObject';
+import isTypedArray from '../isTypedArray';
+import toPlainObject from '../toPlainObject';
/**
* A specialized version of `baseMerge` for arrays and objects which performs
@@ -16,52 +20,44 @@ import toPlainObject from '../lang/toPlainObject';
* @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);
}
export default baseMergeDeep;
diff --git a/internal/baseOrderBy.js b/internal/baseOrderBy.js
new file mode 100644
index 000000000..41dc37556
--- /dev/null
+++ b/internal/baseOrderBy.js
@@ -0,0 +1,36 @@
+import arrayMap from './arrayMap';
+import baseIteratee from './baseIteratee';
+import baseMap from './baseMap';
+import baseSortBy from './baseSortBy';
+import compareMultiple from './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);
+ });
+}
+
+export default baseOrderBy;
diff --git a/internal/basePick.js b/internal/basePick.js
new file mode 100644
index 000000000..95f1d145b
--- /dev/null
+++ b/internal/basePick.js
@@ -0,0 +1,22 @@
+import arrayReduce from './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;
+ }, {});
+}
+
+export default basePick;
diff --git a/internal/basePickBy.js b/internal/basePickBy.js
new file mode 100644
index 000000000..24be0cfe8
--- /dev/null
+++ b/internal/basePickBy.js
@@ -0,0 +1,21 @@
+import baseForIn from './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;
+}
+
+export default basePickBy;
diff --git a/internal/basePropertyDeep.js b/internal/basePropertyDeep.js
index 4644bd6c0..ae817578c 100644
--- a/internal/basePropertyDeep.js
+++ b/internal/basePropertyDeep.js
@@ -1,5 +1,4 @@
import baseGet from './baseGet';
-import toPath from './toPath';
/**
* A specialized version of `baseProperty` which supports deep paths.
@@ -9,10 +8,8 @@ import toPath from './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..68c8e5a12
--- /dev/null
+++ b/internal/basePullAll.js
@@ -0,0 +1,15 @@
+import basePullAllBy from './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);
+}
+
+export default basePullAll;
diff --git a/internal/basePullAllBy.js b/internal/basePullAllBy.js
new file mode 100644
index 000000000..fd08cd9e3
--- /dev/null
+++ b/internal/basePullAllBy.js
@@ -0,0 +1,43 @@
+import arrayMap from './arrayMap';
+import baseIndexOf from './baseIndexOf';
+
+/** Used for built-in method references. */
+var arrayProto = Array.prototype;
+
+/** Built-in value references. */
+var splice = arrayProto.splice;
+
+/**
+ * The base implementation of `_.pullAllBy` without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to remove.
+ * @param {Function} [iteratee] The iteratee invoked per element.
+ * @returns {Array} Returns `array`.
+ */
+function basePullAllBy(array, values, iteratee) {
+ var index = -1,
+ length = values.length,
+ seen = array;
+
+ if (iteratee) {
+ seen = arrayMap(array, function(value) { return iteratee(value); });
+ }
+ while (++index < length) {
+ var fromIndex = 0,
+ value = values[index],
+ computed = iteratee ? iteratee(value) : value;
+
+ while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
+ if (seen !== array) {
+ splice.call(seen, fromIndex, 1);
+ }
+ splice.call(array, fromIndex, 1);
+ }
+ }
+ return array;
+}
+
+export default basePullAllBy;
diff --git a/internal/basePullAt.js b/internal/basePullAt.js
index 4cb090d57..93dcacb46 100644
--- a/internal/basePullAt.js
+++ b/internal/basePullAt.js
@@ -1,14 +1,18 @@
+import baseToPath from './baseToPath';
import isIndex from './isIndex';
+import isKey from './isKey';
+import last from '../last';
+import parent from './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 +20,27 @@ var splice = arrayProto.splice;
* @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 f4aa8b0a8..0e6cf0302 100644
--- a/internal/baseRandom.js
+++ b/internal/baseRandom.js
@@ -1,18 +1,18 @@
-/* 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));
}
export default baseRandom;
diff --git a/internal/baseRange.js b/internal/baseRange.js
new file mode 100644
index 000000000..0f08adf71
--- /dev/null
+++ b/internal/baseRange.js
@@ -0,0 +1,28 @@
+/* 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;
+}
+
+export default baseRange;
diff --git a/internal/baseReduce.js b/internal/baseReduce.js
index 2a7e51afb..d81fc728a 100644
--- a/internal/baseReduce.js
+++ b/internal/baseReduce.js
@@ -1,14 +1,13 @@
/**
- * 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..e73dd5847
--- /dev/null
+++ b/internal/baseSet.js
@@ -0,0 +1,43 @@
+import assignValue from './assignValue';
+import baseToPath from './baseToPath';
+import isIndex from './isIndex';
+import isKey from './isKey';
+import isObject from '../isObject';
+
+/**
+ * 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;
+}
+
+export default baseSet;
diff --git a/internal/baseSetData.js b/internal/baseSetData.js
index c2364b97a..1fd920eef 100644
--- a/internal/baseSetData.js
+++ b/internal/baseSetData.js
@@ -1,4 +1,4 @@
-import identity from '../utility/identity';
+import identity from '../identity';
import metaMap from './metaMap';
/**
diff --git a/internal/baseSlice.js b/internal/baseSlice.js
index d26a4d439..bd9c69b71 100644
--- a/internal/baseSlice.js
+++ b/internal/baseSlice.js
@@ -11,11 +11,10 @@ function baseSlice(array, start, end) {
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 014bff510..f33f6ea2c 100644
--- a/internal/baseSome.js
+++ b/internal/baseSome.js
@@ -1,14 +1,12 @@
import baseEach from './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 192a459d7..000000000
--- a/internal/baseSortByOrder.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import arrayMap from './arrayMap';
-import baseCallback from './baseCallback';
-import baseMap from './baseMap';
-import baseSortBy from './baseSortBy';
-import compareMultiple from './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);
- });
-}
-
-export default baseSortByOrder;
diff --git a/internal/binaryIndex.js b/internal/baseSortedIndex.js
similarity index 71%
rename from internal/binaryIndex.js
rename to internal/baseSortedIndex.js
index 37024e29d..4e19323ff 100644
--- a/internal/binaryIndex.js
+++ b/internal/baseSortedIndex.js
@@ -1,12 +1,13 @@
-import binaryIndexBy from './binaryIndexBy';
-import identity from '../utility/identity';
+import baseSortedIndexBy from './baseSortedIndexBy';
+import identity from '../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
@@ -16,7 +17,7 @@ var MAX_ARRAY_LENGTH = 4294967295,
* @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;
@@ -33,7 +34,7 @@ function binaryIndex(array, value, retHighest) {
}
return high;
}
- return binaryIndexBy(array, value, identity, retHighest);
+ return baseSortedIndexBy(array, value, identity, retHighest);
}
-export default binaryIndex;
+export default baseSortedIndex;
diff --git a/internal/binaryIndexBy.js b/internal/baseSortedIndexBy.js
similarity index 73%
rename from internal/binaryIndexBy.js
rename to internal/baseSortedIndexBy.js
index 1541a625f..8c035ec3b 100644
--- a/internal/binaryIndexBy.js
+++ b/internal/baseSortedIndexBy.js
@@ -1,25 +1,24 @@
-/* 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,
@@ -54,4 +53,4 @@ function binaryIndexBy(array, value, iteratee, retHighest) {
return nativeMin(high, MAX_ARRAY_INDEX);
}
-export default binaryIndexBy;
+export default baseSortedIndexBy;
diff --git a/internal/baseSortedUniq.js b/internal/baseSortedUniq.js
new file mode 100644
index 000000000..086c6b8a9
--- /dev/null
+++ b/internal/baseSortedUniq.js
@@ -0,0 +1,14 @@
+import baseSortedUniqBy from './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);
+}
+
+export default baseSortedUniq;
diff --git a/internal/baseSortedUniqBy.js b/internal/baseSortedUniqBy.js
new file mode 100644
index 000000000..71e552e51
--- /dev/null
+++ b/internal/baseSortedUniqBy.js
@@ -0,0 +1,33 @@
+import eq from '../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;
+}
+
+export default baseSortedUniqBy;
diff --git a/internal/baseSum.js b/internal/baseSum.js
index 53953c10e..c0e4ea5e3 100644
--- a/internal/baseSum.js
+++ b/internal/baseSum.js
@@ -1,19 +1,22 @@
-import baseEach from './baseEach';
-
/**
- * 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..d5d0e274f
--- /dev/null
+++ b/internal/baseTimes.js
@@ -0,0 +1,20 @@
+/**
+ * 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;
+}
+
+export default baseTimes;
diff --git a/internal/baseToPairs.js b/internal/baseToPairs.js
new file mode 100644
index 000000000..ed98cf1cb
--- /dev/null
+++ b/internal/baseToPairs.js
@@ -0,0 +1,18 @@
+import arrayMap from './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]];
+ });
+}
+
+export default baseToPairs;
diff --git a/internal/baseToPath.js b/internal/baseToPath.js
new file mode 100644
index 000000000..de15bc6aa
--- /dev/null
+++ b/internal/baseToPath.js
@@ -0,0 +1,16 @@
+import isArray from '../isArray';
+import stringToPath from './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);
+}
+
+export default baseToPath;
diff --git a/internal/baseToString.js b/internal/baseToString.js
deleted file mode 100644
index c9d99b53d..000000000
--- a/internal/baseToString.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * 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 + '');
-}
-
-export default baseToString;
diff --git a/internal/baseUnary.js b/internal/baseUnary.js
new file mode 100644
index 000000000..0419362b2
--- /dev/null
+++ b/internal/baseUnary.js
@@ -0,0 +1,14 @@
+/**
+ * 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);
+ };
+}
+
+export default baseUnary;
diff --git a/internal/baseUniq.js b/internal/baseUniq.js
index bc22b48ff..17de7c2b0 100644
--- a/internal/baseUniq.js
+++ b/internal/baseUniq.js
@@ -1,41 +1,52 @@
-import baseIndexOf from './baseIndexOf';
-import cacheIndexOf from './cacheIndexOf';
-import createCache from './createCache';
+import SetCache from './SetCache';
+import arrayIncludes from './arrayIncludes';
+import arrayIncludesWith from './arrayIncludesWith';
+import cacheHas from './cacheHas';
+import createSet from './createSet';
+import setToArray from './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) {
@@ -47,8 +58,8 @@ function baseUniq(array, iteratee) {
}
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..b1c740231
--- /dev/null
+++ b/internal/baseUnset.js
@@ -0,0 +1,22 @@
+import baseToPath from './baseToPath';
+import has from '../has';
+import isKey from './isKey';
+import last from '../last';
+import parent from './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;
+}
+
+export default baseUnset;
diff --git a/internal/baseValues.js b/internal/baseValues.js
index 935114af7..37a526e5d 100644
--- a/internal/baseValues.js
+++ b/internal/baseValues.js
@@ -1,3 +1,5 @@
+import arrayMap from './arrayMap';
+
/**
* The base implementation of `_.values` and `_.valuesIn` which creates an
* array of `object` property values corresponding to the property names
@@ -9,14 +11,9 @@
* @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];
+ });
}
export default baseValues;
diff --git a/internal/baseWhile.js b/internal/baseWhile.js
index 997f111fa..045d539db 100644
--- a/internal/baseWhile.js
+++ b/internal/baseWhile.js
@@ -1,8 +1,8 @@
import baseSlice from './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 @@ function baseWhile(array, predicate, isDrop, fromRight) {
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 7c5c3dc83..fad9d936f 100644
--- a/internal/baseWrapperValue.js
+++ b/internal/baseWrapperValue.js
@@ -1,5 +1,6 @@
import LazyWrapper from './LazyWrapper';
import arrayPush from './arrayPush';
+import arrayReduce from './arrayReduce';
/**
* The base implementation of `wrapperValue` which returns the result of
@@ -8,7 +9,7 @@ import arrayPush from './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) {
@@ -16,14 +17,9 @@ function baseWrapperValue(value, actions) {
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);
}
export default baseWrapperValue;
diff --git a/internal/baseXor.js b/internal/baseXor.js
new file mode 100644
index 000000000..96e844191
--- /dev/null
+++ b/internal/baseXor.js
@@ -0,0 +1,30 @@
+import arrayPush from './arrayPush';
+import baseDifference from './baseDifference';
+import baseUniq from './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) : [];
+}
+
+export default baseXor;
diff --git a/internal/bindCallback.js b/internal/bindCallback.js
deleted file mode 100644
index ca3397e8a..000000000
--- a/internal/bindCallback.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import identity from '../utility/identity';
-
-/**
- * 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);
- };
-}
-
-export default bindCallback;
diff --git a/internal/bufferClone.js b/internal/bufferClone.js
deleted file mode 100644
index acf2f60f1..000000000
--- a/internal/bufferClone.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import root from './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;
-}
-
-export default bufferClone;
diff --git a/internal/cacheHas.js b/internal/cacheHas.js
new file mode 100644
index 000000000..a3d401ff6
--- /dev/null
+++ b/internal/cacheHas.js
@@ -0,0 +1,25 @@
+import isKeyable from './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);
+}
+
+export default cacheHas;
diff --git a/internal/cacheIndexOf.js b/internal/cacheIndexOf.js
deleted file mode 100644
index 700fc3caa..000000000
--- a/internal/cacheIndexOf.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import isObject from '../lang/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;
-}
-
-export default cacheIndexOf;
diff --git a/internal/cachePush.js b/internal/cachePush.js
index 93a60cfe7..27b972253 100644
--- a/internal/cachePush.js
+++ b/internal/cachePush.js
@@ -1,7 +1,10 @@
-import isObject from '../lang/isObject';
+import isKeyable from './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 @@ import isObject from '../lang/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..2a8f730ad
--- /dev/null
+++ b/internal/charsEndIndex.js
@@ -0,0 +1,19 @@
+import baseIndexOf from './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;
+}
+
+export default charsEndIndex;
diff --git a/internal/charsLeftIndex.js b/internal/charsLeftIndex.js
deleted file mode 100644
index cfe5fc2e6..000000000
--- a/internal/charsLeftIndex.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * 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;
-}
-
-export default charsLeftIndex;
diff --git a/internal/charsRightIndex.js b/internal/charsRightIndex.js
deleted file mode 100644
index 2cc439637..000000000
--- a/internal/charsRightIndex.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * 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;
-}
-
-export default charsRightIndex;
diff --git a/internal/charsStartIndex.js b/internal/charsStartIndex.js
new file mode 100644
index 000000000..6ceb43491
--- /dev/null
+++ b/internal/charsStartIndex.js
@@ -0,0 +1,20 @@
+import baseIndexOf from './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;
+}
+
+export default charsStartIndex;
diff --git a/internal/checkGlobal.js b/internal/checkGlobal.js
new file mode 100644
index 000000000..523609a94
--- /dev/null
+++ b/internal/checkGlobal.js
@@ -0,0 +1,12 @@
+/**
+ * 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;
+}
+
+export default checkGlobal;
diff --git a/internal/cloneBuffer.js b/internal/cloneBuffer.js
new file mode 100644
index 000000000..5e56ba0ac
--- /dev/null
+++ b/internal/cloneBuffer.js
@@ -0,0 +1,19 @@
+import Uint8Array from './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;
+}
+
+export default cloneBuffer;
diff --git a/internal/cloneMap.js b/internal/cloneMap.js
new file mode 100644
index 000000000..cb54bdaa1
--- /dev/null
+++ b/internal/cloneMap.js
@@ -0,0 +1,17 @@
+import addMapEntry from './addMapEntry';
+import arrayReduce from './arrayReduce';
+import mapToArray from './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);
+}
+
+export default cloneMap;
diff --git a/internal/cloneRegExp.js b/internal/cloneRegExp.js
new file mode 100644
index 000000000..4942fa44b
--- /dev/null
+++ b/internal/cloneRegExp.js
@@ -0,0 +1,19 @@
+/** 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;
+}
+
+export default cloneRegExp;
diff --git a/internal/cloneSet.js b/internal/cloneSet.js
new file mode 100644
index 000000000..44c6f7c48
--- /dev/null
+++ b/internal/cloneSet.js
@@ -0,0 +1,17 @@
+import addSetEntry from './addSetEntry';
+import arrayReduce from './arrayReduce';
+import setToArray from './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);
+}
+
+export default cloneSet;
diff --git a/internal/cloneSymbol.js b/internal/cloneSymbol.js
new file mode 100644
index 000000000..4bc4c587a
--- /dev/null
+++ b/internal/cloneSymbol.js
@@ -0,0 +1,18 @@
+import _Symbol from './_Symbol';
+
+/** 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)) : {};
+}
+
+export default cloneSymbol;
diff --git a/internal/cloneTypedArray.js b/internal/cloneTypedArray.js
new file mode 100644
index 000000000..95c2c40ee
--- /dev/null
+++ b/internal/cloneTypedArray.js
@@ -0,0 +1,18 @@
+import cloneBuffer from './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);
+}
+
+export default cloneTypedArray;
diff --git a/internal/compareAscending.js b/internal/compareAscending.js
index a908e8080..8d048f9aa 100644
--- a/internal/compareAscending.js
+++ b/internal/compareAscending.js
@@ -1,16 +1,33 @@
-import baseCompareAscending from './baseCompareAscending';
-
/**
- * 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;
}
export default compareAscending;
diff --git a/internal/compareMultiple.js b/internal/compareMultiple.js
index ad3e1721e..323c24216 100644
--- a/internal/compareMultiple.js
+++ b/internal/compareMultiple.js
@@ -1,17 +1,17 @@
-import baseCompareAscending from './baseCompareAscending';
+import compareAscending from './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 @@ function compareMultiple(object, other, orders) {
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 d89463f9a..854f489aa 100644
--- a/internal/composeArgs.js
+++ b/internal/composeArgs.js
@@ -1,4 +1,4 @@
-/* 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 0886f3cbb..48b059c8c 100644
--- a/internal/composeArgsRight.js
+++ b/internal/composeArgsRight.js
@@ -1,4 +1,4 @@
-/* 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 86%
rename from internal/arrayCopy.js
rename to internal/copyArray.js
index 0b34ccb98..b29b71e95 100644
--- a/internal/arrayCopy.js
+++ b/internal/copyArray.js
@@ -6,7 +6,7 @@
* @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;
@@ -17,4 +17,4 @@ function arrayCopy(source, array) {
return array;
}
-export default arrayCopy;
+export default copyArray;
diff --git a/internal/baseCopy.js b/internal/copyObject.js
similarity index 53%
rename from internal/baseCopy.js
rename to internal/copyObject.js
index be5759522..1e7050819 100644
--- a/internal/baseCopy.js
+++ b/internal/copyObject.js
@@ -1,3 +1,5 @@
+import copyObjectWith from './copyObjectWith';
+
/**
* Copies properties of `source` to `object`.
*
@@ -7,17 +9,8 @@
* @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);
}
-export default baseCopy;
+export default copyObject;
diff --git a/internal/copyObjectWith.js b/internal/copyObjectWith.js
new file mode 100644
index 000000000..46adee9b3
--- /dev/null
+++ b/internal/copyObjectWith.js
@@ -0,0 +1,29 @@
+import assignValue from './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;
+}
+
+export default copyObjectWith;
diff --git a/internal/copySymbols.js b/internal/copySymbols.js
new file mode 100644
index 000000000..854798050
--- /dev/null
+++ b/internal/copySymbols.js
@@ -0,0 +1,16 @@
+import copyObject from './copyObject';
+import getSymbols from './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);
+}
+
+export default copySymbols;
diff --git a/internal/createAggregator.js b/internal/createAggregator.js
index 5aee6a0df..f53259456 100644
--- a/internal/createAggregator.js
+++ b/internal/createAggregator.js
@@ -1,9 +1,9 @@
-import baseCallback from './baseCallback';
import baseEach from './baseEach';
-import isArray from '../lang/isArray';
+import baseIteratee from './baseIteratee';
+import isArray from '../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.
@@ -11,9 +11,9 @@ import isArray from '../lang/isArray';
* @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,
@@ -21,11 +21,11 @@ function createAggregator(setter, initializer) {
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 184c2a317..0dd9da9b2 100644
--- a/internal/createAssigner.js
+++ b/internal/createAssigner.js
@@ -1,33 +1,26 @@
-import bindCallback from './bindCallback';
import isIterateeCall from './isIterateeCall';
-import restParam from '../function/restParam';
+import rest from '../rest';
/**
- * 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 4a28c9351..f3b527edb 100644
--- a/internal/createBaseEach.js
+++ b/internal/createBaseEach.js
@@ -1,6 +1,4 @@
-import getLength from './getLength';
-import isLength from './isLength';
-import toObject from './toObject';
+import isArrayLike from '../isArrayLike';
/**
* Creates a `baseEach` or `baseEachRight` function.
@@ -12,12 +10,15 @@ import toObject from './toObject';
*/
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 0bc9540b2..97249e7de 100644
--- a/internal/createBaseFor.js
+++ b/internal/createBaseFor.js
@@ -1,7 +1,5 @@
-import toObject from './toObject';
-
/**
- * 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 +7,13 @@ import toObject from './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..6693eaafa
--- /dev/null
+++ b/internal/createBaseWrapper.js
@@ -0,0 +1,28 @@
+import createCtorWrapper from './createCtorWrapper';
+import root from './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;
+}
+
+export default createBaseWrapper;
diff --git a/internal/createBindWrapper.js b/internal/createBindWrapper.js
deleted file mode 100644
index 19cd166ce..000000000
--- a/internal/createBindWrapper.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import createCtorWrapper from './createCtorWrapper';
-import root from './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;
-}
-
-export default createBindWrapper;
diff --git a/internal/createCache.js b/internal/createCache.js
deleted file mode 100644
index f7606a1cf..000000000
--- a/internal/createCache.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import SetCache from './SetCache';
-import getNative from './getNative';
-import root from './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;
-}
-
-export default createCache;
diff --git a/internal/createCaseFirst.js b/internal/createCaseFirst.js
new file mode 100644
index 000000000..419286fcb
--- /dev/null
+++ b/internal/createCaseFirst.js
@@ -0,0 +1,34 @@
+import stringToArray from './stringToArray';
+import toString from '../toString';
+
+/** 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;
+ };
+}
+
+export default createCaseFirst;
diff --git a/internal/createCompounder.js b/internal/createCompounder.js
index 144dd09a6..6178cdab3 100644
--- a/internal/createCompounder.js
+++ b/internal/createCompounder.js
@@ -1,9 +1,9 @@
-import deburr from '../string/deburr';
-import words from '../string/words';
+import arrayReduce from './arrayReduce';
+import deburr from '../deburr';
+import words from '../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.
@@ -11,15 +11,7 @@ import words from '../string/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 b05cb162a..331cd0f08 100644
--- a/internal/createCtorWrapper.js
+++ b/internal/createCtorWrapper.js
@@ -1,5 +1,5 @@
import baseCreate from './baseCreate';
-import isObject from '../lang/isObject';
+import isObject from '../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 03c8c6cce..000000000
--- a/internal/createCurry.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import createWrapper from './createWrapper';
-import isIterateeCall from './isIterateeCall';
-
-/**
- * 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;
-}
-
-export default createCurry;
diff --git a/internal/createCurryWrapper.js b/internal/createCurryWrapper.js
new file mode 100644
index 000000000..1fb8b1f86
--- /dev/null
+++ b/internal/createCurryWrapper.js
@@ -0,0 +1,42 @@
+import apply from './apply';
+import createCtorWrapper from './createCtorWrapper';
+import createHybridWrapper from './createHybridWrapper';
+import createRecurryWrapper from './createRecurryWrapper';
+import replaceHolders from './replaceHolders';
+import root from './root';
+
+/**
+ * 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;
+}
+
+export default createCurryWrapper;
diff --git a/internal/createDefaults.js b/internal/createDefaults.js
deleted file mode 100644
index 5fa865d63..000000000
--- a/internal/createDefaults.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import restParam from '../function/restParam';
-
-/**
- * Creates a `_.defaults` or `_.defaultsDeep` function.
- *
- * @private
- * @param {Function} assigner The function to assign values.
- * @param {Function} customizer The function to customize assigned values.
- * @returns {Function} Returns the new defaults function.
- */
-function createDefaults(assigner, customizer) {
- return restParam(function(args) {
- var object = args[0];
- if (object == null) {
- return object;
- }
- args.push(customizer);
- return assigner.apply(undefined, args);
- });
-}
-
-export default createDefaults;
diff --git a/internal/createExtremum.js b/internal/createExtremum.js
deleted file mode 100644
index 82ad48d0f..000000000
--- a/internal/createExtremum.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import arrayExtremum from './arrayExtremum';
-import baseCallback from './baseCallback';
-import baseExtremum from './baseExtremum';
-import isArray from '../lang/isArray';
-import isIterateeCall from './isIterateeCall';
-import toIterable from './toIterable';
-
-/**
- * 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);
- };
-}
-
-export default createExtremum;
diff --git a/internal/createFind.js b/internal/createFind.js
deleted file mode 100644
index 8445c9651..000000000
--- a/internal/createFind.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import baseCallback from './baseCallback';
-import baseFind from './baseFind';
-import baseFindIndex from './baseFindIndex';
-import isArray from '../lang/isArray';
-
-/**
- * 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);
- };
-}
-
-export default createFind;
diff --git a/internal/createFindIndex.js b/internal/createFindIndex.js
deleted file mode 100644
index a9b8cf7cc..000000000
--- a/internal/createFindIndex.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import baseCallback from './baseCallback';
-import baseFindIndex from './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);
- };
-}
-
-export default createFindIndex;
diff --git a/internal/createFindKey.js b/internal/createFindKey.js
deleted file mode 100644
index f51ac2b31..000000000
--- a/internal/createFindKey.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import baseCallback from './baseCallback';
-import baseFind from './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);
- };
-}
-
-export default createFindKey;
diff --git a/internal/createFlow.js b/internal/createFlow.js
index 970415842..dd0371a58 100644
--- a/internal/createFlow.js
+++ b/internal/createFlow.js
@@ -1,8 +1,10 @@
import LodashWrapper from './LodashWrapper';
+import baseFlatten from './baseFlatten';
import getData from './getData';
import getFuncName from './getFuncName';
-import isArray from '../lang/isArray';
+import isArray from '../isArray';
import isLaziable from './isLaziable';
+import rest from '../rest';
/** Used to compose bitmasks for wrapper metadata. */
var CURRY_FLAG = 8,
@@ -24,23 +26,26 @@ var FUNC_ERROR_TEXT = 'Expected a function';
* @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];
@@ -68,7 +73,7 @@ function createFlow(fromRight) {
}
return result;
};
- };
+ });
}
export default createFlow;
diff --git a/internal/createForEach.js b/internal/createForEach.js
deleted file mode 100644
index fd213aefe..000000000
--- a/internal/createForEach.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import bindCallback from './bindCallback';
-import isArray from '../lang/isArray';
-
-/**
- * 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));
- };
-}
-
-export default createForEach;
diff --git a/internal/createForIn.js b/internal/createForIn.js
deleted file mode 100644
index 22ffa4e93..000000000
--- a/internal/createForIn.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import bindCallback from './bindCallback';
-import keysIn from '../object/keysIn';
-
-/**
- * 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);
- };
-}
-
-export default createForIn;
diff --git a/internal/createForOwn.js b/internal/createForOwn.js
deleted file mode 100644
index cf912cfdf..000000000
--- a/internal/createForOwn.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import bindCallback from './bindCallback';
-
-/**
- * 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);
- };
-}
-
-export default createForOwn;
diff --git a/internal/createHybridWrapper.js b/internal/createHybridWrapper.js
index 5ceed61aa..be81ece05 100644
--- a/internal/createHybridWrapper.js
+++ b/internal/createHybridWrapper.js
@@ -1,33 +1,26 @@
-import arrayCopy from './arrayCopy';
import composeArgs from './composeArgs';
import composeArgsRight from './composeArgsRight';
import createCtorWrapper from './createCtorWrapper';
-import isLaziable from './isLaziable';
+import createRecurryWrapper from './createRecurryWrapper';
import reorder from './reorder';
import replaceHolders from './replaceHolders';
import root from './root';
-import setData from './setData';
/** 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.
@@ -43,13 +36,11 @@ function createHybridWrapper(func, bitmask, thisArg, partials, holders, partials
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);
@@ -69,27 +60,7 @@ function createHybridWrapper(func, bitmask, thisArg, partials, holders, partials
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,
@@ -97,12 +68,14 @@ function createHybridWrapper(func, bitmask, thisArg, partials, holders, partials
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 e0d1b8e30..000000000
--- a/internal/createObjectMapper.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import baseCallback from './baseCallback';
-import baseForOwn from './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;
- };
-}
-
-export default createObjectMapper;
diff --git a/internal/createOver.js b/internal/createOver.js
new file mode 100644
index 000000000..0722c595e
--- /dev/null
+++ b/internal/createOver.js
@@ -0,0 +1,26 @@
+import apply from './apply';
+import arrayMap from './arrayMap';
+import baseFlatten from './baseFlatten';
+import baseIteratee from './baseIteratee';
+import rest from '../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);
+ });
+ });
+ });
+}
+
+export default createOver;
diff --git a/internal/createPadDir.js b/internal/createPadDir.js
deleted file mode 100644
index e2ee0d72b..000000000
--- a/internal/createPadDir.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import baseToString from './baseToString';
-import createPadding from './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);
- };
-}
-
-export default createPadDir;
diff --git a/internal/createPadding.js b/internal/createPadding.js
index f7a0fbf4f..5b5e1620f 100644
--- a/internal/createPadding.js
+++ b/internal/createPadding.js
@@ -1,30 +1,46 @@
-import repeat from '../string/repeat';
-import root from './root';
+import repeat from '../repeat';
+import stringSize from './stringSize';
+import stringToArray from './stringToArray';
+import toInteger from '../toInteger';
-/* Native method references for those with the same name as other `lodash` methods. */
-var nativeCeil = Math.ceil,
- nativeIsFinite = root.isFinite;
+/** 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);
}
export default createPadding;
diff --git a/internal/createPartial.js b/internal/createPartial.js
deleted file mode 100644
index fb268ade2..000000000
--- a/internal/createPartial.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import createWrapper from './createWrapper';
-import replaceHolders from './replaceHolders';
-import restParam from '../function/restParam';
-
-/**
- * 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;
-}
-
-export default createPartial;
diff --git a/internal/createPartialWrapper.js b/internal/createPartialWrapper.js
index f9635fc02..42e2b0d67 100644
--- a/internal/createPartialWrapper.js
+++ b/internal/createPartialWrapper.js
@@ -1,3 +1,4 @@
+import apply from './apply';
import createCtorWrapper from './createCtorWrapper';
import root from './root';
@@ -5,29 +6,28 @@ import root from './root';
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];
@@ -35,8 +35,7 @@ function createPartialWrapper(func, bitmask, thisArg, partials) {
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..b26c7670c
--- /dev/null
+++ b/internal/createRange.js
@@ -0,0 +1,31 @@
+import baseRange from './baseRange';
+import isIterateeCall from './isIterateeCall';
+import toNumber from '../toNumber';
+
+/**
+ * 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);
+ };
+}
+
+export default createRange;
diff --git a/internal/createRecurryWrapper.js b/internal/createRecurryWrapper.js
new file mode 100644
index 000000000..127dfdb9a
--- /dev/null
+++ b/internal/createRecurryWrapper.js
@@ -0,0 +1,53 @@
+import copyArray from './copyArray';
+import isLaziable from './isLaziable';
+import setData from './setData';
+
+/** 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;
+}
+
+export default createRecurryWrapper;
diff --git a/internal/createReduce.js b/internal/createReduce.js
deleted file mode 100644
index 66c99fde2..000000000
--- a/internal/createReduce.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import baseCallback from './baseCallback';
-import baseReduce from './baseReduce';
-import isArray from '../lang/isArray';
-
-/**
- * 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);
- };
-}
-
-export default createReduce;
diff --git a/internal/createRound.js b/internal/createRound.js
index 27a759f2a..a197b70e2 100644
--- a/internal/createRound.js
+++ b/internal/createRound.js
@@ -1,8 +1,9 @@
-/** Native method references. */
-var pow = Math.pow;
+import toInteger from '../toInteger';
+import toNumber from '../toNumber';
+import toString from '../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.
@@ -11,10 +12,16 @@ var pow = Math.pow;
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..63536c8d8
--- /dev/null
+++ b/internal/createSet.js
@@ -0,0 +1,15 @@
+import Set from './Set';
+import noop from '../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);
+};
+
+export default createSet;
diff --git a/internal/createSortedIndex.js b/internal/createSortedIndex.js
deleted file mode 100644
index b7807bba0..000000000
--- a/internal/createSortedIndex.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import baseCallback from './baseCallback';
-import binaryIndex from './binaryIndex';
-import binaryIndexBy from './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);
- };
-}
-
-export default createSortedIndex;
diff --git a/internal/createWrapper.js b/internal/createWrapper.js
index bc4d6eacf..e5ba76744 100644
--- a/internal/createWrapper.js
+++ b/internal/createWrapper.js
@@ -1,21 +1,25 @@
import baseSetData from './baseSetData';
-import createBindWrapper from './createBindWrapper';
+import createBaseWrapper from './createBaseWrapper';
+import createCurryWrapper from './createCurryWrapper';
import createHybridWrapper from './createHybridWrapper';
import createPartialWrapper from './createPartialWrapper';
import getData from './getData';
import mergeData from './mergeData';
import setData from './setData';
+import toInteger from '../toInteger';
/** 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;
/**
@@ -23,8 +27,8 @@ var nativeMax = Math.max;
* `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`
@@ -53,7 +57,10 @@ function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, a
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;
@@ -65,17 +72,25 @@ function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, a
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 f94e2f3e4..76f8f302b 100644
--- a/internal/equalArrays.js
+++ b/internal/equalArrays.js
@@ -1,5 +1,9 @@
import arraySome from './arraySome';
+/** 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.
@@ -8,44 +12,61 @@ import arraySome from './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;
}
export default equalArrays;
diff --git a/internal/equalByTag.js b/internal/equalByTag.js
index 8fa010411..2a1355eb2 100644
--- a/internal/equalByTag.js
+++ b/internal/equalByTag.js
@@ -1,10 +1,28 @@
+import Uint8Array from './Uint8Array';
+import _Symbol from './_Symbol';
+import mapToArray from './mapToArray';
+import setToArray from './setToArray';
+
+/** 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
@@ -17,10 +35,20 @@ var boolTag = '[object Boolean]',
* @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
@@ -32,15 +60,27 @@ function equalByTag(object, other, tag) {
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 cbae5d662..a98567ce8 100644
--- a/internal/equalObjects.js
+++ b/internal/equalObjects.js
@@ -1,10 +1,9 @@
-import keys from '../object/keys';
+import baseHas from './baseHas';
+import keys from '../keys';
-/** 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
@@ -14,42 +13,60 @@ var hasOwnProperty = objectProto.hasOwnProperty;
* @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;
@@ -58,10 +75,11 @@ function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, sta
('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;
}
export default equalObjects;
diff --git a/internal/escapeRegExpChar.js b/internal/escapeRegExpChar.js
deleted file mode 100644
index 625ab38d0..000000000
--- a/internal/escapeRegExpChar.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/** 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;
-}
-
-export default escapeRegExpChar;
diff --git a/internal/getData.js b/internal/getData.js
index 7dc75375a..ab01f2379 100644
--- a/internal/getData.js
+++ b/internal/getData.js
@@ -1,5 +1,5 @@
import metaMap from './metaMap';
-import noop from '../utility/noop';
+import noop from '../noop';
/**
* Gets metadata for `func`.
diff --git a/internal/getMatchData.js b/internal/getMatchData.js
index bccf3c31e..bb5124708 100644
--- a/internal/getMatchData.js
+++ b/internal/getMatchData.js
@@ -1,15 +1,15 @@
import isStrictComparable from './isStrictComparable';
-import pairs from '../object/pairs';
+import toPairs from '../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 099a9b379..1b8e71391 100644
--- a/internal/getNative.js
+++ b/internal/getNative.js
@@ -1,4 +1,4 @@
-import isNative from '../lang/isNative';
+import isNative from '../isNative';
/**
* Gets the native function at `key` of `object`.
diff --git a/internal/getSymbols.js b/internal/getSymbols.js
new file mode 100644
index 000000000..73bbca717
--- /dev/null
+++ b/internal/getSymbols.js
@@ -0,0 +1,15 @@
+/** 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 [];
+};
+
+export default getSymbols;
diff --git a/internal/getTag.js b/internal/getTag.js
new file mode 100644
index 000000000..3ecf91703
--- /dev/null
+++ b/internal/getTag.js
@@ -0,0 +1,55 @@
+import Map from './Map';
+import Set from './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;
+ };
+}
+
+export default getTag;
diff --git a/internal/getView.js b/internal/getView.js
index cf677bf13..14fbba4d8 100644
--- a/internal/getView.js
+++ b/internal/getView.js
@@ -1,4 +1,4 @@
-/* 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..66dd47845
--- /dev/null
+++ b/internal/hasPath.js
@@ -0,0 +1,37 @@
+import baseToPath from './baseToPath';
+import isArguments from '../isArguments';
+import isArray from '../isArray';
+import isIndex from './isIndex';
+import isKey from './isKey';
+import isLength from '../isLength';
+import isString from '../isString';
+import last from '../last';
+import parent from './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)));
+}
+
+export default hasPath;
diff --git a/internal/hashDelete.js b/internal/hashDelete.js
new file mode 100644
index 000000000..28a88c4fb
--- /dev/null
+++ b/internal/hashDelete.js
@@ -0,0 +1,15 @@
+import hashHas from './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];
+}
+
+export default hashDelete;
diff --git a/internal/hashGet.js b/internal/hashGet.js
new file mode 100644
index 000000000..72557a1c5
--- /dev/null
+++ b/internal/hashGet.js
@@ -0,0 +1,28 @@
+import nativeCreate from './nativeCreate';
+
+/** 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;
+}
+
+export default hashGet;
diff --git a/internal/hashHas.js b/internal/hashHas.js
new file mode 100644
index 000000000..90e74a178
--- /dev/null
+++ b/internal/hashHas.js
@@ -0,0 +1,21 @@
+import nativeCreate from './nativeCreate';
+
+/** 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);
+}
+
+export default hashHas;
diff --git a/internal/hashSet.js b/internal/hashSet.js
new file mode 100644
index 000000000..d2d0738ee
--- /dev/null
+++ b/internal/hashSet.js
@@ -0,0 +1,18 @@
+import nativeCreate from './nativeCreate';
+
+/** 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;
+}
+
+export default hashSet;
diff --git a/internal/indexKeys.js b/internal/indexKeys.js
new file mode 100644
index 000000000..070f4e68d
--- /dev/null
+++ b/internal/indexKeys.js
@@ -0,0 +1,22 @@
+import baseTimes from './baseTimes';
+import isArguments from '../isArguments';
+import isArray from '../isArray';
+import isLength from '../isLength';
+import isString from '../isString';
+
+/**
+ * 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;
+}
+
+export default indexKeys;
diff --git a/internal/initCloneArray.js b/internal/initCloneArray.js
index 8e6d68296..599732e03 100644
--- a/internal/initCloneArray.js
+++ b/internal/initCloneArray.js
@@ -1,4 +1,4 @@
-/** Used for native method references. */
+/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
@@ -13,9 +13,9 @@ var hasOwnProperty = objectProto.hasOwnProperty;
*/
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 3751a36e5..bf02b3577 100644
--- a/internal/initCloneByTag.js
+++ b/internal/initCloneByTag.js
@@ -1,11 +1,19 @@
-import bufferClone from './bufferClone';
+import cloneBuffer from './cloneBuffer';
+import cloneMap from './cloneMap';
+import cloneRegExp from './cloneRegExp';
+import cloneSet from './cloneSet';
+import cloneSymbol from './cloneSymbol';
+import cloneTypedArray from './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 +26,6 @@ var arrayBufferTag = '[object ArrayBuffer]',
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 +42,7 @@ function initCloneByTag(object, tag, isDeep) {
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
- return bufferClone(object);
+ return cloneBuffer(object);
case boolTag:
case dateTag:
@@ -46,18 +51,24 @@ function initCloneByTag(object, tag, isDeep) {
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;
}
export default initCloneByTag;
diff --git a/internal/initCloneObject.js b/internal/initCloneObject.js
index 5d8afa206..40f5fa485 100644
--- a/internal/initCloneObject.js
+++ b/internal/initCloneObject.js
@@ -1,3 +1,6 @@
+import baseCreate from './baseCreate';
+import isFunction from '../isFunction';
+
/**
* Initializes an object clone.
*
@@ -7,10 +10,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);
}
export default initCloneObject;
diff --git a/internal/invokePath.js b/internal/invokePath.js
deleted file mode 100644
index 1aee55a25..000000000
--- a/internal/invokePath.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import baseGet from './baseGet';
-import baseSlice from './baseSlice';
-import isKey from './isKey';
-import last from '../array/last';
-import toPath from './toPath';
-
-/**
- * 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);
-}
-
-export default invokePath;
diff --git a/internal/isArrayLike.js b/internal/isArrayLike.js
deleted file mode 100644
index df01faef9..000000000
--- a/internal/isArrayLike.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import getLength from './getLength';
-import isLength from './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));
-}
-
-export default isArrayLike;
diff --git a/internal/isHostObject.js b/internal/isHostObject.js
new file mode 100644
index 000000000..29382d12f
--- /dev/null
+++ b/internal/isHostObject.js
@@ -0,0 +1,20 @@
+/**
+ * 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;
+}
+
+export default isHostObject;
diff --git a/internal/isIndex.js b/internal/isIndex.js
index 8bbc020d9..47a4460e5 100644
--- a/internal/isIndex.js
+++ b/internal/isIndex.js
@@ -1,12 +1,9 @@
-/** 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 4c85d77b1..808ad1345 100644
--- a/internal/isIterateeCall.js
+++ b/internal/isIterateeCall.js
@@ -1,6 +1,7 @@
-import isArrayLike from './isArrayLike';
+import eq from '../eq';
+import isArrayLike from '../isArrayLike';
import isIndex from './isIndex';
-import isObject from '../lang/isObject';
+import isObject from '../isObject';
/**
* Checks if the provided arguments are from an iteratee call.
@@ -19,8 +20,7 @@ function isIterateeCall(value, index, object) {
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 51345543f..76e0981eb 100644
--- a/internal/isKey.js
+++ b/internal/isKey.js
@@ -1,8 +1,7 @@
-import isArray from '../lang/isArray';
-import toObject from './toObject';
+import isArray from '../isArray';
/** Used to match property names within property paths. */
-var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
+var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
reIsPlainProp = /^\w*$/;
/**
@@ -14,15 +13,12 @@ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
* @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)));
}
export default isKey;
diff --git a/internal/isKeyable.js b/internal/isKeyable.js
new file mode 100644
index 000000000..972b86b62
--- /dev/null
+++ b/internal/isKeyable.js
@@ -0,0 +1,14 @@
+/**
+ * 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;
+}
+
+export default isKeyable;
diff --git a/internal/isLaziable.js b/internal/isLaziable.js
index 5b588712a..feaac019b 100644
--- a/internal/isLaziable.js
+++ b/internal/isLaziable.js
@@ -1,7 +1,7 @@
import LazyWrapper from './LazyWrapper';
import getData from './getData';
import getFuncName from './getFuncName';
-import lodash from '../chain/lodash';
+import lodash from '../wrapperLodash';
/**
* Checks if `func` has a lazy counterpart.
diff --git a/internal/isLength.js b/internal/isLength.js
deleted file mode 100644
index 717da4e97..000000000
--- a/internal/isLength.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * 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;
-}
-
-export default isLength;
diff --git a/internal/isObjectLike.js b/internal/isObjectLike.js
deleted file mode 100644
index 3aab34860..000000000
--- a/internal/isObjectLike.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * 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';
-}
-
-export default isObjectLike;
diff --git a/internal/isPrototype.js b/internal/isPrototype.js
new file mode 100644
index 000000000..f6c7660d0
--- /dev/null
+++ b/internal/isPrototype.js
@@ -0,0 +1,18 @@
+/** 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;
+}
+
+export default isPrototype;
diff --git a/internal/isSpace.js b/internal/isSpace.js
deleted file mode 100644
index b9082a212..000000000
--- a/internal/isSpace.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * 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)));
-}
-
-export default isSpace;
diff --git a/internal/isStrictComparable.js b/internal/isStrictComparable.js
index a3d21d21c..1d6ef1257 100644
--- a/internal/isStrictComparable.js
+++ b/internal/isStrictComparable.js
@@ -1,4 +1,4 @@
-import isObject from '../lang/isObject';
+import isObject from '../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..315bf2bfe
--- /dev/null
+++ b/internal/iteratorToArray.js
@@ -0,0 +1,18 @@
+/**
+ * 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;
+}
+
+export default iteratorToArray;
diff --git a/internal/lazyClone.js b/internal/lazyClone.js
index 2169ceaf7..f000e864c 100644
--- a/internal/lazyClone.js
+++ b/internal/lazyClone.js
@@ -1,5 +1,5 @@
import LazyWrapper from './LazyWrapper';
-import arrayCopy from './arrayCopy';
+import copyArray from './copyArray';
/**
* Creates a clone of the lazy wrapper object.
@@ -11,12 +11,12 @@ import arrayCopy from './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 9b6014d6b..93651a3f8 100644
--- a/internal/lazyValue.js
+++ b/internal/lazyValue.js
@@ -1,6 +1,6 @@
import baseWrapperValue from './baseWrapperValue';
import getView from './getView';
-import isArray from '../lang/isArray';
+import isArray from '../isArray';
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
@@ -9,7 +9,7 @@ var LARGE_ARRAY_SIZE = 200;
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..51e2918cb
--- /dev/null
+++ b/internal/mapClear.js
@@ -0,0 +1,15 @@
+import Hash from './Hash';
+import Map from './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 };
+}
+
+export default mapClear;
diff --git a/internal/mapDelete.js b/internal/mapDelete.js
index 6fce95500..120f56cae 100644
--- a/internal/mapDelete.js
+++ b/internal/mapDelete.js
@@ -1,14 +1,23 @@
+import Map from './Map';
+import assocDelete from './assocDelete';
+import hashDelete from './hashDelete';
+import isKeyable from './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);
}
export default mapDelete;
diff --git a/internal/mapGet.js b/internal/mapGet.js
index 4f1913dec..1aaeda84f 100644
--- a/internal/mapGet.js
+++ b/internal/mapGet.js
@@ -1,14 +1,23 @@
+import Map from './Map';
+import assocGet from './assocGet';
+import hashGet from './hashGet';
+import isKeyable from './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);
}
export default mapGet;
diff --git a/internal/mapHas.js b/internal/mapHas.js
index 0bea8caae..2bbcd7a99 100644
--- a/internal/mapHas.js
+++ b/internal/mapHas.js
@@ -1,20 +1,23 @@
-/** Used for native method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
+import Map from './Map';
+import assocHas from './assocHas';
+import hashHas from './hashHas';
+import isKeyable from './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);
}
export default mapHas;
diff --git a/internal/mapSet.js b/internal/mapSet.js
index 90bd28aee..5bc650a56 100644
--- a/internal/mapSet.js
+++ b/internal/mapSet.js
@@ -1,16 +1,26 @@
+import Map from './Map';
+import assocSet from './assocSet';
+import hashSet from './hashSet';
+import isKeyable from './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..fd5adc419
--- /dev/null
+++ b/internal/mapToArray.js
@@ -0,0 +1,18 @@
+/**
+ * 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;
+}
+
+export default mapToArray;
diff --git a/internal/mergeData.js b/internal/mergeData.js
index 156398383..0dda6e78c 100644
--- a/internal/mergeData.js
+++ b/internal/mergeData.js
@@ -1,10 +1,11 @@
-import arrayCopy from './arrayCopy';
import composeArgs from './composeArgs';
import composeArgsRight from './composeArgsRight';
+import copyArray from './copyArray';
import replaceHolders from './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,
@@ -13,18 +14,18 @@ var BIND_FLAG = 1,
/** 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.
@@ -35,12 +36,12 @@ function mergeData(data, source) {
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)) {
@@ -56,20 +57,20 @@ function mergeData(data, source) {
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 f9227ea86..9b74d4ea1 100644
--- a/internal/mergeDefaults.js
+++ b/internal/mergeDefaults.js
@@ -1,15 +1,25 @@
-import merge from '../object/merge';
+import baseClone from './baseClone';
+import baseMerge from './baseMerge';
+import isObject from '../isObject';
/**
* 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;
}
export default mergeDefaults;
diff --git a/internal/metaMap.js b/internal/metaMap.js
index 0b1d71119..aeda1e383 100644
--- a/internal/metaMap.js
+++ b/internal/metaMap.js
@@ -1,8 +1,4 @@
-import getNative from './getNative';
-import root from './root';
-
-/** Native method references. */
-var WeakMap = getNative(root, 'WeakMap');
+import WeakMap from './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..1df596f45
--- /dev/null
+++ b/internal/nativeCreate.js
@@ -0,0 +1,6 @@
+import getNative from './getNative';
+
+/* Built-in method references that are verified to be native. */
+var nativeCreate = getNative(Object, 'create');
+
+export default nativeCreate;
diff --git a/internal/parent.js b/internal/parent.js
new file mode 100644
index 000000000..0f621956a
--- /dev/null
+++ b/internal/parent.js
@@ -0,0 +1,16 @@
+import baseSlice from './baseSlice';
+import get from '../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));
+}
+
+export default parent;
diff --git a/internal/pickByArray.js b/internal/pickByArray.js
deleted file mode 100644
index 928932e5a..000000000
--- a/internal/pickByArray.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import toObject from './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;
-}
-
-export default pickByArray;
diff --git a/internal/pickByCallback.js b/internal/pickByCallback.js
deleted file mode 100644
index a8af9550d..000000000
--- a/internal/pickByCallback.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import baseForIn from './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;
-}
-
-export default pickByCallback;
diff --git a/internal/reorder.js b/internal/reorder.js
index a31e032cc..0be0bcebc 100644
--- a/internal/reorder.js
+++ b/internal/reorder.js
@@ -1,7 +1,7 @@
-import arrayCopy from './arrayCopy';
+import copyArray from './copyArray';
import isIndex from './isIndex';
-/* 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;
/**
@@ -17,7 +17,7 @@ var nativeMin = Math.min;
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 20d53b67d..2b376d78b 100644
--- a/internal/root.js
+++ b/internal/root.js
@@ -1,3 +1,5 @@
+import checkGlobal from './checkGlobal';
+
/** Used to determine if values are of the language type `Object`. */
var objectTypes = {
'function': true,
@@ -5,19 +7,22 @@ var objectTypes = {
};
/** 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.
@@ -25,6 +30,6 @@ var freeWindow = objectTypes[typeof window] && window && window.Object && window
* 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')();
export default root;
diff --git a/internal/setData.js b/internal/setData.js
index 6bc08bbd1..458127454 100644
--- a/internal/setData.js
+++ b/internal/setData.js
@@ -1,7 +1,7 @@
import baseSetData from './baseSetData';
-import now from '../date/now';
+import now from '../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..7ab0451dd
--- /dev/null
+++ b/internal/setToArray.js
@@ -0,0 +1,18 @@
+/**
+ * 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;
+}
+
+export default setToArray;
diff --git a/internal/shimKeys.js b/internal/shimKeys.js
deleted file mode 100644
index fd7351231..000000000
--- a/internal/shimKeys.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import isArguments from '../lang/isArguments';
-import isArray from '../lang/isArray';
-import isIndex from './isIndex';
-import isLength from './isLength';
-import keysIn from '../object/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;
-}
-
-export default shimKeys;
diff --git a/internal/sortedUniq.js b/internal/sortedUniq.js
deleted file mode 100644
index d5b9464f4..000000000
--- a/internal/sortedUniq.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 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;
-}
-
-export default sortedUniq;
diff --git a/internal/stackClear.js b/internal/stackClear.js
new file mode 100644
index 000000000..8e0c9c038
--- /dev/null
+++ b/internal/stackClear.js
@@ -0,0 +1,12 @@
+/**
+ * Removes all key-value entries from the stack.
+ *
+ * @private
+ * @name clear
+ * @memberOf Stack
+ */
+function stackClear() {
+ this.__data__ = { 'array': [], 'map': null };
+}
+
+export default stackClear;
diff --git a/internal/stackDelete.js b/internal/stackDelete.js
new file mode 100644
index 000000000..c9bdeb80a
--- /dev/null
+++ b/internal/stackDelete.js
@@ -0,0 +1,19 @@
+import assocDelete from './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);
+}
+
+export default stackDelete;
diff --git a/internal/stackGet.js b/internal/stackGet.js
new file mode 100644
index 000000000..0f512c012
--- /dev/null
+++ b/internal/stackGet.js
@@ -0,0 +1,19 @@
+import assocGet from './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);
+}
+
+export default stackGet;
diff --git a/internal/stackHas.js b/internal/stackHas.js
new file mode 100644
index 000000000..db6f9c663
--- /dev/null
+++ b/internal/stackHas.js
@@ -0,0 +1,19 @@
+import assocHas from './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);
+}
+
+export default stackHas;
diff --git a/internal/stackSet.js b/internal/stackSet.js
new file mode 100644
index 000000000..160e241b0
--- /dev/null
+++ b/internal/stackSet.js
@@ -0,0 +1,36 @@
+import MapCache from './MapCache';
+import assocSet from './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;
+}
+
+export default stackSet;
diff --git a/internal/stringSize.js b/internal/stringSize.js
new file mode 100644
index 000000000..070656b34
--- /dev/null
+++ b/internal/stringSize.js
@@ -0,0 +1,45 @@
+/** 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;
+}
+
+export default stringSize;
diff --git a/internal/stringToArray.js b/internal/stringToArray.js
new file mode 100644
index 000000000..5a2c6047a
--- /dev/null
+++ b/internal/stringToArray.js
@@ -0,0 +1,36 @@
+/** 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);
+}
+
+export default stringToArray;
diff --git a/internal/toPath.js b/internal/stringToPath.js
similarity index 51%
rename from internal/toPath.js
rename to internal/stringToPath.js
index 918a521f5..5269d7870 100644
--- a/internal/toPath.js
+++ b/internal/stringToPath.js
@@ -1,28 +1,24 @@
-import baseToString from './baseToString';
-import isArray from '../lang/isArray';
+import toString from '../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;
}
-export default toPath;
+export default stringToPath;
diff --git a/internal/toArrayLikeObject.js b/internal/toArrayLikeObject.js
new file mode 100644
index 000000000..b9066b11d
--- /dev/null
+++ b/internal/toArrayLikeObject.js
@@ -0,0 +1,14 @@
+import isArrayLikeObject from '../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 : [];
+}
+
+export default toArrayLikeObject;
diff --git a/internal/toFunction.js b/internal/toFunction.js
new file mode 100644
index 000000000..199ee43e1
--- /dev/null
+++ b/internal/toFunction.js
@@ -0,0 +1,14 @@
+import identity from '../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;
+}
+
+export default toFunction;
diff --git a/internal/toIterable.js b/internal/toIterable.js
deleted file mode 100644
index dcce3cf9c..000000000
--- a/internal/toIterable.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import isArrayLike from './isArrayLike';
-import isObject from '../lang/isObject';
-import values from '../object/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);
-}
-
-export default toIterable;
diff --git a/internal/toObject.js b/internal/toObject.js
deleted file mode 100644
index fa7de0eb9..000000000
--- a/internal/toObject.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import isObject from '../lang/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);
-}
-
-export default toObject;
diff --git a/internal/trimmedLeftIndex.js b/internal/trimmedLeftIndex.js
deleted file mode 100644
index bfa0d8d1c..000000000
--- a/internal/trimmedLeftIndex.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import isSpace from './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;
-}
-
-export default trimmedLeftIndex;
diff --git a/internal/trimmedRightIndex.js b/internal/trimmedRightIndex.js
deleted file mode 100644
index dbaf53932..000000000
--- a/internal/trimmedRightIndex.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import isSpace from './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;
-}
-
-export default trimmedRightIndex;
diff --git a/internal/wrapperClone.js b/internal/wrapperClone.js
index 57b88baf2..c9b8f0752 100644
--- a/internal/wrapperClone.js
+++ b/internal/wrapperClone.js
@@ -1,6 +1,6 @@
import LazyWrapper from './LazyWrapper';
import LodashWrapper from './LodashWrapper';
-import arrayCopy from './arrayCopy';
+import copyArray from './copyArray';
/**
* Creates a clone of `wrapper`.
@@ -10,9 +10,14 @@ import arrayCopy from './arrayCopy';
* @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;
}
export default wrapperClone;
diff --git a/intersection.js b/intersection.js
new file mode 100644
index 000000000..61b52321f
--- /dev/null
+++ b/intersection.js
@@ -0,0 +1,27 @@
+import arrayMap from './internal/arrayMap';
+import baseIntersection from './internal/baseIntersection';
+import rest from './rest';
+import toArrayLikeObject from './internal/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)
+ : [];
+});
+
+export default intersection;
diff --git a/intersectionBy.js b/intersectionBy.js
new file mode 100644
index 000000000..ff8cd2870
--- /dev/null
+++ b/intersectionBy.js
@@ -0,0 +1,42 @@
+import arrayMap from './internal/arrayMap';
+import baseIntersection from './internal/baseIntersection';
+import baseIteratee from './internal/baseIteratee';
+import last from './last';
+import rest from './rest';
+import toArrayLikeObject from './internal/toArrayLikeObject';
+
+/**
+ * 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))
+ : [];
+});
+
+export default intersectionBy;
diff --git a/intersectionWith.js b/intersectionWith.js
new file mode 100644
index 000000000..8a4076246
--- /dev/null
+++ b/intersectionWith.js
@@ -0,0 +1,40 @@
+import arrayMap from './internal/arrayMap';
+import baseIntersection from './internal/baseIntersection';
+import last from './last';
+import rest from './rest';
+import toArrayLikeObject from './internal/toArrayLikeObject';
+
+/**
+ * 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)
+ : [];
+});
+
+export default intersectionWith;
diff --git a/object/invert.js b/invert.js
similarity index 55%
rename from object/invert.js
rename to invert.js
index 6f1e499ef..9743942c9 100644
--- a/object/invert.js
+++ b/invert.js
@@ -1,7 +1,7 @@
-import isIterateeCall from '../internal/isIterateeCall';
+import arrayReduce from './internal/arrayReduce';
import keys from './keys';
-/** Used for native method references. */
+/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
@@ -10,14 +10,14 @@ var hasOwnProperty = objectProto.hasOwnProperty;
/**
* 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
*
@@ -26,24 +26,14 @@ var hasOwnProperty = objectProto.hasOwnProperty;
* _.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 {
@@ -53,8 +43,8 @@ function invert(object, multiValue, guard) {
else {
result[value] = key;
}
- }
- return result;
+ return result;
+ }, {});
}
export default invert;
diff --git a/invoke.js b/invoke.js
new file mode 100644
index 000000000..42d4e76a7
--- /dev/null
+++ b/invoke.js
@@ -0,0 +1,23 @@
+import baseInvoke from './internal/baseInvoke';
+import rest from './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);
+
+export default invoke;
diff --git a/collection/invoke.js b/invokeMap.js
similarity index 59%
rename from collection/invoke.js
rename to invokeMap.js
index 56a5ef126..becc750e2 100644
--- a/collection/invoke.js
+++ b/invokeMap.js
@@ -1,8 +1,9 @@
-import baseEach from '../internal/baseEach';
-import invokePath from '../internal/invokePath';
-import isArrayLike from '../internal/isArrayLike';
-import isKey from '../internal/isKey';
-import restParam from '../function/restParam';
+import apply from './internal/apply';
+import baseEach from './internal/baseEach';
+import baseInvoke from './internal/baseInvoke';
+import isArrayLike from './isArrayLike';
+import isKey from './internal/isKey';
+import rest from './rest';
/**
* Invokes the method at `path` of each element in `collection`, returning
@@ -13,20 +14,20 @@ import restParam from '../function/restParam';
* @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),
@@ -34,9 +35,9 @@ var invoke = restParam(function(collection, path, args) {
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;
});
-export default invoke;
+export default invokeMap;
diff --git a/isArguments.js b/isArguments.js
new file mode 100644
index 000000000..62c5e3642
--- /dev/null
+++ b/isArguments.js
@@ -0,0 +1,43 @@
+import isArrayLikeObject from './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);
+}
+
+export default isArguments;
diff --git a/isArray.js b/isArray.js
new file mode 100644
index 000000000..8c1d036f2
--- /dev/null
+++ b/isArray.js
@@ -0,0 +1,26 @@
+/**
+ * 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;
+
+export default isArray;
diff --git a/isArrayLike.js b/isArrayLike.js
new file mode 100644
index 000000000..e4614b565
--- /dev/null
+++ b/isArrayLike.js
@@ -0,0 +1,35 @@
+import getLength from './internal/getLength';
+import isFunction from './isFunction';
+import isLength from './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));
+}
+
+export default isArrayLike;
diff --git a/isArrayLikeObject.js b/isArrayLikeObject.js
new file mode 100644
index 000000000..c73838a38
--- /dev/null
+++ b/isArrayLikeObject.js
@@ -0,0 +1,32 @@
+import isArrayLike from './isArrayLike';
+import isObjectLike from './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);
+}
+
+export default isArrayLikeObject;
diff --git a/lang/isBoolean.js b/isBoolean.js
similarity index 72%
rename from lang/isBoolean.js
rename to isBoolean.js
index f6a6f8674..27a0f2222 100644
--- a/lang/isBoolean.js
+++ b/isBoolean.js
@@ -1,16 +1,16 @@
-import isObjectLike from '../internal/isObjectLike';
+import isObjectLike from './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 @@ var objToString = objectProto.toString;
* // => 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);
}
export default isBoolean;
diff --git a/lang/isDate.js b/isDate.js
similarity index 76%
rename from lang/isDate.js
rename to isDate.js
index 7befa7271..0218fb2b9 100644
--- a/lang/isDate.js
+++ b/isDate.js
@@ -1,16 +1,16 @@
-import isObjectLike from '../internal/isObjectLike';
+import isObjectLike from './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 @@ var objToString = objectProto.toString;
* // => false
*/
function isDate(value) {
- return isObjectLike(value) && objToString.call(value) == dateTag;
+ return isObjectLike(value) && objectToString.call(value) == dateTag;
}
export default isDate;
diff --git a/lang/isElement.js b/isElement.js
similarity index 83%
rename from lang/isElement.js
rename to isElement.js
index 5bb92d4f2..14ab21951 100644
--- a/lang/isElement.js
+++ b/isElement.js
@@ -1,8 +1,8 @@
-import isObjectLike from '../internal/isObjectLike';
+import isObjectLike from './isObjectLike';
import isPlainObject from './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 58%
rename from lang/isEmpty.js
rename to isEmpty.js
index 16737095e..dc5d66203 100644
--- a/lang/isEmpty.js
+++ b/isEmpty.js
@@ -1,10 +1,7 @@
-import isArguments from './isArguments';
-import isArray from './isArray';
-import isArrayLike from '../internal/isArrayLike';
import isFunction from './isFunction';
-import isObjectLike from '../internal/isObjectLike';
-import isString from './isString';
-import keys from '../object/keys';
+import isObjectLike from './isObjectLike';
+import keys from './keys';
+import size from './size';
/**
* Checks if `value` is empty. A value is considered empty unless it's an
@@ -34,14 +31,9 @@ import keys from '../object/keys';
* // => 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;
}
export default isEmpty;
diff --git a/isEqual.js b/isEqual.js
new file mode 100644
index 000000000..586548aa1
--- /dev/null
+++ b/isEqual.js
@@ -0,0 +1,34 @@
+import baseIsEqual from './internal/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);
+}
+
+export default isEqual;
diff --git a/isEqualWith.js b/isEqualWith.js
new file mode 100644
index 000000000..f7397398e
--- /dev/null
+++ b/isEqualWith.js
@@ -0,0 +1,40 @@
+import baseIsEqual from './internal/baseIsEqual';
+
+/**
+ * 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;
+}
+
+export default isEqualWith;
diff --git a/lang/isError.js b/isError.js
similarity index 74%
rename from lang/isError.js
rename to isError.js
index 9bbece9a1..6ec72aac8 100644
--- a/lang/isError.js
+++ b/isError.js
@@ -1,16 +1,16 @@
-import isObjectLike from '../internal/isObjectLike';
+import isObjectLike from './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 @@ var objToString = objectProto.toString;
* // => 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;
}
export default isError;
diff --git a/lang/isFinite.js b/isFinite.js
similarity index 54%
rename from lang/isFinite.js
rename to isFinite.js
index 4e59703c1..057d5db27 100644
--- a/lang/isFinite.js
+++ b/isFinite.js
@@ -1,12 +1,12 @@
-import root from '../internal/root';
+import root from './internal/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 @@ var nativeIsFinite = root.isFinite;
* @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 63%
rename from lang/isFunction.js
rename to isFunction.js
index 32c5fda19..5e2e6b609 100644
--- a/lang/isFunction.js
+++ b/isFunction.js
@@ -1,16 +1,17 @@
import isObject from './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 @@ var objToString = objectProto.toString;
*/
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;
}
export default isFunction;
diff --git a/isInteger.js b/isInteger.js
new file mode 100644
index 000000000..4c8799b73
--- /dev/null
+++ b/isInteger.js
@@ -0,0 +1,31 @@
+import toInteger from './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);
+}
+
+export default isInteger;
diff --git a/isLength.js b/isLength.js
new file mode 100644
index 000000000..d13d42318
--- /dev/null
+++ b/isLength.js
@@ -0,0 +1,32 @@
+/** 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;
+}
+
+export default isLength;
diff --git a/isMatch.js b/isMatch.js
new file mode 100644
index 000000000..e32ffec0c
--- /dev/null
+++ b/isMatch.js
@@ -0,0 +1,30 @@
+import baseIsMatch from './internal/baseIsMatch';
+import getMatchData from './internal/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));
+}
+
+export default isMatch;
diff --git a/isMatchWith.js b/isMatchWith.js
new file mode 100644
index 000000000..97539690d
--- /dev/null
+++ b/isMatchWith.js
@@ -0,0 +1,40 @@
+import baseIsMatch from './internal/baseIsMatch';
+import getMatchData from './internal/getMatchData';
+
+/**
+ * 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);
+}
+
+export default isMatchWith;
diff --git a/lang/isNaN.js b/isNaN.js
similarity index 96%
rename from lang/isNaN.js
rename to isNaN.js
index d2b2d0f5a..099a9970c 100644
--- a/lang/isNaN.js
+++ b/isNaN.js
@@ -27,7 +27,7 @@ import isNumber from './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 63%
rename from lang/isNative.js
rename to isNative.js
index e037e95ee..18bf0432e 100644
--- a/lang/isNative.js
+++ b/isNative.js
@@ -1,21 +1,25 @@
import isFunction from './isFunction';
-import isObjectLike from '../internal/isObjectLike';
+import isHostObject from './internal/isHostObject';
+import isObjectLike from './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.*?') + '$'
);
@@ -40,9 +44,10 @@ function isNative(value) {
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);
}
export default isNative;
diff --git a/isNil.js b/isNil.js
new file mode 100644
index 000000000..44603d47f
--- /dev/null
+++ b/isNil.js
@@ -0,0 +1,24 @@
+/**
+ * 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;
+}
+
+export default 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 dcc8c3db8..0fcfce16b 100644
--- a/lang/isNumber.js
+++ b/isNumber.js
@@ -1,16 +1,16 @@
-import isObjectLike from '../internal/isObjectLike';
+import isObjectLike from './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 @@ var objToString = objectProto.toString;
* @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);
}
export default isNumber;
diff --git a/lang/isObject.js b/isObject.js
similarity index 92%
rename from lang/isObject.js
rename to isObject.js
index 19bba5e4a..8aebc4b8d 100644
--- a/lang/isObject.js
+++ b/isObject.js
@@ -15,7 +15,10 @@
* _.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..4d1211a9a
--- /dev/null
+++ b/isObjectLike.js
@@ -0,0 +1,28 @@
+/**
+ * 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';
+}
+
+export default isObjectLike;
diff --git a/isPlainObject.js b/isPlainObject.js
new file mode 100644
index 000000000..dcef5ebc6
--- /dev/null
+++ b/isPlainObject.js
@@ -0,0 +1,68 @@
+import isHostObject from './internal/isHostObject';
+import isObjectLike from './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);
+}
+
+export default isPlainObject;
diff --git a/lang/isRegExp.js b/isRegExp.js
similarity index 81%
rename from lang/isRegExp.js
rename to isRegExp.js
index 6bc150988..ce968c52c 100644
--- a/lang/isRegExp.js
+++ b/isRegExp.js
@@ -3,14 +3,14 @@ import isObject from './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 @@ var objToString = objectProto.toString;
* // => false
*/
function isRegExp(value) {
- return isObject(value) && objToString.call(value) == regexpTag;
+ return isObject(value) && objectToString.call(value) == regexpTag;
}
export default isRegExp;
diff --git a/isSafeInteger.js b/isSafeInteger.js
new file mode 100644
index 000000000..c81338df9
--- /dev/null
+++ b/isSafeInteger.js
@@ -0,0 +1,35 @@
+import isInteger from './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;
+}
+
+export default isSafeInteger;
diff --git a/lang/isString.js b/isString.js
similarity index 69%
rename from lang/isString.js
rename to isString.js
index f596442d5..7dd6d3554 100644
--- a/lang/isString.js
+++ b/isString.js
@@ -1,16 +1,17 @@
-import isObjectLike from '../internal/isObjectLike';
+import isArray from './isArray';
+import isObjectLike from './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 +30,8 @@ var objToString = objectProto.toString;
* // => 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);
}
export default isString;
diff --git a/isSymbol.js b/isSymbol.js
new file mode 100644
index 000000000..37ed8d98b
--- /dev/null
+++ b/isSymbol.js
@@ -0,0 +1,36 @@
+import isObjectLike from './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);
+}
+
+export default isSymbol;
diff --git a/lang/isTypedArray.js b/isTypedArray.js
similarity index 91%
rename from lang/isTypedArray.js
rename to isTypedArray.js
index a8b1c9135..e1f9e5481 100644
--- a/lang/isTypedArray.js
+++ b/isTypedArray.js
@@ -1,5 +1,5 @@
-import isLength from '../internal/isLength';
-import isObjectLike from '../internal/isObjectLike';
+import isLength from './isLength';
+import isObjectLike from './isObjectLike';
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
@@ -42,14 +42,14 @@ typedArrayTags[numberTag] = typedArrayTags[objectTag] =
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.
@@ -68,7 +68,7 @@ var objToString = objectProto.toString;
* // => false
*/
function isTypedArray(value) {
- return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
+ return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
}
export default 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..7e6a5ba2a
--- /dev/null
+++ b/iteratee.js
@@ -0,0 +1,41 @@
+import baseIteratee from './internal/baseIteratee';
+import isArray from './isArray';
+import isObjectLike from './isObjectLike';
+import matches from './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);
+}
+
+export default iteratee;
diff --git a/join.js b/join.js
new file mode 100644
index 000000000..ad2b69c15
--- /dev/null
+++ b/join.js
@@ -0,0 +1,25 @@
+/** 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) : '';
+}
+
+export default join;
diff --git a/string/kebabCase.js b/kebabCase.js
similarity index 90%
rename from string/kebabCase.js
rename to kebabCase.js
index 51ee6b29e..3af75437e 100644
--- a/string/kebabCase.js
+++ b/kebabCase.js
@@ -1,4 +1,4 @@
-import createCompounder from '../internal/createCompounder';
+import createCompounder from './internal/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..c7b18da46
--- /dev/null
+++ b/keyBy.js
@@ -0,0 +1,34 @@
+import createAggregator from './internal/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;
+});
+
+export default keyBy;
diff --git a/keys.js b/keys.js
new file mode 100644
index 000000000..71dd5436d
--- /dev/null
+++ b/keys.js
@@ -0,0 +1,55 @@
+import baseHas from './internal/baseHas';
+import baseKeys from './internal/baseKeys';
+import indexKeys from './internal/indexKeys';
+import isArrayLike from './isArrayLike';
+import isIndex from './internal/isIndex';
+import isPrototype from './internal/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;
+}
+
+export default keys;
diff --git a/keysIn.js b/keysIn.js
new file mode 100644
index 000000000..d3e06e263
--- /dev/null
+++ b/keysIn.js
@@ -0,0 +1,54 @@
+import baseKeysIn from './internal/baseKeysIn';
+import indexKeys from './internal/indexKeys';
+import isIndex from './internal/isIndex';
+import isPrototype from './internal/isPrototype';
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @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;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+function keysIn(object) {
+ var index = -1,
+ isProto = isPrototype(object),
+ props = baseKeysIn(object),
+ propsLength = props.length,
+ indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.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);
+ }
+ }
+ return result;
+}
+
+export default keysIn;
diff --git a/lang.default.js b/lang.default.js
new file mode 100644
index 000000000..b72c6c85b
--- /dev/null
+++ b/lang.default.js
@@ -0,0 +1,60 @@
+import clone from './clone';
+import cloneDeep from './cloneDeep';
+import cloneDeepWith from './cloneDeepWith';
+import cloneWith from './cloneWith';
+import eq from './eq';
+import gt from './gt';
+import gte from './gte';
+import isArguments from './isArguments';
+import isArray from './isArray';
+import isArrayLike from './isArrayLike';
+import isArrayLikeObject from './isArrayLikeObject';
+import isBoolean from './isBoolean';
+import isDate from './isDate';
+import isElement from './isElement';
+import isEmpty from './isEmpty';
+import isEqual from './isEqual';
+import isEqualWith from './isEqualWith';
+import isError from './isError';
+import isFinite from './isFinite';
+import isFunction from './isFunction';
+import isInteger from './isInteger';
+import isLength from './isLength';
+import isMatch from './isMatch';
+import isMatchWith from './isMatchWith';
+import isNaN from './isNaN';
+import isNative from './isNative';
+import isNil from './isNil';
+import isNull from './isNull';
+import isNumber from './isNumber';
+import isObject from './isObject';
+import isObjectLike from './isObjectLike';
+import isPlainObject from './isPlainObject';
+import isRegExp from './isRegExp';
+import isSafeInteger from './isSafeInteger';
+import isString from './isString';
+import isSymbol from './isSymbol';
+import isTypedArray from './isTypedArray';
+import isUndefined from './isUndefined';
+import lt from './lt';
+import lte from './lte';
+import toArray from './toArray';
+import toInteger from './toInteger';
+import toLength from './toLength';
+import toNumber from './toNumber';
+import toPlainObject from './toPlainObject';
+import toSafeInteger from './toSafeInteger';
+import toString from './toString';
+
+export default {
+ 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
+};
diff --git a/lang.js b/lang.js
index 3d281a2c0..5295b18d0 100644
--- a/lang.js
+++ b/lang.js
@@ -1,63 +1,48 @@
-import clone from './lang/clone';
-import cloneDeep from './lang/cloneDeep';
-import eq from './lang/eq';
-import gt from './lang/gt';
-import gte from './lang/gte';
-import isArguments from './lang/isArguments';
-import isArray from './lang/isArray';
-import isBoolean from './lang/isBoolean';
-import isDate from './lang/isDate';
-import isElement from './lang/isElement';
-import isEmpty from './lang/isEmpty';
-import isEqual from './lang/isEqual';
-import isError from './lang/isError';
-import isFinite from './lang/isFinite';
-import isFunction from './lang/isFunction';
-import isMatch from './lang/isMatch';
-import isNaN from './lang/isNaN';
-import isNative from './lang/isNative';
-import isNull from './lang/isNull';
-import isNumber from './lang/isNumber';
-import isObject from './lang/isObject';
-import isPlainObject from './lang/isPlainObject';
-import isRegExp from './lang/isRegExp';
-import isString from './lang/isString';
-import isTypedArray from './lang/isTypedArray';
-import isUndefined from './lang/isUndefined';
-import lt from './lang/lt';
-import lte from './lang/lte';
-import toArray from './lang/toArray';
-import toPlainObject from './lang/toPlainObject';
-
-export default {
- 'clone': clone,
- 'cloneDeep': cloneDeep,
- 'eq': eq,
- 'gt': gt,
- 'gte': gte,
- 'isArguments': isArguments,
- 'isArray': isArray,
- 'isBoolean': isBoolean,
- 'isDate': isDate,
- 'isElement': isElement,
- 'isEmpty': isEmpty,
- 'isEqual': isEqual,
- 'isError': isError,
- 'isFinite': isFinite,
- 'isFunction': isFunction,
- 'isMatch': isMatch,
- 'isNaN': isNaN,
- 'isNative': isNative,
- 'isNull': isNull,
- 'isNumber': isNumber,
- 'isObject': isObject,
- 'isPlainObject': isPlainObject,
- 'isRegExp': isRegExp,
- 'isString': isString,
- 'isTypedArray': isTypedArray,
- 'isUndefined': isUndefined,
- 'lt': lt,
- 'lte': lte,
- 'toArray': toArray,
- 'toPlainObject': toPlainObject
-};
+export { default as clone } from './clone';
+export { default as cloneDeep } from './cloneDeep';
+export { default as cloneDeepWith } from './cloneDeepWith';
+export { default as cloneWith } from './cloneWith';
+export { default as eq } from './eq';
+export { default as gt } from './gt';
+export { default as gte } from './gte';
+export { default as isArguments } from './isArguments';
+export { default as isArray } from './isArray';
+export { default as isArrayLike } from './isArrayLike';
+export { default as isArrayLikeObject } from './isArrayLikeObject';
+export { default as isBoolean } from './isBoolean';
+export { default as isDate } from './isDate';
+export { default as isElement } from './isElement';
+export { default as isEmpty } from './isEmpty';
+export { default as isEqual } from './isEqual';
+export { default as isEqualWith } from './isEqualWith';
+export { default as isError } from './isError';
+export { default as isFinite } from './isFinite';
+export { default as isFunction } from './isFunction';
+export { default as isInteger } from './isInteger';
+export { default as isLength } from './isLength';
+export { default as isMatch } from './isMatch';
+export { default as isMatchWith } from './isMatchWith';
+export { default as isNaN } from './isNaN';
+export { default as isNative } from './isNative';
+export { default as isNil } from './isNil';
+export { default as isNull } from './isNull';
+export { default as isNumber } from './isNumber';
+export { default as isObject } from './isObject';
+export { default as isObjectLike } from './isObjectLike';
+export { default as isPlainObject } from './isPlainObject';
+export { default as isRegExp } from './isRegExp';
+export { default as isSafeInteger } from './isSafeInteger';
+export { default as isString } from './isString';
+export { default as isSymbol } from './isSymbol';
+export { default as isTypedArray } from './isTypedArray';
+export { default as isUndefined } from './isUndefined';
+export { default as lt } from './lt';
+export { default as lte } from './lte';
+export { default as toArray } from './toArray';
+export { default as toInteger } from './toInteger';
+export { default as toLength } from './toLength';
+export { default as toNumber } from './toNumber';
+export { default as toPlainObject } from './toPlainObject';
+export { default as toSafeInteger } from './toSafeInteger';
+export { default as toString } from './toString';
+export { default as default } from './lang.default';
diff --git a/lang/clone.js b/lang/clone.js
deleted file mode 100644
index a277bca43..000000000
--- a/lang/clone.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import baseClone from '../internal/baseClone';
-import bindCallback from '../internal/bindCallback';
-import isIterateeCall from '../internal/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);
-}
-
-export default clone;
diff --git a/lang/cloneDeep.js b/lang/cloneDeep.js
deleted file mode 100644
index 2961a5209..000000000
--- a/lang/cloneDeep.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import baseClone from '../internal/baseClone';
-import bindCallback from '../internal/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);
-}
-
-export default cloneDeep;
diff --git a/lang/eq.js b/lang/eq.js
deleted file mode 100644
index fc0698220..000000000
--- a/lang/eq.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import isEqual from './isEqual'
-export default isEqual;
diff --git a/lang/isArguments.js b/lang/isArguments.js
deleted file mode 100644
index 22140d86c..000000000
--- a/lang/isArguments.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import isArrayLike from '../internal/isArrayLike';
-import isObjectLike from '../internal/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');
-}
-
-export default isArguments;
diff --git a/lang/isArray.js b/lang/isArray.js
deleted file mode 100644
index 9af0bf7bc..000000000
--- a/lang/isArray.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import getNative from '../internal/getNative';
-import isLength from '../internal/isLength';
-import isObjectLike from '../internal/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;
-};
-
-export default isArray;
diff --git a/lang/isEqual.js b/lang/isEqual.js
deleted file mode 100644
index 50fc64a46..000000000
--- a/lang/isEqual.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import baseIsEqual from '../internal/baseIsEqual';
-import bindCallback from '../internal/bindCallback';
-
-/**
- * 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;
-}
-
-export default isEqual;
diff --git a/lang/isMatch.js b/lang/isMatch.js
deleted file mode 100644
index e58ef5606..000000000
--- a/lang/isMatch.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import baseIsMatch from '../internal/baseIsMatch';
-import bindCallback from '../internal/bindCallback';
-import getMatchData from '../internal/getMatchData';
-
-/**
- * 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);
-}
-
-export default isMatch;
diff --git a/lang/isPlainObject.js b/lang/isPlainObject.js
deleted file mode 100644
index 8d1724cff..000000000
--- a/lang/isPlainObject.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import baseForIn from '../internal/baseForIn';
-import isArguments from './isArguments';
-import isObjectLike from '../internal/isObjectLike';
-
-/** `Object#toString` result references. */
-var objectTag = '[object Object]';
-
-/** Used for native method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/**
- * Used to resolve the [`toStringTag`](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);
-}
-
-export default isPlainObject;
diff --git a/lang/toArray.js b/lang/toArray.js
deleted file mode 100644
index bab36a8ad..000000000
--- a/lang/toArray.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import arrayCopy from '../internal/arrayCopy';
-import getLength from '../internal/getLength';
-import isLength from '../internal/isLength';
-import values from '../object/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);
-}
-
-export default 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 52%
rename from array/lastIndexOf.js
rename to lastIndexOf.js
index f7b1c4cd7..eb56fbc58 100644
--- a/array/lastIndexOf.js
+++ b/lastIndexOf.js
@@ -1,7 +1,7 @@
-import binaryIndex from '../internal/binaryIndex';
-import indexOfNaN from '../internal/indexOfNaN';
+import indexOfNaN from './internal/indexOfNaN';
+import toInteger from './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,
nativeMin = Math.min;
@@ -14,8 +14,7 @@ var nativeMax = Math.max,
* @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
*
@@ -25,10 +24,6 @@ var nativeMax = Math.max,
* // 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;
@@ -36,15 +31,9 @@ function lastIndexOf(array, value, fromIndex) {
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/lodash.default.js b/lodash.default.js
new file mode 100644
index 000000000..819c47bf1
--- /dev/null
+++ b/lodash.default.js
@@ -0,0 +1,604 @@
+/**
+ * @license
+ * lodash 4.0.0 (Custom Build)
+ * Build: `lodash modularize exports="es" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+import array from './array';
+import collection from './collection';
+import date from './date';
+import func from './function';
+import lang from './lang';
+import math from './math';
+import number from './number';
+import object from './object';
+import seq from './seq';
+import string from './string';
+import util from './util';
+import LazyWrapper from './internal/LazyWrapper';
+import LodashWrapper from './internal/LodashWrapper';
+import _Symbol from './internal/_Symbol';
+import arrayEach from './internal/arrayEach';
+import arrayPush from './internal/arrayPush';
+import baseForOwn from './internal/baseForOwn';
+import baseFunctions from './internal/baseFunctions';
+import baseInvoke from './internal/baseInvoke';
+import baseIteratee from './internal/baseIteratee';
+import createHybridWrapper from './internal/createHybridWrapper';
+import identity from './identity';
+import isArray from './isArray';
+import isObject from './isObject';
+import keys from './keys';
+import last from './last';
+import lazyClone from './internal/lazyClone';
+import lazyReverse from './internal/lazyReverse';
+import lazyValue from './internal/lazyValue';
+import _mixin from './mixin';
+import realNames from './internal/realNames';
+import rest from './rest';
+import thru from './thru';
+import toInteger from './toInteger';
+import lodash from './wrapperLodash';
+
+/** Used as the semantic version number. */
+var VERSION = '4.0.0';
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_KEY_FLAG = 2;
+
+/** Used to indicate the type of lazy iteratees. */
+var LAZY_FILTER_FLAG = 1,
+ LAZY_WHILE_FLAG = 3;
+
+/** Used as references for the maximum length and index of an array. */
+var MAX_ARRAY_LENGTH = 4294967295;
+
+/** Used for built-in method references. */
+var arrayProto = Array.prototype,
+ objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Built-in value references. */
+var iteratorSymbol = typeof (iteratorSymbol = _Symbol && _Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined;
+
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max,
+ nativeMin = Math.min;
+
+// wrap `_.mixin` so it works when provided only one argument
+var mixin = (function(func) {
+ return function(object, source, options) {
+ if (options == null) {
+ var isObj = isObject(source),
+ props = isObj && keys(source),
+ methodNames = props && props.length && baseFunctions(source, props);
+
+ if (!(methodNames ? methodNames.length : isObj)) {
+ options = source;
+ source = object;
+ object = this;
+ }
+ }
+ return func(object, source, options);
+ };
+}(_mixin));
+
+// Add functions that return wrapped values when chaining.
+lodash.after = func.after;
+lodash.ary = func.ary;
+lodash.assign = object.assign;
+lodash.assignIn = object.assignIn;
+lodash.assignInWith = object.assignInWith;
+lodash.assignWith = object.assignWith;
+lodash.at = collection.at;
+lodash.before = func.before;
+lodash.bind = func.bind;
+lodash.bindAll = util.bindAll;
+lodash.bindKey = func.bindKey;
+lodash.chain = seq.chain;
+lodash.chunk = array.chunk;
+lodash.compact = array.compact;
+lodash.concat = array.concat;
+lodash.cond = util.cond;
+lodash.conforms = util.conforms;
+lodash.constant = util.constant;
+lodash.countBy = collection.countBy;
+lodash.create = object.create;
+lodash.curry = func.curry;
+lodash.curryRight = func.curryRight;
+lodash.debounce = func.debounce;
+lodash.defaults = object.defaults;
+lodash.defaultsDeep = object.defaultsDeep;
+lodash.defer = func.defer;
+lodash.delay = func.delay;
+lodash.difference = array.difference;
+lodash.differenceBy = array.differenceBy;
+lodash.differenceWith = array.differenceWith;
+lodash.drop = array.drop;
+lodash.dropRight = array.dropRight;
+lodash.dropRightWhile = array.dropRightWhile;
+lodash.dropWhile = array.dropWhile;
+lodash.fill = array.fill;
+lodash.filter = collection.filter;
+lodash.flatMap = array.flatMap;
+lodash.flatten = array.flatten;
+lodash.flattenDeep = array.flattenDeep;
+lodash.flip = func.flip;
+lodash.flow = util.flow;
+lodash.flowRight = util.flowRight;
+lodash.fromPairs = array.fromPairs;
+lodash.functions = object.functions;
+lodash.functionsIn = object.functionsIn;
+lodash.groupBy = collection.groupBy;
+lodash.initial = array.initial;
+lodash.intersection = array.intersection;
+lodash.intersectionBy = array.intersectionBy;
+lodash.intersectionWith = array.intersectionWith;
+lodash.invert = object.invert;
+lodash.invokeMap = collection.invokeMap;
+lodash.iteratee = util.iteratee;
+lodash.keyBy = collection.keyBy;
+lodash.keys = keys;
+lodash.keysIn = object.keysIn;
+lodash.map = collection.map;
+lodash.mapKeys = object.mapKeys;
+lodash.mapValues = object.mapValues;
+lodash.matches = util.matches;
+lodash.matchesProperty = util.matchesProperty;
+lodash.memoize = func.memoize;
+lodash.merge = object.merge;
+lodash.mergeWith = object.mergeWith;
+lodash.method = util.method;
+lodash.methodOf = util.methodOf;
+lodash.mixin = mixin;
+lodash.negate = func.negate;
+lodash.nthArg = util.nthArg;
+lodash.omit = object.omit;
+lodash.omitBy = object.omitBy;
+lodash.once = func.once;
+lodash.orderBy = collection.orderBy;
+lodash.over = util.over;
+lodash.overArgs = func.overArgs;
+lodash.overEvery = util.overEvery;
+lodash.overSome = util.overSome;
+lodash.partial = func.partial;
+lodash.partialRight = func.partialRight;
+lodash.partition = collection.partition;
+lodash.pick = object.pick;
+lodash.pickBy = object.pickBy;
+lodash.property = util.property;
+lodash.propertyOf = util.propertyOf;
+lodash.pull = array.pull;
+lodash.pullAll = array.pullAll;
+lodash.pullAllBy = array.pullAllBy;
+lodash.pullAt = array.pullAt;
+lodash.range = util.range;
+lodash.rangeRight = util.rangeRight;
+lodash.rearg = func.rearg;
+lodash.reject = collection.reject;
+lodash.remove = array.remove;
+lodash.rest = rest;
+lodash.reverse = array.reverse;
+lodash.sampleSize = collection.sampleSize;
+lodash.set = object.set;
+lodash.setWith = object.setWith;
+lodash.shuffle = collection.shuffle;
+lodash.slice = array.slice;
+lodash.sortBy = collection.sortBy;
+lodash.sortedUniq = array.sortedUniq;
+lodash.sortedUniqBy = array.sortedUniqBy;
+lodash.split = string.split;
+lodash.spread = func.spread;
+lodash.tail = array.tail;
+lodash.take = array.take;
+lodash.takeRight = array.takeRight;
+lodash.takeRightWhile = array.takeRightWhile;
+lodash.takeWhile = array.takeWhile;
+lodash.tap = seq.tap;
+lodash.throttle = func.throttle;
+lodash.thru = thru;
+lodash.toArray = lang.toArray;
+lodash.toPairs = object.toPairs;
+lodash.toPairsIn = object.toPairsIn;
+lodash.toPath = util.toPath;
+lodash.toPlainObject = lang.toPlainObject;
+lodash.transform = object.transform;
+lodash.unary = func.unary;
+lodash.union = array.union;
+lodash.unionBy = array.unionBy;
+lodash.unionWith = array.unionWith;
+lodash.uniq = array.uniq;
+lodash.uniqBy = array.uniqBy;
+lodash.uniqWith = array.uniqWith;
+lodash.unset = object.unset;
+lodash.unzip = array.unzip;
+lodash.unzipWith = array.unzipWith;
+lodash.values = object.values;
+lodash.valuesIn = object.valuesIn;
+lodash.without = array.without;
+lodash.words = string.words;
+lodash.wrap = func.wrap;
+lodash.xor = array.xor;
+lodash.xorBy = array.xorBy;
+lodash.xorWith = array.xorWith;
+lodash.zip = array.zip;
+lodash.zipObject = array.zipObject;
+lodash.zipWith = array.zipWith;
+
+// Add aliases.
+lodash.each = collection.forEach;
+lodash.eachRight = collection.forEachRight;
+lodash.extend = object.assignIn;
+lodash.extendWith = object.assignInWith;
+
+// Add functions to `lodash.prototype`.
+mixin(lodash, lodash);
+
+// Add functions that return unwrapped values when chaining.
+lodash.add = math.add;
+lodash.attempt = util.attempt;
+lodash.camelCase = string.camelCase;
+lodash.capitalize = string.capitalize;
+lodash.ceil = math.ceil;
+lodash.clamp = number.clamp;
+lodash.clone = lang.clone;
+lodash.cloneDeep = lang.cloneDeep;
+lodash.cloneDeepWith = lang.cloneDeepWith;
+lodash.cloneWith = lang.cloneWith;
+lodash.deburr = string.deburr;
+lodash.endsWith = string.endsWith;
+lodash.eq = lang.eq;
+lodash.escape = string.escape;
+lodash.escapeRegExp = string.escapeRegExp;
+lodash.every = collection.every;
+lodash.find = collection.find;
+lodash.findIndex = array.findIndex;
+lodash.findKey = object.findKey;
+lodash.findLast = collection.findLast;
+lodash.findLastIndex = array.findLastIndex;
+lodash.findLastKey = object.findLastKey;
+lodash.floor = math.floor;
+lodash.forEach = collection.forEach;
+lodash.forEachRight = collection.forEachRight;
+lodash.forIn = object.forIn;
+lodash.forInRight = object.forInRight;
+lodash.forOwn = object.forOwn;
+lodash.forOwnRight = object.forOwnRight;
+lodash.get = object.get;
+lodash.gt = lang.gt;
+lodash.gte = lang.gte;
+lodash.has = object.has;
+lodash.hasIn = object.hasIn;
+lodash.head = array.head;
+lodash.identity = identity;
+lodash.includes = collection.includes;
+lodash.indexOf = array.indexOf;
+lodash.inRange = number.inRange;
+lodash.invoke = object.invoke;
+lodash.isArguments = lang.isArguments;
+lodash.isArray = isArray;
+lodash.isArrayLike = lang.isArrayLike;
+lodash.isArrayLikeObject = lang.isArrayLikeObject;
+lodash.isBoolean = lang.isBoolean;
+lodash.isDate = lang.isDate;
+lodash.isElement = lang.isElement;
+lodash.isEmpty = lang.isEmpty;
+lodash.isEqual = lang.isEqual;
+lodash.isEqualWith = lang.isEqualWith;
+lodash.isError = lang.isError;
+lodash.isFinite = lang.isFinite;
+lodash.isFunction = lang.isFunction;
+lodash.isInteger = lang.isInteger;
+lodash.isLength = lang.isLength;
+lodash.isMatch = lang.isMatch;
+lodash.isMatchWith = lang.isMatchWith;
+lodash.isNaN = lang.isNaN;
+lodash.isNative = lang.isNative;
+lodash.isNil = lang.isNil;
+lodash.isNull = lang.isNull;
+lodash.isNumber = lang.isNumber;
+lodash.isObject = isObject;
+lodash.isObjectLike = lang.isObjectLike;
+lodash.isPlainObject = lang.isPlainObject;
+lodash.isRegExp = lang.isRegExp;
+lodash.isSafeInteger = lang.isSafeInteger;
+lodash.isString = lang.isString;
+lodash.isSymbol = lang.isSymbol;
+lodash.isTypedArray = lang.isTypedArray;
+lodash.isUndefined = lang.isUndefined;
+lodash.join = array.join;
+lodash.kebabCase = string.kebabCase;
+lodash.last = last;
+lodash.lastIndexOf = array.lastIndexOf;
+lodash.lowerCase = string.lowerCase;
+lodash.lowerFirst = string.lowerFirst;
+lodash.lt = lang.lt;
+lodash.lte = lang.lte;
+lodash.max = math.max;
+lodash.maxBy = math.maxBy;
+lodash.mean = math.mean;
+lodash.min = math.min;
+lodash.minBy = math.minBy;
+lodash.noop = util.noop;
+lodash.now = date.now;
+lodash.pad = string.pad;
+lodash.padEnd = string.padEnd;
+lodash.padStart = string.padStart;
+lodash.parseInt = string.parseInt;
+lodash.random = number.random;
+lodash.reduce = collection.reduce;
+lodash.reduceRight = collection.reduceRight;
+lodash.repeat = string.repeat;
+lodash.replace = string.replace;
+lodash.result = object.result;
+lodash.round = math.round;
+lodash.sample = collection.sample;
+lodash.size = collection.size;
+lodash.snakeCase = string.snakeCase;
+lodash.some = collection.some;
+lodash.sortedIndex = array.sortedIndex;
+lodash.sortedIndexBy = array.sortedIndexBy;
+lodash.sortedIndexOf = array.sortedIndexOf;
+lodash.sortedLastIndex = array.sortedLastIndex;
+lodash.sortedLastIndexBy = array.sortedLastIndexBy;
+lodash.sortedLastIndexOf = array.sortedLastIndexOf;
+lodash.startCase = string.startCase;
+lodash.startsWith = string.startsWith;
+lodash.subtract = math.subtract;
+lodash.sum = math.sum;
+lodash.sumBy = math.sumBy;
+lodash.template = string.template;
+lodash.times = util.times;
+lodash.toInteger = toInteger;
+lodash.toLength = lang.toLength;
+lodash.toLower = string.toLower;
+lodash.toNumber = lang.toNumber;
+lodash.toSafeInteger = lang.toSafeInteger;
+lodash.toString = lang.toString;
+lodash.toUpper = string.toUpper;
+lodash.trim = string.trim;
+lodash.trimEnd = string.trimEnd;
+lodash.trimStart = string.trimStart;
+lodash.truncate = string.truncate;
+lodash.unescape = string.unescape;
+lodash.uniqueId = util.uniqueId;
+lodash.upperCase = string.upperCase;
+lodash.upperFirst = string.upperFirst;
+
+// Add aliases.
+lodash.first = array.head;
+
+mixin(lodash, (function() {
+ var source = {};
+ baseForOwn(lodash, function(func, methodName) {
+ if (!hasOwnProperty.call(lodash.prototype, methodName)) {
+ source[methodName] = func;
+ }
+ });
+ return source;
+}()), { 'chain': false });
+
+/**
+ * The semantic version number.
+ *
+ * @static
+ * @memberOf _
+ * @type string
+ */
+lodash.VERSION = VERSION;
+(lodash.templateSettings = string.templateSettings).imports._ = lodash;
+
+// Assign default placeholders.
+arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
+ lodash[methodName].placeholder = lodash;
+});
+
+// Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
+arrayEach(['drop', 'take'], function(methodName, index) {
+ LazyWrapper.prototype[methodName] = function(n) {
+ var filtered = this.__filtered__;
+ if (filtered && !index) {
+ return new LazyWrapper(this);
+ }
+ n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
+
+ var result = this.clone();
+ if (filtered) {
+ result.__takeCount__ = nativeMin(n, result.__takeCount__);
+ } else {
+ result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
+ }
+ return result;
+ };
+
+ LazyWrapper.prototype[methodName + 'Right'] = function(n) {
+ return this.reverse()[methodName](n).reverse();
+ };
+});
+
+// Add `LazyWrapper` methods that accept an `iteratee` value.
+arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
+ var type = index + 1,
+ isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
+
+ LazyWrapper.prototype[methodName] = function(iteratee) {
+ var result = this.clone();
+ result.__iteratees__.push({ 'iteratee': baseIteratee(iteratee, 3), 'type': type });
+ result.__filtered__ = result.__filtered__ || isFilter;
+ return result;
+ };
+});
+
+// Add `LazyWrapper` methods for `_.head` and `_.last`.
+arrayEach(['head', 'last'], function(methodName, index) {
+ var takeName = 'take' + (index ? 'Right' : '');
+
+ LazyWrapper.prototype[methodName] = function() {
+ return this[takeName](1).value()[0];
+ };
+});
+
+// Add `LazyWrapper` methods for `_.initial` and `_.tail`.
+arrayEach(['initial', 'tail'], function(methodName, index) {
+ var dropName = 'drop' + (index ? '' : 'Right');
+
+ LazyWrapper.prototype[methodName] = function() {
+ return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
+ };
+});
+
+LazyWrapper.prototype.compact = function() {
+ return this.filter(identity);
+};
+
+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 = baseIteratee(predicate, 3);
+ return this.filter(function(value) {
+ return !predicate(value);
+ });
+};
+
+LazyWrapper.prototype.slice = function(start, end) {
+ start = toInteger(start);
+
+ var result = this;
+ if (result.__filtered__ && (start > 0 || end < 0)) {
+ return new LazyWrapper(result);
+ }
+ if (start < 0) {
+ result = result.takeRight(-start);
+ } else if (start) {
+ result = result.drop(start);
+ }
+ if (end !== undefined) {
+ end = toInteger(end);
+ result = end < 0 ? result.dropRight(-end) : result.take(end - start);
+ }
+ return result;
+};
+
+LazyWrapper.prototype.takeRightWhile = function(predicate) {
+ return this.reverse().takeWhile(predicate).reverse();
+};
+
+LazyWrapper.prototype.toArray = function() {
+ return this.take(MAX_ARRAY_LENGTH);
+};
+
+// Add `LazyWrapper` methods to `lodash.prototype`.
+baseForOwn(LazyWrapper.prototype, function(func, 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 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 chainAll = this.__chain__,
+ isHybrid = !!this.__actions__.length,
+ isUnwrapped = retUnwrapped && !chainAll,
+ onlyLazy = isLazy && !isHybrid;
+
+ if (!retUnwrapped && useLazy) {
+ value = onlyLazy ? value : new LazyWrapper(this);
+ var result = func.apply(value, args);
+ result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
+ return new LodashWrapper(result, chainAll);
+ }
+ 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(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
+ var func = arrayProto[methodName],
+ chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
+ retUnwrapped = /^(?:pop|shift)$/.test(methodName);
+
+ lodash.prototype[methodName] = function() {
+ var args = arguments;
+ if (retUnwrapped && !this.__chain__) {
+ return func.apply(this.value(), args);
+ }
+ return this[chainName](function(value) {
+ return func.apply(value, args);
+ });
+ };
+});
+
+// Map minified function names to their real names.
+baseForOwn(LazyWrapper.prototype, function(func, methodName) {
+ var lodashFunc = lodash[methodName];
+ if (lodashFunc) {
+ var key = (lodashFunc.name + ''),
+ names = realNames[key] || (realNames[key] = []);
+
+ names.push({ 'name': methodName, 'func': lodashFunc });
+ }
+});
+
+realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];
+
+// Add functions to the lazy wrapper.
+LazyWrapper.prototype.clone = lazyClone;
+LazyWrapper.prototype.reverse = lazyReverse;
+LazyWrapper.prototype.value = lazyValue;
+
+// Add chaining functions to the `lodash` wrapper.
+lodash.prototype.at = seq.at;
+lodash.prototype.chain = seq.wrapperChain;
+lodash.prototype.commit = seq.commit;
+lodash.prototype.flatMap = seq.flatMap;
+lodash.prototype.next = seq.next;
+lodash.prototype.plant = seq.plant;
+lodash.prototype.reverse = seq.reverse;
+lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = seq.value;
+
+if (iteratorSymbol) {
+ lodash.prototype[iteratorSymbol] = seq.toIterator;
+}
+
+export default lodash;
diff --git a/lodash.js b/lodash.js
index dd45ef96b..f65170e3b 100644
--- a/lodash.js
+++ b/lodash.js
@@ -1,551 +1,299 @@
/**
* @license
- * lodash 3.10.1 (Custom Build)
- * Build: `lodash modularize modern exports="es" -o ./`
- * Copyright 2012-2015 The Dojo Foundation
+ * lodash 4.0.0 (Custom Build)
+ * Build: `lodash modularize exports="es" -o ./`
+ * 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
*/
-import array from './array';
-import chain from './chain';
-import collection from './collection';
-import date from './date';
-import func from './function';
-import lang from './lang';
-import math from './math';
-import number from './number';
-import object from './object';
-import string from './string';
-import utility from './utility';
-import LazyWrapper from './internal/LazyWrapper';
-import LodashWrapper from './internal/LodashWrapper';
-import arrayEach from './internal/arrayEach';
-import arrayPush from './internal/arrayPush';
-import baseCallback from './internal/baseCallback';
-import baseForOwn from './internal/baseForOwn';
-import baseFunctions from './internal/baseFunctions';
-import baseMatches from './internal/baseMatches';
-import createHybridWrapper from './internal/createHybridWrapper';
-import identity from './utility/identity';
-import isArray from './lang/isArray';
-import isObject from './lang/isObject';
-import keys from './object/keys';
-import last from './array/last';
-import lazyClone from './internal/lazyClone';
-import lazyReverse from './internal/lazyReverse';
-import lazyValue from './internal/lazyValue';
-import lodash from './chain/lodash';
-import _mixin from './utility/mixin';
-import property from './utility/property';
-import realNames from './internal/realNames';
-import support from './support';
-import thru from './chain/thru';
-
-/** Used as the semantic version number. */
-var VERSION = '3.10.1';
-
-/** Used to compose bitmasks for wrapper metadata. */
-var BIND_KEY_FLAG = 2;
-
-/** Used to indicate the type of lazy iteratees. */
-var LAZY_MAP_FLAG = 2;
-
-/** Used for native method references. */
-var arrayProto = Array.prototype,
- stringProto = String.prototype;
-
-/* Native method references for those with the same name as other `lodash` methods. */
-var nativeFloor = Math.floor,
- nativeMax = Math.max,
- nativeMin = Math.min;
-
-/** Used as references for `-Infinity` and `Infinity`. */
-var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
-
-// wrap `_.mixin` so it works when provided only one argument
-var mixin = (function(func) {
- return function(object, source, options) {
- if (options == null) {
- var isObj = isObject(source),
- props = isObj && keys(source),
- methodNames = props && props.length && baseFunctions(source, props);
-
- if (!(methodNames ? methodNames.length : isObj)) {
- options = source;
- source = object;
- object = this;
- }
- }
- return func(object, source, options);
- };
-}(_mixin));
-
-// Add functions that return wrapped values when chaining.
-lodash.after = func.after;
-lodash.ary = func.ary;
-lodash.assign = object.assign;
-lodash.at = collection.at;
-lodash.before = func.before;
-lodash.bind = func.bind;
-lodash.bindAll = func.bindAll;
-lodash.bindKey = func.bindKey;
-lodash.callback = utility.callback;
-lodash.chain = chain.chain;
-lodash.chunk = array.chunk;
-lodash.compact = array.compact;
-lodash.constant = utility.constant;
-lodash.countBy = collection.countBy;
-lodash.create = object.create;
-lodash.curry = func.curry;
-lodash.curryRight = func.curryRight;
-lodash.debounce = func.debounce;
-lodash.defaults = object.defaults;
-lodash.defaultsDeep = object.defaultsDeep;
-lodash.defer = func.defer;
-lodash.delay = func.delay;
-lodash.difference = array.difference;
-lodash.drop = array.drop;
-lodash.dropRight = array.dropRight;
-lodash.dropRightWhile = array.dropRightWhile;
-lodash.dropWhile = array.dropWhile;
-lodash.fill = array.fill;
-lodash.filter = collection.filter;
-lodash.flatten = array.flatten;
-lodash.flattenDeep = array.flattenDeep;
-lodash.flow = func.flow;
-lodash.flowRight = func.flowRight;
-lodash.forEach = collection.forEach;
-lodash.forEachRight = collection.forEachRight;
-lodash.forIn = object.forIn;
-lodash.forInRight = object.forInRight;
-lodash.forOwn = object.forOwn;
-lodash.forOwnRight = object.forOwnRight;
-lodash.functions = object.functions;
-lodash.groupBy = collection.groupBy;
-lodash.indexBy = collection.indexBy;
-lodash.initial = array.initial;
-lodash.intersection = array.intersection;
-lodash.invert = object.invert;
-lodash.invoke = collection.invoke;
-lodash.keys = keys;
-lodash.keysIn = object.keysIn;
-lodash.map = collection.map;
-lodash.mapKeys = object.mapKeys;
-lodash.mapValues = object.mapValues;
-lodash.matches = utility.matches;
-lodash.matchesProperty = utility.matchesProperty;
-lodash.memoize = func.memoize;
-lodash.merge = object.merge;
-lodash.method = utility.method;
-lodash.methodOf = utility.methodOf;
-lodash.mixin = mixin;
-lodash.modArgs = func.modArgs;
-lodash.negate = func.negate;
-lodash.omit = object.omit;
-lodash.once = func.once;
-lodash.pairs = object.pairs;
-lodash.partial = func.partial;
-lodash.partialRight = func.partialRight;
-lodash.partition = collection.partition;
-lodash.pick = object.pick;
-lodash.pluck = collection.pluck;
-lodash.property = property;
-lodash.propertyOf = utility.propertyOf;
-lodash.pull = array.pull;
-lodash.pullAt = array.pullAt;
-lodash.range = utility.range;
-lodash.rearg = func.rearg;
-lodash.reject = collection.reject;
-lodash.remove = array.remove;
-lodash.rest = array.rest;
-lodash.restParam = func.restParam;
-lodash.set = object.set;
-lodash.shuffle = collection.shuffle;
-lodash.slice = array.slice;
-lodash.sortBy = collection.sortBy;
-lodash.sortByAll = collection.sortByAll;
-lodash.sortByOrder = collection.sortByOrder;
-lodash.spread = func.spread;
-lodash.take = array.take;
-lodash.takeRight = array.takeRight;
-lodash.takeRightWhile = array.takeRightWhile;
-lodash.takeWhile = array.takeWhile;
-lodash.tap = chain.tap;
-lodash.throttle = func.throttle;
-lodash.thru = thru;
-lodash.times = utility.times;
-lodash.toArray = lang.toArray;
-lodash.toPlainObject = lang.toPlainObject;
-lodash.transform = object.transform;
-lodash.union = array.union;
-lodash.uniq = array.uniq;
-lodash.unzip = array.unzip;
-lodash.unzipWith = array.unzipWith;
-lodash.values = object.values;
-lodash.valuesIn = object.valuesIn;
-lodash.where = collection.where;
-lodash.without = array.without;
-lodash.wrap = func.wrap;
-lodash.xor = array.xor;
-lodash.zip = array.zip;
-lodash.zipObject = array.zipObject;
-lodash.zipWith = array.zipWith;
-
-// Add aliases.
-lodash.backflow = func.flowRight;
-lodash.collect = collection.map;
-lodash.compose = func.flowRight;
-lodash.each = collection.forEach;
-lodash.eachRight = collection.forEachRight;
-lodash.extend = object.assign;
-lodash.iteratee = utility.callback;
-lodash.methods = object.functions;
-lodash.object = array.zipObject;
-lodash.select = collection.filter;
-lodash.tail = array.rest;
-lodash.unique = array.uniq;
-
-// Add functions to `lodash.prototype`.
-mixin(lodash, lodash);
-
-// Add functions that return unwrapped values when chaining.
-lodash.add = math.add;
-lodash.attempt = utility.attempt;
-lodash.camelCase = string.camelCase;
-lodash.capitalize = string.capitalize;
-lodash.ceil = math.ceil;
-lodash.clone = lang.clone;
-lodash.cloneDeep = lang.cloneDeep;
-lodash.deburr = string.deburr;
-lodash.endsWith = string.endsWith;
-lodash.escape = string.escape;
-lodash.escapeRegExp = string.escapeRegExp;
-lodash.every = collection.every;
-lodash.find = collection.find;
-lodash.findIndex = array.findIndex;
-lodash.findKey = object.findKey;
-lodash.findLast = collection.findLast;
-lodash.findLastIndex = array.findLastIndex;
-lodash.findLastKey = object.findLastKey;
-lodash.findWhere = collection.findWhere;
-lodash.first = array.first;
-lodash.floor = math.floor;
-lodash.get = object.get;
-lodash.gt = lang.gt;
-lodash.gte = lang.gte;
-lodash.has = object.has;
-lodash.identity = identity;
-lodash.includes = collection.includes;
-lodash.indexOf = array.indexOf;
-lodash.inRange = number.inRange;
-lodash.isArguments = lang.isArguments;
-lodash.isArray = isArray;
-lodash.isBoolean = lang.isBoolean;
-lodash.isDate = lang.isDate;
-lodash.isElement = lang.isElement;
-lodash.isEmpty = lang.isEmpty;
-lodash.isEqual = lang.isEqual;
-lodash.isError = lang.isError;
-lodash.isFinite = lang.isFinite;
-lodash.isFunction = lang.isFunction;
-lodash.isMatch = lang.isMatch;
-lodash.isNaN = lang.isNaN;
-lodash.isNative = lang.isNative;
-lodash.isNull = lang.isNull;
-lodash.isNumber = lang.isNumber;
-lodash.isObject = isObject;
-lodash.isPlainObject = lang.isPlainObject;
-lodash.isRegExp = lang.isRegExp;
-lodash.isString = lang.isString;
-lodash.isTypedArray = lang.isTypedArray;
-lodash.isUndefined = lang.isUndefined;
-lodash.kebabCase = string.kebabCase;
-lodash.last = last;
-lodash.lastIndexOf = array.lastIndexOf;
-lodash.lt = lang.lt;
-lodash.lte = lang.lte;
-lodash.max = math.max;
-lodash.min = math.min;
-lodash.noop = utility.noop;
-lodash.now = date.now;
-lodash.pad = string.pad;
-lodash.padLeft = string.padLeft;
-lodash.padRight = string.padRight;
-lodash.parseInt = string.parseInt;
-lodash.random = number.random;
-lodash.reduce = collection.reduce;
-lodash.reduceRight = collection.reduceRight;
-lodash.repeat = string.repeat;
-lodash.result = object.result;
-lodash.round = math.round;
-lodash.size = collection.size;
-lodash.snakeCase = string.snakeCase;
-lodash.some = collection.some;
-lodash.sortedIndex = array.sortedIndex;
-lodash.sortedLastIndex = array.sortedLastIndex;
-lodash.startCase = string.startCase;
-lodash.startsWith = string.startsWith;
-lodash.sum = math.sum;
-lodash.template = string.template;
-lodash.trim = string.trim;
-lodash.trimLeft = string.trimLeft;
-lodash.trimRight = string.trimRight;
-lodash.trunc = string.trunc;
-lodash.unescape = string.unescape;
-lodash.uniqueId = utility.uniqueId;
-lodash.words = string.words;
-
-// Add aliases.
-lodash.all = collection.every;
-lodash.any = collection.some;
-lodash.contains = collection.includes;
-lodash.eq = lang.isEqual;
-lodash.detect = collection.find;
-lodash.foldl = collection.reduce;
-lodash.foldr = collection.reduceRight;
-lodash.head = array.first;
-lodash.include = collection.includes;
-lodash.inject = collection.reduce;
-
-mixin(lodash, (function() {
- var source = {};
- baseForOwn(lodash, function(func, methodName) {
- if (!lodash.prototype[methodName]) {
- source[methodName] = func;
- }
- });
- return source;
-}()), false);
-
-// Add functions capable of returning wrapped and unwrapped values when chaining.
-lodash.sample = collection.sample;
-
-lodash.prototype.sample = function(n) {
- if (!this.__chain__ && n == null) {
- return collection.sample(this.value());
- }
- return this.thru(function(value) {
- return collection.sample(value, n);
- });
-};
-
-/**
- * The semantic version number.
- *
- * @static
- * @memberOf _
- * @type string
- */
-lodash.VERSION = VERSION;
-
-lodash.support = support;
-(lodash.templateSettings = string.templateSettings).imports._ = lodash;
-
-// Assign default placeholders.
-arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
- lodash[methodName].placeholder = lodash;
-});
-
-// Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
-arrayEach(['drop', 'take'], function(methodName, index) {
- LazyWrapper.prototype[methodName] = function(n) {
- var filtered = this.__filtered__;
- if (filtered && !index) {
- return new LazyWrapper(this);
- }
- n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0);
-
- var result = this.clone();
- if (filtered) {
- result.__takeCount__ = nativeMin(result.__takeCount__, n);
- } else {
- result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
- }
- return result;
- };
-
- LazyWrapper.prototype[methodName + 'Right'] = function(n) {
- return this.reverse()[methodName](n).reverse();
- };
-});
-
-// Add `LazyWrapper` methods that accept an `iteratee` value.
-arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
- var type = index + 1,
- isFilter = type != LAZY_MAP_FLAG;
-
- LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {
- var result = this.clone();
- result.__iteratees__.push({ 'iteratee': baseCallback(iteratee, thisArg, 1), 'type': type });
- result.__filtered__ = result.__filtered__ || isFilter;
- return result;
- };
-});
-
-// Add `LazyWrapper` methods for `_.first` and `_.last`.
-arrayEach(['first', 'last'], function(methodName, index) {
- var takeName = 'take' + (index ? 'Right' : '');
-
- LazyWrapper.prototype[methodName] = function() {
- return this[takeName](1).value()[0];
- };
-});
-
-// Add `LazyWrapper` methods for `_.initial` and `_.rest`.
-arrayEach(['initial', 'rest'], function(methodName, index) {
- var dropName = 'drop' + (index ? '' : 'Right');
-
- LazyWrapper.prototype[methodName] = function() {
- return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
- };
-});
-
-// 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 = baseCallback(predicate, thisArg, 1);
- return this.filter(function(value) {
- return !predicate(value);
- });
-};
-
-LazyWrapper.prototype.slice = function(start, end) {
- start = start == null ? 0 : (+start || 0);
-
- var result = this;
- if (result.__filtered__ && (start > 0 || end < 0)) {
- return new LazyWrapper(result);
- }
- if (start < 0) {
- result = result.takeRight(-start);
- } else if (start) {
- result = result.drop(start);
- }
- if (end !== undefined) {
- end = (+end || 0);
- 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.toArray = function() {
- return this.take(POSITIVE_INFINITY);
-};
-
-// 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];
-
- if (!lodashFunc) {
- return;
- }
- lodash.prototype[methodName] = function() {
- var args = retUnwrapped ? [1] : arguments,
- chainAll = this.__chain__,
- value = this.__wrapped__,
- isHybrid = !!this.__actions__.length,
- isLazy = value instanceof LazyWrapper,
- iteratee = args[0],
- useLazy = isLazy || isArray(value);
-
- if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
- // Avoid lazy use if the iteratee has a "length" value other than `1`.
- 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 },
- onlyLazy = isLazy && !isHybrid;
-
- if (retUnwrapped && !chainAll) {
- if (onlyLazy) {
- value = value.clone();
- value.__actions__.push(action);
- return func.call(value);
- }
- return lodashFunc.call(undefined, this.value())[0];
- }
- if (!retUnwrapped && useLazy) {
- value = onlyLazy ? value : new LazyWrapper(this);
- var result = func.apply(value, args);
- result.__actions__.push(action);
- return new LodashWrapper(result, chainAll);
- }
- return this.thru(interceptor);
- };
-});
-
-// 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],
- chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
- retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName);
-
- lodash.prototype[methodName] = function() {
- var args = arguments;
- if (retUnwrapped && !this.__chain__) {
- return func.apply(this.value(), args);
- }
- return this[chainName](function(value) {
- return func.apply(value, args);
- });
- };
-});
-
-// Map minified function names to their real names.
-baseForOwn(LazyWrapper.prototype, function(func, methodName) {
- var lodashFunc = lodash[methodName];
- if (lodashFunc) {
- var key = (lodashFunc.name + ''),
- names = realNames[key] || (realNames[key] = []);
-
- names.push({ 'name': methodName, 'func': lodashFunc });
- }
-});
-
-realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];
-
-// Add functions to the lazy wrapper.
-LazyWrapper.prototype.clone = lazyClone;
-LazyWrapper.prototype.reverse = lazyReverse;
-LazyWrapper.prototype.value = lazyValue;
-
-// Add chaining functions to the `lodash` wrapper.
-lodash.prototype.chain = chain.wrapperChain;
-lodash.prototype.commit = chain.commit;
-lodash.prototype.concat = chain.concat;
-lodash.prototype.plant = chain.plant;
-lodash.prototype.reverse = chain.reverse;
-lodash.prototype.toString = chain.toString;
-lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = chain.value;
-
-// 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;
-
-export default lodash;
+export { default as add } from './add';
+export { default as after } from './after';
+export { default as ary } from './ary';
+export { default as assign } from './assign';
+export { default as assignIn } from './assignIn';
+export { default as assignInWith } from './assignInWith';
+export { default as assignWith } from './assignWith';
+export { default as at } from './at';
+export { default as attempt } from './attempt';
+export { default as before } from './before';
+export { default as bind } from './bind';
+export { default as bindAll } from './bindAll';
+export { default as bindKey } from './bindKey';
+export { default as camelCase } from './camelCase';
+export { default as capitalize } from './capitalize';
+export { default as ceil } from './ceil';
+export { default as chain } from './chain';
+export { default as chunk } from './chunk';
+export { default as clamp } from './clamp';
+export { default as clone } from './clone';
+export { default as cloneDeep } from './cloneDeep';
+export { default as cloneDeepWith } from './cloneDeepWith';
+export { default as cloneWith } from './cloneWith';
+export { default as commit } from './commit';
+export { default as compact } from './compact';
+export { default as concat } from './concat';
+export { default as cond } from './cond';
+export { default as conforms } from './conforms';
+export { default as constant } from './constant';
+export { default as countBy } from './countBy';
+export { default as create } from './create';
+export { default as curry } from './curry';
+export { default as curryRight } from './curryRight';
+export { default as debounce } from './debounce';
+export { default as deburr } from './deburr';
+export { default as defaults } from './defaults';
+export { default as defaultsDeep } from './defaultsDeep';
+export { default as defer } from './defer';
+export { default as delay } from './delay';
+export { default as difference } from './difference';
+export { default as differenceBy } from './differenceBy';
+export { default as differenceWith } from './differenceWith';
+export { default as drop } from './drop';
+export { default as dropRight } from './dropRight';
+export { default as dropRightWhile } from './dropRightWhile';
+export { default as dropWhile } from './dropWhile';
+export { default as each } from './each';
+export { default as eachRight } from './eachRight';
+export { default as endsWith } from './endsWith';
+export { default as eq } from './eq';
+export { default as escape } from './escape';
+export { default as escapeRegExp } from './escapeRegExp';
+export { default as every } from './every';
+export { default as fill } from './fill';
+export { default as filter } from './filter';
+export { default as find } from './find';
+export { default as findIndex } from './findIndex';
+export { default as findKey } from './findKey';
+export { default as findLast } from './findLast';
+export { default as findLastIndex } from './findLastIndex';
+export { default as findLastKey } from './findLastKey';
+export { default as flatMap } from './flatMap';
+export { default as flatten } from './flatten';
+export { default as flattenDeep } from './flattenDeep';
+export { default as flip } from './flip';
+export { default as floor } from './floor';
+export { default as flow } from './flow';
+export { default as flowRight } from './flowRight';
+export { default as forEach } from './forEach';
+export { default as forEachRight } from './forEachRight';
+export { default as forIn } from './forIn';
+export { default as forInRight } from './forInRight';
+export { default as forOwn } from './forOwn';
+export { default as forOwnRight } from './forOwnRight';
+export { default as fromPairs } from './fromPairs';
+export { default as functions } from './functions';
+export { default as functionsIn } from './functionsIn';
+export { default as get } from './get';
+export { default as groupBy } from './groupBy';
+export { default as gt } from './gt';
+export { default as gte } from './gte';
+export { default as has } from './has';
+export { default as hasIn } from './hasIn';
+export { default as head } from './head';
+export { default as identity } from './identity';
+export { default as inRange } from './inRange';
+export { default as includes } from './includes';
+export { default as indexOf } from './indexOf';
+export { default as initial } from './initial';
+export { default as intersection } from './intersection';
+export { default as intersectionBy } from './intersectionBy';
+export { default as intersectionWith } from './intersectionWith';
+export { default as invert } from './invert';
+export { default as invoke } from './invoke';
+export { default as invokeMap } from './invokeMap';
+export { default as isArguments } from './isArguments';
+export { default as isArray } from './isArray';
+export { default as isArrayLike } from './isArrayLike';
+export { default as isArrayLikeObject } from './isArrayLikeObject';
+export { default as isBoolean } from './isBoolean';
+export { default as isDate } from './isDate';
+export { default as isElement } from './isElement';
+export { default as isEmpty } from './isEmpty';
+export { default as isEqual } from './isEqual';
+export { default as isEqualWith } from './isEqualWith';
+export { default as isError } from './isError';
+export { default as isFinite } from './isFinite';
+export { default as isFunction } from './isFunction';
+export { default as isInteger } from './isInteger';
+export { default as isLength } from './isLength';
+export { default as isMatch } from './isMatch';
+export { default as isMatchWith } from './isMatchWith';
+export { default as isNaN } from './isNaN';
+export { default as isNative } from './isNative';
+export { default as isNil } from './isNil';
+export { default as isNull } from './isNull';
+export { default as isNumber } from './isNumber';
+export { default as isObject } from './isObject';
+export { default as isObjectLike } from './isObjectLike';
+export { default as isPlainObject } from './isPlainObject';
+export { default as isRegExp } from './isRegExp';
+export { default as isSafeInteger } from './isSafeInteger';
+export { default as isString } from './isString';
+export { default as isSymbol } from './isSymbol';
+export { default as isTypedArray } from './isTypedArray';
+export { default as isUndefined } from './isUndefined';
+export { default as iteratee } from './iteratee';
+export { default as join } from './join';
+export { default as kebabCase } from './kebabCase';
+export { default as keyBy } from './keyBy';
+export { default as keys } from './keys';
+export { default as keysIn } from './keysIn';
+export { default as last } from './last';
+export { default as lastIndexOf } from './lastIndexOf';
+export { default as lodash } from './wrapperLodash';
+export { default as lowerCase } from './lowerCase';
+export { default as lowerFirst } from './lowerFirst';
+export { default as lt } from './lt';
+export { default as lte } from './lte';
+export { default as map } from './map';
+export { default as mapKeys } from './mapKeys';
+export { default as mapValues } from './mapValues';
+export { default as matches } from './matches';
+export { default as matchesProperty } from './matchesProperty';
+export { default as max } from './max';
+export { default as maxBy } from './maxBy';
+export { default as mean } from './mean';
+export { default as memoize } from './memoize';
+export { default as merge } from './merge';
+export { default as mergeWith } from './mergeWith';
+export { default as method } from './method';
+export { default as methodOf } from './methodOf';
+export { default as min } from './min';
+export { default as minBy } from './minBy';
+export { default as mixin } from './mixin';
+export { default as negate } from './negate';
+export { default as next } from './next';
+export { default as noop } from './noop';
+export { default as now } from './now';
+export { default as nthArg } from './nthArg';
+export { default as omit } from './omit';
+export { default as omitBy } from './omitBy';
+export { default as once } from './once';
+export { default as orderBy } from './orderBy';
+export { default as over } from './over';
+export { default as overArgs } from './overArgs';
+export { default as overEvery } from './overEvery';
+export { default as overSome } from './overSome';
+export { default as pad } from './pad';
+export { default as padEnd } from './padEnd';
+export { default as padStart } from './padStart';
+export { default as parseInt } from './parseInt';
+export { default as partial } from './partial';
+export { default as partialRight } from './partialRight';
+export { default as partition } from './partition';
+export { default as pick } from './pick';
+export { default as pickBy } from './pickBy';
+export { default as plant } from './plant';
+export { default as property } from './property';
+export { default as propertyOf } from './propertyOf';
+export { default as pull } from './pull';
+export { default as pullAll } from './pullAll';
+export { default as pullAllBy } from './pullAllBy';
+export { default as pullAt } from './pullAt';
+export { default as random } from './random';
+export { default as range } from './range';
+export { default as rangeRight } from './rangeRight';
+export { default as rearg } from './rearg';
+export { default as reduce } from './reduce';
+export { default as reduceRight } from './reduceRight';
+export { default as reject } from './reject';
+export { default as remove } from './remove';
+export { default as repeat } from './repeat';
+export { default as replace } from './replace';
+export { default as rest } from './rest';
+export { default as result } from './result';
+export { default as reverse } from './reverse';
+export { default as round } from './round';
+export { default as sample } from './sample';
+export { default as sampleSize } from './sampleSize';
+export { default as set } from './set';
+export { default as setWith } from './setWith';
+export { default as shuffle } from './shuffle';
+export { default as size } from './size';
+export { default as slice } from './slice';
+export { default as snakeCase } from './snakeCase';
+export { default as some } from './some';
+export { default as sortBy } from './sortBy';
+export { default as sortedIndex } from './sortedIndex';
+export { default as sortedIndexBy } from './sortedIndexBy';
+export { default as sortedIndexOf } from './sortedIndexOf';
+export { default as sortedLastIndex } from './sortedLastIndex';
+export { default as sortedLastIndexBy } from './sortedLastIndexBy';
+export { default as sortedLastIndexOf } from './sortedLastIndexOf';
+export { default as sortedUniq } from './sortedUniq';
+export { default as sortedUniqBy } from './sortedUniqBy';
+export { default as split } from './split';
+export { default as spread } from './spread';
+export { default as startCase } from './startCase';
+export { default as startsWith } from './startsWith';
+export { default as subtract } from './subtract';
+export { default as sum } from './sum';
+export { default as sumBy } from './sumBy';
+export { default as tail } from './tail';
+export { default as take } from './take';
+export { default as takeRight } from './takeRight';
+export { default as takeRightWhile } from './takeRightWhile';
+export { default as takeWhile } from './takeWhile';
+export { default as tap } from './tap';
+export { default as template } from './template';
+export { default as templateSettings } from './templateSettings';
+export { default as throttle } from './throttle';
+export { default as thru } from './thru';
+export { default as times } from './times';
+export { default as toArray } from './toArray';
+export { default as toInteger } from './toInteger';
+export { default as toIterator } from './toIterator';
+export { default as toJSON } from './toJSON';
+export { default as toLength } from './toLength';
+export { default as toLower } from './toLower';
+export { default as toNumber } from './toNumber';
+export { default as toPairs } from './toPairs';
+export { default as toPairsIn } from './toPairsIn';
+export { default as toPath } from './toPath';
+export { default as toPlainObject } from './toPlainObject';
+export { default as toSafeInteger } from './toSafeInteger';
+export { default as toString } from './toString';
+export { default as toUpper } from './toUpper';
+export { default as transform } from './transform';
+export { default as trim } from './trim';
+export { default as trimEnd } from './trimEnd';
+export { default as trimStart } from './trimStart';
+export { default as truncate } from './truncate';
+export { default as unary } from './unary';
+export { default as unescape } from './unescape';
+export { default as union } from './union';
+export { default as unionBy } from './unionBy';
+export { default as unionWith } from './unionWith';
+export { default as uniq } from './uniq';
+export { default as uniqBy } from './uniqBy';
+export { default as uniqWith } from './uniqWith';
+export { default as uniqueId } from './uniqueId';
+export { default as unset } from './unset';
+export { default as unzip } from './unzip';
+export { default as unzipWith } from './unzipWith';
+export { default as upperCase } from './upperCase';
+export { default as upperFirst } from './upperFirst';
+export { default as value } from './value';
+export { default as valueOf } from './valueOf';
+export { default as values } from './values';
+export { default as valuesIn } from './valuesIn';
+export { default as without } from './without';
+export { default as words } from './words';
+export { default as wrap } from './wrap';
+export { default as wrapperAt } from './wrapperAt';
+export { default as wrapperChain } from './wrapperChain';
+export { default as wrapperCommit } from './commit';
+export { default as wrapperFlatMap } from './wrapperFlatMap';
+export { default as wrapperNext } from './next';
+export { default as wrapperPlant } from './plant';
+export { default as wrapperReverse } from './wrapperReverse';
+export { default as wrapperToIterator } from './toIterator';
+export { default as wrapperValue } from './wrapperValue';
+export { default as xor } from './xor';
+export { default as xorBy } from './xorBy';
+export { default as xorWith } from './xorWith';
+export { default as zip } from './zip';
+export { default as zipObject } from './zipObject';
+export { default as zipWith } from './zipWith';
+export { default as default } from './lodash.default';
diff --git a/lowerCase.js b/lowerCase.js
new file mode 100644
index 000000000..e06f7b18b
--- /dev/null
+++ b/lowerCase.js
@@ -0,0 +1,26 @@
+import createCompounder from './internal/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();
+});
+
+export default lowerCase;
diff --git a/lowerFirst.js b/lowerFirst.js
new file mode 100644
index 000000000..f5f6a4fc6
--- /dev/null
+++ b/lowerFirst.js
@@ -0,0 +1,21 @@
+import createCaseFirst from './internal/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');
+
+export default 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/map.js b/map.js
new file mode 100644
index 000000000..cb5139a30
--- /dev/null
+++ b/map.js
@@ -0,0 +1,52 @@
+import arrayMap from './internal/arrayMap';
+import baseIteratee from './internal/baseIteratee';
+import baseMap from './internal/baseMap';
+import isArray from './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));
+}
+
+export default map;
diff --git a/object/mapKeys.js b/mapKeys.js
similarity index 62%
rename from object/mapKeys.js
rename to mapKeys.js
index ae66ea3c8..d1394242f 100644
--- a/object/mapKeys.js
+++ b/mapKeys.js
@@ -1,4 +1,5 @@
-import createObjectMapper from '../internal/createObjectMapper';
+import baseForOwn from './internal/baseForOwn';
+import baseIteratee from './internal/baseIteratee';
/**
* The opposite of `_.mapValues`; this method creates an object with the
@@ -9,9 +10,7 @@ import createObjectMapper from '../internal/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,6 +19,14 @@ import createObjectMapper from '../internal/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;
+}
export default mapKeys;
diff --git a/mapValues.js b/mapValues.js
new file mode 100644
index 000000000..13e1c8326
--- /dev/null
+++ b/mapValues.js
@@ -0,0 +1,39 @@
+import baseForOwn from './internal/baseForOwn';
+import baseIteratee from './internal/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;
+}
+
+export default mapValues;
diff --git a/matches.js b/matches.js
new file mode 100644
index 000000000..e3b06506a
--- /dev/null
+++ b/matches.js
@@ -0,0 +1,30 @@
+import baseClone from './internal/baseClone';
+import baseMatches from './internal/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));
+}
+
+export default matches;
diff --git a/utility/matchesProperty.js b/matchesProperty.js
similarity index 53%
rename from utility/matchesProperty.js
rename to matchesProperty.js
index 273d0ee6b..39a54663e 100644
--- a/utility/matchesProperty.js
+++ b/matchesProperty.js
@@ -1,17 +1,16 @@
-import baseClone from '../internal/baseClone';
-import baseMatchesProperty from '../internal/baseMatchesProperty';
+import baseClone from './internal/baseClone';
+import baseMatchesProperty from './internal/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.default.js b/math.default.js
new file mode 100644
index 000000000..56fc9bca7
--- /dev/null
+++ b/math.default.js
@@ -0,0 +1,18 @@
+import add from './add';
+import ceil from './ceil';
+import floor from './floor';
+import max from './max';
+import maxBy from './maxBy';
+import mean from './mean';
+import min from './min';
+import minBy from './minBy';
+import round from './round';
+import subtract from './subtract';
+import sum from './sum';
+import sumBy from './sumBy';
+
+export default {
+ add, ceil, floor, max, maxBy,
+ mean, min, minBy, round, subtract,
+ sum, sumBy
+};
diff --git a/math.js b/math.js
index 23272eedf..9b7faa088 100644
--- a/math.js
+++ b/math.js
@@ -1,17 +1,13 @@
-import add from './math/add';
-import ceil from './math/ceil';
-import floor from './math/floor';
-import max from './math/max';
-import min from './math/min';
-import round from './math/round';
-import sum from './math/sum';
-
-export default {
- 'add': add,
- 'ceil': ceil,
- 'floor': floor,
- 'max': max,
- 'min': min,
- 'round': round,
- 'sum': sum
-};
+export { default as add } from './add';
+export { default as ceil } from './ceil';
+export { default as floor } from './floor';
+export { default as max } from './max';
+export { default as maxBy } from './maxBy';
+export { default as mean } from './mean';
+export { default as min } from './min';
+export { default as minBy } from './minBy';
+export { default as round } from './round';
+export { default as subtract } from './subtract';
+export { default as sum } from './sum';
+export { default as sumBy } from './sumBy';
+export { default as default } from './math.default';
diff --git a/math/add.js b/math/add.js
deleted file mode 100644
index c8c851d1c..000000000
--- a/math/add.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * 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);
-}
-
-export default add;
diff --git a/math/max.js b/math/max.js
deleted file mode 100644
index 16d05210f..000000000
--- a/math/max.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import createExtremum from '../internal/createExtremum';
-import gt from '../lang/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);
-
-export default max;
diff --git a/math/min.js b/math/min.js
deleted file mode 100644
index 362ba6668..000000000
--- a/math/min.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import createExtremum from '../internal/createExtremum';
-import lt from '../lang/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);
-
-export default min;
diff --git a/math/sum.js b/math/sum.js
deleted file mode 100644
index 536ec7c7c..000000000
--- a/math/sum.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import arraySum from '../internal/arraySum';
-import baseCallback from '../internal/baseCallback';
-import baseSum from '../internal/baseSum';
-import isArray from '../lang/isArray';
-import isIterateeCall from '../internal/isIterateeCall';
-import toIterable from '../internal/toIterable';
-
-/**
- * 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);
-}
-
-export default sum;
diff --git a/max.js b/max.js
new file mode 100644
index 000000000..0efe10a55
--- /dev/null
+++ b/max.js
@@ -0,0 +1,28 @@
+import baseExtremum from './internal/baseExtremum';
+import gt from './gt';
+import identity from './identity';
+
+/**
+ * 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;
+}
+
+export default max;
diff --git a/maxBy.js b/maxBy.js
new file mode 100644
index 000000000..08b632aa5
--- /dev/null
+++ b/maxBy.js
@@ -0,0 +1,33 @@
+import baseExtremum from './internal/baseExtremum';
+import baseIteratee from './internal/baseIteratee';
+import gt from './gt';
+
+/**
+ * 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;
+}
+
+export default maxBy;
diff --git a/mean.js b/mean.js
new file mode 100644
index 000000000..4d917c575
--- /dev/null
+++ b/mean.js
@@ -0,0 +1,20 @@
+import sum from './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);
+}
+
+export default mean;
diff --git a/function/memoize.js b/memoize.js
similarity index 66%
rename from function/memoize.js
rename to memoize.js
index bb4eed49e..42577daf5 100644
--- a/function/memoize.js
+++ b/memoize.js
@@ -1,4 +1,4 @@
-import MapCache from '../internal/MapCache';
+import MapCache from './internal/MapCache';
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -7,14 +7,13 @@ var FUNC_ERROR_TEXT = 'Expected a function';
* Creates a function that memoizes the result of `func`. If `resolver` is
* provided it determines the cache key for storing the result based on the
* 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 @@ var FUNC_ERROR_TEXT = 'Expected a function';
* @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..31ed9c8cc
--- /dev/null
+++ b/merge.js
@@ -0,0 +1,37 @@
+import baseMerge from './internal/baseMerge';
+import createAssigner from './internal/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);
+});
+
+export default merge;
diff --git a/mergeWith.js b/mergeWith.js
new file mode 100644
index 000000000..d03a955e0
--- /dev/null
+++ b/mergeWith.js
@@ -0,0 +1,43 @@
+import baseMerge from './internal/baseMerge';
+import createAssigner from './internal/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);
+});
+
+export default mergeWith;
diff --git a/utility/method.js b/method.js
similarity index 62%
rename from utility/method.js
rename to method.js
index eab75386d..cb951de9c 100644
--- a/utility/method.js
+++ b/method.js
@@ -1,13 +1,13 @@
-import invokePath from '../internal/invokePath';
-import restParam from '../function/restParam';
+import baseInvoke from './internal/baseInvoke';
+import rest from './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.
@@ -21,12 +21,12 @@ import restParam from '../function/restParam';
* _.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 69%
rename from utility/methodOf.js
rename to methodOf.js
index 72dd94259..dfdfb7cb8 100644
--- a/utility/methodOf.js
+++ b/methodOf.js
@@ -1,14 +1,14 @@
-import invokePath from '../internal/invokePath';
-import restParam from '../function/restParam';
+import baseInvoke from './internal/baseInvoke';
+import rest from './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.
@@ -23,9 +23,9 @@ import restParam from '../function/restParam';
* _.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..631fa4473
--- /dev/null
+++ b/min.js
@@ -0,0 +1,28 @@
+import baseExtremum from './internal/baseExtremum';
+import identity from './identity';
+import lt from './lt';
+
+/**
+ * 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;
+}
+
+export default min;
diff --git a/minBy.js b/minBy.js
new file mode 100644
index 000000000..695b573de
--- /dev/null
+++ b/minBy.js
@@ -0,0 +1,33 @@
+import baseExtremum from './internal/baseExtremum';
+import baseIteratee from './internal/baseIteratee';
+import lt from './lt';
+
+/**
+ * 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;
+}
+
+export default minBy;
diff --git a/mixin.js b/mixin.js
new file mode 100644
index 000000000..822d9bde2
--- /dev/null
+++ b/mixin.js
@@ -0,0 +1,74 @@
+import arrayEach from './internal/arrayEach';
+import arrayPush from './internal/arrayPush';
+import baseFunctions from './internal/baseFunctions';
+import copyArray from './internal/copyArray';
+import isFunction from './isFunction';
+import isObject from './isObject';
+import keys from './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;
+}
+
+export default 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..5967dbf9d
--- /dev/null
+++ b/next.js
@@ -0,0 +1,34 @@
+import toArray from './toArray';
+
+/**
+ * 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 };
+}
+
+export default wrapperNext;
diff --git a/utility/noop.js b/noop.js
similarity index 93%
rename from utility/noop.js
rename to noop.js
index 8b697d7bc..b7bed8503 100644
--- a/utility/noop.js
+++ b/noop.js
@@ -4,7 +4,7 @@
*
* @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..8480fdf46
--- /dev/null
+++ b/now.js
@@ -0,0 +1,19 @@
+/**
+ * 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;
+
+export default now;
diff --git a/nthArg.js b/nthArg.js
new file mode 100644
index 000000000..996fe2b52
--- /dev/null
+++ b/nthArg.js
@@ -0,0 +1,25 @@
+import toInteger from './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];
+ };
+}
+
+export default nthArg;
diff --git a/number.default.js b/number.default.js
new file mode 100644
index 000000000..98fd81715
--- /dev/null
+++ b/number.default.js
@@ -0,0 +1,7 @@
+import clamp from './clamp';
+import inRange from './inRange';
+import random from './random';
+
+export default {
+ clamp, inRange, random
+};
diff --git a/number.js b/number.js
index 005dad038..cfffee737 100644
--- a/number.js
+++ b/number.js
@@ -1,7 +1,4 @@
-import inRange from './number/inRange';
-import random from './number/random';
-
-export default {
- 'inRange': inRange,
- 'random': random
-};
+export { default as clamp } from './clamp';
+export { default as inRange } from './inRange';
+export { default as random } from './random';
+export { default as default } from './number.default';
diff --git a/number/random.js b/number/random.js
deleted file mode 100644
index 7ac049bb5..000000000
--- a/number/random.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import baseRandom from '../internal/baseRandom';
-import isIterateeCall from '../internal/isIterateeCall';
-
-/* 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);
-}
-
-export default random;
diff --git a/object.default.js b/object.default.js
new file mode 100644
index 000000000..fcc640a14
--- /dev/null
+++ b/object.default.js
@@ -0,0 +1,50 @@
+import assign from './assign';
+import assignIn from './assignIn';
+import assignInWith from './assignInWith';
+import assignWith from './assignWith';
+import create from './create';
+import defaults from './defaults';
+import defaultsDeep from './defaultsDeep';
+import findKey from './findKey';
+import findLastKey from './findLastKey';
+import forIn from './forIn';
+import forInRight from './forInRight';
+import forOwn from './forOwn';
+import forOwnRight from './forOwnRight';
+import functions from './functions';
+import functionsIn from './functionsIn';
+import get from './get';
+import has from './has';
+import hasIn from './hasIn';
+import invert from './invert';
+import invoke from './invoke';
+import keys from './keys';
+import keysIn from './keysIn';
+import mapKeys from './mapKeys';
+import mapValues from './mapValues';
+import merge from './merge';
+import mergeWith from './mergeWith';
+import omit from './omit';
+import omitBy from './omitBy';
+import pick from './pick';
+import pickBy from './pickBy';
+import result from './result';
+import set from './set';
+import setWith from './setWith';
+import toPairs from './toPairs';
+import toPairsIn from './toPairsIn';
+import transform from './transform';
+import unset from './unset';
+import values from './values';
+import valuesIn from './valuesIn';
+
+export default {
+ 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
+};
diff --git a/object.js b/object.js
index 87dddcc70..a95f299e3 100644
--- a/object.js
+++ b/object.js
@@ -1,61 +1,40 @@
-import assign from './object/assign';
-import create from './object/create';
-import defaults from './object/defaults';
-import defaultsDeep from './object/defaultsDeep';
-import extend from './object/extend';
-import findKey from './object/findKey';
-import findLastKey from './object/findLastKey';
-import forIn from './object/forIn';
-import forInRight from './object/forInRight';
-import forOwn from './object/forOwn';
-import forOwnRight from './object/forOwnRight';
-import functions from './object/functions';
-import get from './object/get';
-import has from './object/has';
-import invert from './object/invert';
-import keys from './object/keys';
-import keysIn from './object/keysIn';
-import mapKeys from './object/mapKeys';
-import mapValues from './object/mapValues';
-import merge from './object/merge';
-import methods from './object/methods';
-import omit from './object/omit';
-import pairs from './object/pairs';
-import pick from './object/pick';
-import result from './object/result';
-import set from './object/set';
-import transform from './object/transform';
-import values from './object/values';
-import valuesIn from './object/valuesIn';
-
-export default {
- 'assign': assign,
- 'create': create,
- 'defaults': defaults,
- 'defaultsDeep': defaultsDeep,
- 'extend': extend,
- 'findKey': findKey,
- 'findLastKey': findLastKey,
- 'forIn': forIn,
- 'forInRight': forInRight,
- 'forOwn': forOwn,
- 'forOwnRight': forOwnRight,
- 'functions': functions,
- 'get': get,
- 'has': has,
- 'invert': invert,
- 'keys': keys,
- 'keysIn': keysIn,
- 'mapKeys': mapKeys,
- 'mapValues': mapValues,
- 'merge': merge,
- 'methods': methods,
- 'omit': omit,
- 'pairs': pairs,
- 'pick': pick,
- 'result': result,
- 'set': set,
- 'transform': transform,
- 'values': values,
- 'valuesIn': valuesIn
-};
+export { default as assign } from './assign';
+export { default as assignIn } from './assignIn';
+export { default as assignInWith } from './assignInWith';
+export { default as assignWith } from './assignWith';
+export { default as create } from './create';
+export { default as defaults } from './defaults';
+export { default as defaultsDeep } from './defaultsDeep';
+export { default as findKey } from './findKey';
+export { default as findLastKey } from './findLastKey';
+export { default as forIn } from './forIn';
+export { default as forInRight } from './forInRight';
+export { default as forOwn } from './forOwn';
+export { default as forOwnRight } from './forOwnRight';
+export { default as functions } from './functions';
+export { default as functionsIn } from './functionsIn';
+export { default as get } from './get';
+export { default as has } from './has';
+export { default as hasIn } from './hasIn';
+export { default as invert } from './invert';
+export { default as invoke } from './invoke';
+export { default as keys } from './keys';
+export { default as keysIn } from './keysIn';
+export { default as mapKeys } from './mapKeys';
+export { default as mapValues } from './mapValues';
+export { default as merge } from './merge';
+export { default as mergeWith } from './mergeWith';
+export { default as omit } from './omit';
+export { default as omitBy } from './omitBy';
+export { default as pick } from './pick';
+export { default as pickBy } from './pickBy';
+export { default as result } from './result';
+export { default as set } from './set';
+export { default as setWith } from './setWith';
+export { default as toPairs } from './toPairs';
+export { default as toPairsIn } from './toPairsIn';
+export { default as transform } from './transform';
+export { default as unset } from './unset';
+export { default as values } from './values';
+export { default as valuesIn } from './valuesIn';
+export { default as default } from './object.default';
diff --git a/object/assign.js b/object/assign.js
deleted file mode 100644
index eaaca53da..000000000
--- a/object/assign.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import assignWith from '../internal/assignWith';
-import baseAssign from '../internal/baseAssign';
-import createAssigner from '../internal/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);
-});
-
-export default assign;
diff --git a/object/defaults.js b/object/defaults.js
deleted file mode 100644
index 70a561dda..000000000
--- a/object/defaults.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import assign from './assign';
-import assignDefaults from '../internal/assignDefaults';
-import createDefaults from '../internal/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);
-
-export default defaults;
diff --git a/object/extend.js b/object/extend.js
deleted file mode 100644
index 89b31da03..000000000
--- a/object/extend.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import assign from './assign'
-export default assign;
diff --git a/object/findKey.js b/object/findKey.js
deleted file mode 100644
index 2132e3314..000000000
--- a/object/findKey.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import baseForOwn from '../internal/baseForOwn';
-import createFindKey from '../internal/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);
-
-export default findKey;
diff --git a/object/findLastKey.js b/object/findLastKey.js
deleted file mode 100644
index d12b2f5ee..000000000
--- a/object/findLastKey.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import baseForOwnRight from '../internal/baseForOwnRight';
-import createFindKey from '../internal/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);
-
-export default findLastKey;
diff --git a/object/functions.js b/object/functions.js
deleted file mode 100644
index 4e5ac25e9..000000000
--- a/object/functions.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import baseFunctions from '../internal/baseFunctions';
-import keysIn from './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));
-}
-
-export default functions;
diff --git a/object/has.js b/object/has.js
deleted file mode 100644
index a4f413c2a..000000000
--- a/object/has.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import baseGet from '../internal/baseGet';
-import baseSlice from '../internal/baseSlice';
-import isArguments from '../lang/isArguments';
-import isArray from '../lang/isArray';
-import isIndex from '../internal/isIndex';
-import isKey from '../internal/isKey';
-import isLength from '../internal/isLength';
-import last from '../array/last';
-import toPath from '../internal/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)));
-}
-
-export default has;
diff --git a/object/keys.js b/object/keys.js
deleted file mode 100644
index 7ef34b37c..000000000
--- a/object/keys.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import getNative from '../internal/getNative';
-import isArrayLike from '../internal/isArrayLike';
-import isObject from '../lang/isObject';
-import shimKeys from '../internal/shimKeys';
-
-/* 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) : [];
-};
-
-export default keys;
diff --git a/object/keysIn.js b/object/keysIn.js
deleted file mode 100644
index 20b9dd281..000000000
--- a/object/keysIn.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import isArguments from '../lang/isArguments';
-import isArray from '../lang/isArray';
-import isIndex from '../internal/isIndex';
-import isLength from '../internal/isLength';
-import isObject from '../lang/isObject';
-
-/** Used for native method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/**
- * Creates an array of the own and inherited enumerable property names of `object`.
- *
- * **Note:** Non-object values are coerced to objects.
- *
- * @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;
- *
- * _.keysIn(new Foo);
- * // => ['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 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)) &&
- !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
- result.push(key);
- }
- }
- return result;
-}
-
-export default keysIn;
diff --git a/object/mapValues.js b/object/mapValues.js
deleted file mode 100644
index 852668b99..000000000
--- a/object/mapValues.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import createObjectMapper from '../internal/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();
-
-export default mapValues;
diff --git a/object/merge.js b/object/merge.js
deleted file mode 100644
index 8f54fbeaf..000000000
--- a/object/merge.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import baseMerge from '../internal/baseMerge';
-import createAssigner from '../internal/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);
-
-export default merge;
diff --git a/object/methods.js b/object/methods.js
deleted file mode 100644
index 265229eb3..000000000
--- a/object/methods.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import functions from './functions'
-export default functions;
diff --git a/object/omit.js b/object/omit.js
deleted file mode 100644
index f89df57c3..000000000
--- a/object/omit.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import arrayMap from '../internal/arrayMap';
-import baseDifference from '../internal/baseDifference';
-import baseFlatten from '../internal/baseFlatten';
-import bindCallback from '../internal/bindCallback';
-import keysIn from './keysIn';
-import pickByArray from '../internal/pickByArray';
-import pickByCallback from '../internal/pickByCallback';
-import restParam from '../function/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);
- });
-});
-
-export default omit;
diff --git a/object/pairs.js b/object/pairs.js
deleted file mode 100644
index 8a4caaf54..000000000
--- a/object/pairs.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import keys from './keys';
-import toObject from '../internal/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;
-}
-
-export default pairs;
diff --git a/object/pick.js b/object/pick.js
deleted file mode 100644
index ed4057896..000000000
--- a/object/pick.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import baseFlatten from '../internal/baseFlatten';
-import bindCallback from '../internal/bindCallback';
-import pickByArray from '../internal/pickByArray';
-import pickByCallback from '../internal/pickByCallback';
-import restParam from '../function/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));
-});
-
-export default pick;
diff --git a/object/set.js b/object/set.js
deleted file mode 100644
index fecfe9f46..000000000
--- a/object/set.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import isIndex from '../internal/isIndex';
-import isKey from '../internal/isKey';
-import isObject from '../lang/isObject';
-import toPath from '../internal/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;
-}
-
-export default set;
diff --git a/omit.js b/omit.js
new file mode 100644
index 000000000..ed341bce8
--- /dev/null
+++ b/omit.js
@@ -0,0 +1,34 @@
+import arrayMap from './internal/arrayMap';
+import baseDifference from './internal/baseDifference';
+import baseFlatten from './internal/baseFlatten';
+import basePick from './internal/basePick';
+import keysIn from './keysIn';
+import rest from './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));
+});
+
+export default omit;
diff --git a/omitBy.js b/omitBy.js
new file mode 100644
index 000000000..f41111a7a
--- /dev/null
+++ b/omitBy.js
@@ -0,0 +1,29 @@
+import baseIteratee from './internal/baseIteratee';
+import basePickBy from './internal/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);
+ });
+}
+
+export default omitBy;
diff --git a/function/once.js b/once.js
similarity index 77%
rename from function/once.js
rename to once.js
index d09ae01ea..5ef7b63c8 100644
--- a/function/once.js
+++ b/once.js
@@ -2,8 +2,8 @@ import before from './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..dd3c2a6d8
--- /dev/null
+++ b/orderBy.js
@@ -0,0 +1,45 @@
+import baseOrderBy from './internal/baseOrderBy';
+import isArray from './isArray';
+
+/**
+ * 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);
+}
+
+export default orderBy;
diff --git a/over.js b/over.js
new file mode 100644
index 000000000..38502a411
--- /dev/null
+++ b/over.js
@@ -0,0 +1,22 @@
+import arrayMap from './internal/arrayMap';
+import createOver from './internal/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);
+
+export default over;
diff --git a/overArgs.js b/overArgs.js
new file mode 100644
index 000000000..5929f42b7
--- /dev/null
+++ b/overArgs.js
@@ -0,0 +1,56 @@
+import apply from './internal/apply';
+import arrayMap from './internal/arrayMap';
+import baseFlatten from './internal/baseFlatten';
+import baseIteratee from './internal/baseIteratee';
+import rest from './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);
+ });
+});
+
+export default overArgs;
diff --git a/overEvery.js b/overEvery.js
new file mode 100644
index 000000000..922624d77
--- /dev/null
+++ b/overEvery.js
@@ -0,0 +1,28 @@
+import arrayEvery from './internal/arrayEvery';
+import createOver from './internal/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);
+
+export default overEvery;
diff --git a/overSome.js b/overSome.js
new file mode 100644
index 000000000..1e41a8b16
--- /dev/null
+++ b/overSome.js
@@ -0,0 +1,28 @@
+import arraySome from './internal/arraySome';
+import createOver from './internal/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);
+
+export default overSome;
diff --git a/package.json b/package.json
index 2f3662244..0376f6def 100644
--- a/package.json
+++ b/package.json
@@ -1,17 +1,16 @@
{
"name": "lodash-es",
- "version": "3.10.1",
- "description": "The modern build of lodash exported as ES modules.",
+ "version": "4.0.0",
+ "description": "Lodash exported as ES modules.",
"homepage": "https://lodash.com/custom-builds",
"license": "MIT",
"jsnext:main": "lodash.js",
+ "main": "lodash.js",
"keywords": "es6, modules, stdlib, util",
"author": "John-David Dalton (http://allyoucanleet.com/)",
"contributors": [
"John-David Dalton (http://allyoucanleet.com/)",
- "Benjamin Tan (https://d10.github.io/)",
- "Blaine Bublitz (http://www.iceddev.com/)",
- "Kit Cambridge (http://kitcambridge.be/)",
+ "Blaine Bublitz (https://github.com/phated)",
"Mathias Bynens (https://mathiasbynens.be/)"
],
"bugs": "https://github.com/lodash/lodash-cli/issues",
diff --git a/string/pad.js b/pad.js
similarity index 59%
rename from string/pad.js
rename to pad.js
index ce8f2707e..887959d2f 100644
--- a/string/pad.js
+++ b/pad.js
@@ -1,11 +1,11 @@
-import baseToString from '../internal/baseToString';
-import createPadding from '../internal/createPadding';
-import root from '../internal/root';
+import createPadding from './internal/createPadding';
+import stringSize from './internal/stringSize';
+import toInteger from './toInteger';
+import toString from './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`.
@@ -30,19 +30,18 @@ var nativeCeil = Math.ceil,
* // => '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);
}
export default pad;
diff --git a/string/padRight.js b/padEnd.js
similarity index 59%
rename from string/padRight.js
rename to padEnd.js
index f4d8dfe97..ada5680fe 100644
--- a/string/padRight.js
+++ b/padEnd.js
@@ -1,4 +1,5 @@
-import createPadDir from '../internal/createPadDir';
+import createPadding from './internal/createPadding';
+import toString from './toString';
/**
* Pads `string` on the right side if it's shorter than `length`. Padding
@@ -13,15 +14,18 @@ import createPadDir from '../internal/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);
+}
-export default padRight;
+export default padEnd;
diff --git a/string/padLeft.js b/padStart.js
similarity index 58%
rename from string/padLeft.js
rename to padStart.js
index a6c361317..4cf076fa1 100644
--- a/string/padLeft.js
+++ b/padStart.js
@@ -1,4 +1,5 @@
-import createPadDir from '../internal/createPadDir';
+import createPadding from './internal/createPadding';
+import toString from './toString';
/**
* Pads `string` on the left side if it's shorter than `length`. Padding
@@ -13,15 +14,18 @@ import createPadDir from '../internal/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;
+}
-export default padLeft;
+export default padStart;
diff --git a/string/parseInt.js b/parseInt.js
similarity index 69%
rename from string/parseInt.js
rename to parseInt.js
index 1267b9d34..793d8ece4 100644
--- a/string/parseInt.js
+++ b/parseInt.js
@@ -1,11 +1,13 @@
-import isIterateeCall from '../internal/isIterateeCall';
-import root from '../internal/root';
-import trim from './trim';
+import root from './internal/root';
+import toString from './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;
/**
@@ -21,7 +23,7 @@ var nativeParseInt = root.parseInt;
* @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
*
@@ -32,15 +34,14 @@ var nativeParseInt = root.parseInt;
* // => [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 72%
rename from function/partial.js
rename to partial.js
index 4cbdb839a..a07c855f2 100644
--- a/function/partial.js
+++ b/partial.js
@@ -1,4 +1,6 @@
-import createPartial from '../internal/createPartial';
+import createWrapper from './internal/createWrapper';
+import replaceHolders from './internal/replaceHolders';
+import rest from './rest';
/** Used to compose bitmasks for wrapper metadata. */
var PARTIAL_FLAG = 32;
@@ -11,7 +13,7 @@ var PARTIAL_FLAG = 32;
* 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,9 +37,9 @@ var PARTIAL_FLAG = 32;
* 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);
+});
export default partial;
diff --git a/function/partialRight.js b/partialRight.js
similarity index 70%
rename from function/partialRight.js
rename to partialRight.js
index 496c46ef9..1fd853b7a 100644
--- a/function/partialRight.js
+++ b/partialRight.js
@@ -1,4 +1,6 @@
-import createPartial from '../internal/createPartial';
+import createWrapper from './internal/createWrapper';
+import replaceHolders from './internal/replaceHolders';
+import rest from './rest';
/** Used to compose bitmasks for wrapper metadata. */
var PARTIAL_RIGHT_FLAG = 64;
@@ -10,7 +12,7 @@ var PARTIAL_RIGHT_FLAG = 64;
* 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,9 +36,9 @@ var PARTIAL_RIGHT_FLAG = 64;
* 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);
+});
export default partialRight;
diff --git a/partition.js b/partition.js
new file mode 100644
index 000000000..732de6144
--- /dev/null
+++ b/partition.js
@@ -0,0 +1,42 @@
+import createAggregator from './internal/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 [[], []]; });
+
+export default partition;
diff --git a/pick.js b/pick.js
new file mode 100644
index 000000000..f3b83631d
--- /dev/null
+++ b/pick.js
@@ -0,0 +1,26 @@
+import baseFlatten from './internal/baseFlatten';
+import basePick from './internal/basePick';
+import rest from './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));
+});
+
+export default pick;
diff --git a/pickBy.js b/pickBy.js
new file mode 100644
index 000000000..6e8202fe6
--- /dev/null
+++ b/pickBy.js
@@ -0,0 +1,25 @@
+import baseIteratee from './internal/baseIteratee';
+import basePickBy from './internal/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));
+}
+
+export default pickBy;
diff --git a/chain/wrapperPlant.js b/plant.js
similarity index 64%
rename from chain/wrapperPlant.js
rename to plant.js
index d06874670..4adaedcac 100644
--- a/chain/wrapperPlant.js
+++ b/plant.js
@@ -1,24 +1,24 @@
-import baseLodash from '../internal/baseLodash';
-import wrapperClone from '../internal/wrapperClone';
+import baseLodash from './internal/baseLodash';
+import wrapperClone from './internal/wrapperClone';
/**
* 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();
@@ -30,6 +30,8 @@ function wrapperPlant(value) {
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 58%
rename from utility/property.js
rename to property.js
index 8ed39c41a..534035f60 100644
--- a/utility/property.js
+++ b/property.js
@@ -1,14 +1,13 @@
-import baseProperty from '../internal/baseProperty';
-import basePropertyDeep from '../internal/basePropertyDeep';
-import isKey from '../internal/isKey';
+import baseProperty from './internal/baseProperty';
+import basePropertyDeep from './internal/basePropertyDeep';
+import isKey from './internal/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
@@ -21,7 +20,7 @@ import isKey from '../internal/isKey';
* _.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 72%
rename from utility/propertyOf.js
rename to propertyOf.js
index cdd8b2a5d..9e4d9349e 100644
--- a/utility/propertyOf.js
+++ b/propertyOf.js
@@ -1,13 +1,12 @@
-import baseGet from '../internal/baseGet';
-import toPath from '../internal/toPath';
+import baseGet from './internal/baseGet';
/**
* 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
@@ -23,7 +22,7 @@ import toPath from '../internal/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..7cf423453
--- /dev/null
+++ b/pull.js
@@ -0,0 +1,27 @@
+import pullAll from './pullAll';
+import rest from './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);
+
+export default pull;
diff --git a/pullAll.js b/pullAll.js
new file mode 100644
index 000000000..d1e2bbba9
--- /dev/null
+++ b/pullAll.js
@@ -0,0 +1,28 @@
+import basePullAll from './internal/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;
+}
+
+export default pullAll;
diff --git a/pullAllBy.js b/pullAllBy.js
new file mode 100644
index 000000000..e9325f47d
--- /dev/null
+++ b/pullAllBy.js
@@ -0,0 +1,32 @@
+import baseIteratee from './internal/baseIteratee';
+import basePullAllBy from './internal/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;
+}
+
+export default pullAllBy;
diff --git a/pullAt.js b/pullAt.js
new file mode 100644
index 000000000..c99e08049
--- /dev/null
+++ b/pullAt.js
@@ -0,0 +1,40 @@
+import arrayMap from './internal/arrayMap';
+import baseAt from './internal/baseAt';
+import baseFlatten from './internal/baseFlatten';
+import basePullAt from './internal/basePullAt';
+import compareAscending from './internal/compareAscending';
+import rest from './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;
+});
+
+export default pullAt;
diff --git a/random.js b/random.js
new file mode 100644
index 000000000..5f23877c5
--- /dev/null
+++ b/random.js
@@ -0,0 +1,81 @@
+import baseRandom from './internal/baseRandom';
+import isIterateeCall from './internal/isIterateeCall';
+import toNumber from './toNumber';
+
+/** 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);
+}
+
+export default random;
diff --git a/range.js b/range.js
new file mode 100644
index 000000000..a2b349943
--- /dev/null
+++ b/range.js
@@ -0,0 +1,45 @@
+import createRange from './internal/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();
+
+export default range;
diff --git a/rangeRight.js b/rangeRight.js
new file mode 100644
index 000000000..fc3f7d511
--- /dev/null
+++ b/rangeRight.js
@@ -0,0 +1,39 @@
+import createRange from './internal/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);
+
+export default rangeRight;
diff --git a/function/rearg.js b/rearg.js
similarity index 70%
rename from function/rearg.js
rename to rearg.js
index f72d0c20e..ea11ab4f5 100644
--- a/function/rearg.js
+++ b/rearg.js
@@ -1,6 +1,6 @@
-import baseFlatten from '../internal/baseFlatten';
-import createWrapper from '../internal/createWrapper';
-import restParam from './restParam';
+import baseFlatten from './internal/baseFlatten';
+import createWrapper from './internal/createWrapper';
+import rest from './rest';
/** Used to compose bitmasks for wrapper metadata. */
var REARG_FLAG = 256;
@@ -16,7 +16,7 @@ var REARG_FLAG = 256;
* @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
*
@@ -26,14 +26,8 @@ var REARG_FLAG = 256;
*
* 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/reduce.js b/reduce.js
new file mode 100644
index 000000000..e0acf968e
--- /dev/null
+++ b/reduce.js
@@ -0,0 +1,49 @@
+import arrayReduce from './internal/arrayReduce';
+import baseEach from './internal/baseEach';
+import baseIteratee from './internal/baseIteratee';
+import baseReduce from './internal/baseReduce';
+import isArray from './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 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`, `orderBy`,
+ * and `sortBy`
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @returns {*} Returns the accumulated value.
+ * @example
+ *
+ * _.reduce([1, 2], function(sum, n) {
+ * return sum + n;
+ * });
+ * // => 3
+ *
+ * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
+ * return result;
+ * }, {});
+ * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
+ */
+function reduce(collection, iteratee, accumulator) {
+ var func = isArray(collection) ? arrayReduce : baseReduce,
+ initFromCollection = arguments.length < 3;
+
+ return func(collection, baseIteratee(iteratee, 4), accumulator, initFromCollection, baseEach);
+}
+
+export default reduce;
diff --git a/reduceRight.js b/reduceRight.js
new file mode 100644
index 000000000..3a79f1770
--- /dev/null
+++ b/reduceRight.js
@@ -0,0 +1,34 @@
+import arrayReduceRight from './internal/arrayReduceRight';
+import baseEachRight from './internal/baseEachRight';
+import baseIteratee from './internal/baseIteratee';
+import baseReduce from './internal/baseReduce';
+import isArray from './isArray';
+
+/**
+ * This method is like `_.reduce` except that it iterates over elements of
+ * `collection` from right to left.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @returns {*} Returns the accumulated value.
+ * @example
+ *
+ * var array = [[0, 1], [2, 3], [4, 5]];
+ *
+ * _.reduceRight(array, function(flattened, other) {
+ * return flattened.concat(other);
+ * }, []);
+ * // => [4, 5, 2, 3, 0, 1]
+ */
+function reduceRight(collection, iteratee, accumulator) {
+ var func = isArray(collection) ? arrayReduceRight : baseReduce,
+ initFromCollection = arguments.length < 3;
+
+ return func(collection, baseIteratee(iteratee, 4), accumulator, initFromCollection, baseEachRight);
+}
+
+export default reduceRight;
diff --git a/reject.js b/reject.js
new file mode 100644
index 000000000..8651c1312
--- /dev/null
+++ b/reject.js
@@ -0,0 +1,46 @@
+import arrayFilter from './internal/arrayFilter';
+import baseFilter from './internal/baseFilter';
+import baseIteratee from './internal/baseIteratee';
+import isArray from './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);
+ });
+}
+
+export default reject;
diff --git a/array/remove.js b/remove.js
similarity index 53%
rename from array/remove.js
rename to remove.js
index 3a03a931c..ffa05fbf5 100644
--- a/array/remove.js
+++ b/remove.js
@@ -1,21 +1,10 @@
-import baseCallback from '../internal/baseCallback';
-import basePullAt from '../internal/basePullAt';
+import baseIteratee from './internal/baseIteratee';
+import basePullAt from './internal/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`.
*
@@ -23,9 +12,7 @@ import basePullAt from '../internal/basePullAt';
* @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
*
@@ -40,7 +27,7 @@ import basePullAt from '../internal/basePullAt';
* console.log(evens);
* // => [2, 4]
*/
-function remove(array, predicate, thisArg) {
+function remove(array, predicate) {
var result = [];
if (!(array && array.length)) {
return result;
@@ -49,7 +36,7 @@ function remove(array, predicate, thisArg) {
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 67%
rename from string/repeat.js
rename to repeat.js
index 7be5b0400..033e79e9c 100644
--- a/string/repeat.js
+++ b/repeat.js
@@ -1,9 +1,11 @@
-import baseToString from '../internal/baseToString';
-import root from '../internal/root';
+import toInteger from './toInteger';
+import toString from './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.
@@ -26,10 +28,11 @@ var nativeFloor = Math.floor,
* // => ''
*/
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..5db1f2026
--- /dev/null
+++ b/replace.js
@@ -0,0 +1,27 @@
+import toString from './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]);
+}
+
+export default replace;
diff --git a/function/restParam.js b/rest.js
similarity index 64%
rename from function/restParam.js
rename to rest.js
index d0f5e4da3..6f8ec16e4 100644
--- a/function/restParam.js
+++ b/rest.js
@@ -1,14 +1,17 @@
+import apply from './internal/apply';
+import toInteger from './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. */
+/* 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 _
@@ -18,7 +21,7 @@ var nativeMax = Math.max;
* @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);
* });
@@ -26,33 +29,33 @@ var nativeMax = Math.max;
* 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);
};
}
-export default restParam;
+export default rest;
diff --git a/object/result.js b/result.js
similarity index 55%
rename from object/result.js
rename to result.js
index 71cc4b556..c5652cb80 100644
--- a/object/result.js
+++ b/result.js
@@ -1,9 +1,8 @@
-import baseGet from '../internal/baseGet';
-import baseSlice from '../internal/baseSlice';
-import isFunction from '../lang/isFunction';
-import isKey from '../internal/isKey';
-import last from '../array/last';
-import toPath from '../internal/toPath';
+import baseToPath from './internal/baseToPath';
+import get from './get';
+import isFunction from './isFunction';
+import isKey from './internal/isKey';
+import parent from './internal/parent';
/**
* This method is like `_.get` except that if the resolved value is a function
@@ -27,21 +26,22 @@ import toPath from '../internal/toPath';
* _.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..c482b5e22
--- /dev/null
+++ b/reverse.js
@@ -0,0 +1,31 @@
+/** 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;
+}
+
+export default reverse;
diff --git a/math/round.js b/round.js
similarity index 70%
rename from math/round.js
rename to round.js
index 9b2728893..ccfd20bee 100644
--- a/math/round.js
+++ b/round.js
@@ -1,12 +1,12 @@
-import createRound from '../internal/createRound';
+import createRound from './internal/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..d1add77d0
--- /dev/null
+++ b/sample.js
@@ -0,0 +1,25 @@
+import baseRandom from './internal/baseRandom';
+import isArrayLike from './isArrayLike';
+import values from './values';
+
+/**
+ * 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;
+}
+
+export default sample;
diff --git a/sampleSize.js b/sampleSize.js
new file mode 100644
index 000000000..cdcfb322c
--- /dev/null
+++ b/sampleSize.js
@@ -0,0 +1,38 @@
+import baseClamp from './internal/baseClamp';
+import baseRandom from './internal/baseRandom';
+import toArray from './toArray';
+import toInteger from './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;
+}
+
+export default sampleSize;
diff --git a/seq.default.js b/seq.default.js
new file mode 100644
index 000000000..811dc0724
--- /dev/null
+++ b/seq.default.js
@@ -0,0 +1,21 @@
+import at from './wrapperAt';
+import chain from './chain';
+import commit from './commit';
+import flatMap from './wrapperFlatMap';
+import lodash from './wrapperLodash';
+import next from './next';
+import plant from './plant';
+import reverse from './wrapperReverse';
+import tap from './tap';
+import thru from './thru';
+import toIterator from './toIterator';
+import toJSON from './toJSON';
+import value from './wrapperValue';
+import valueOf from './valueOf';
+import wrapperChain from './wrapperChain';
+
+export default {
+ at, chain, commit, flatMap, lodash,
+ next, plant, reverse, tap, thru,
+ toIterator, toJSON, value, valueOf, wrapperChain
+};
diff --git a/seq.js b/seq.js
new file mode 100644
index 000000000..9dfa5d89f
--- /dev/null
+++ b/seq.js
@@ -0,0 +1,16 @@
+export { default as at } from './wrapperAt';
+export { default as chain } from './chain';
+export { default as commit } from './commit';
+export { default as flatMap } from './wrapperFlatMap';
+export { default as lodash } from './wrapperLodash';
+export { default as next } from './next';
+export { default as plant } from './plant';
+export { default as reverse } from './wrapperReverse';
+export { default as tap } from './tap';
+export { default as thru } from './thru';
+export { default as toIterator } from './toIterator';
+export { default as toJSON } from './toJSON';
+export { default as value } from './wrapperValue';
+export { default as valueOf } from './valueOf';
+export { default as wrapperChain } from './wrapperChain';
+export { default as default } from './seq.default';
diff --git a/set.js b/set.js
new file mode 100644
index 000000000..eeab21b96
--- /dev/null
+++ b/set.js
@@ -0,0 +1,32 @@
+import baseSet from './internal/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);
+}
+
+export default set;
diff --git a/setWith.js b/setWith.js
new file mode 100644
index 000000000..2950f5860
--- /dev/null
+++ b/setWith.js
@@ -0,0 +1,27 @@
+import baseSet from './internal/baseSet';
+
+/**
+ * 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);
+}
+
+export default setWith;
diff --git a/collection/shuffle.js b/shuffle.js
similarity index 59%
rename from collection/shuffle.js
rename to shuffle.js
index 4ec9ab344..acad96c5a 100644
--- a/collection/shuffle.js
+++ b/shuffle.js
@@ -1,7 +1,7 @@
-import sample from './sample';
+import sampleSize from './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 @@ var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
* @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 @@ var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
* // => [4, 1, 3, 2]
*/
function shuffle(collection) {
- return sample(collection, POSITIVE_INFINITY);
+ return sampleSize(collection, MAX_ARRAY_LENGTH);
}
export default shuffle;
diff --git a/size.js b/size.js
new file mode 100644
index 000000000..57cc21aac
--- /dev/null
+++ b/size.js
@@ -0,0 +1,37 @@
+import isArrayLike from './isArrayLike';
+import isString from './isString';
+import keys from './keys';
+import stringSize from './internal/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;
+}
+
+export default size;
diff --git a/array/slice.js b/slice.js
similarity index 61%
rename from array/slice.js
rename to slice.js
index 0fe0b64e9..bec70cff2 100644
--- a/array/slice.js
+++ b/slice.js
@@ -1,11 +1,12 @@
-import baseSlice from '../internal/baseSlice';
-import isIterateeCall from '../internal/isIterateeCall';
+import baseSlice from './internal/baseSlice';
+import isIterateeCall from './internal/isIterateeCall';
+import toInteger from './toInteger';
/**
* 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 _
@@ -24,6 +25,10 @@ function slice(array, start, end) {
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 90%
rename from string/snakeCase.js
rename to snakeCase.js
index 3dc9a0b3e..8261f3387 100644
--- a/string/snakeCase.js
+++ b/snakeCase.js
@@ -1,4 +1,4 @@
-import createCompounder from '../internal/createCompounder';
+import createCompounder from './internal/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..816faef96
--- /dev/null
+++ b/some.js
@@ -0,0 +1,49 @@
+import arraySome from './internal/arraySome';
+import baseIteratee from './internal/baseIteratee';
+import baseSome from './internal/baseSome';
+import isArray from './isArray';
+import isIterateeCall from './internal/isIterateeCall';
+
+/**
+ * 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));
+}
+
+export default some;
diff --git a/sortBy.js b/sortBy.js
new file mode 100644
index 000000000..cb28447f9
--- /dev/null
+++ b/sortBy.js
@@ -0,0 +1,52 @@
+import baseFlatten from './internal/baseFlatten';
+import baseOrderBy from './internal/baseOrderBy';
+import isIterateeCall from './internal/isIterateeCall';
+import rest from './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), []);
+});
+
+export default sortBy;
diff --git a/sortedIndex.js b/sortedIndex.js
new file mode 100644
index 000000000..4665e01da
--- /dev/null
+++ b/sortedIndex.js
@@ -0,0 +1,25 @@
+import baseSortedIndex from './internal/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);
+}
+
+export default sortedIndex;
diff --git a/sortedIndexBy.js b/sortedIndexBy.js
new file mode 100644
index 000000000..9dec783e6
--- /dev/null
+++ b/sortedIndexBy.js
@@ -0,0 +1,31 @@
+import baseIteratee from './internal/baseIteratee';
+import baseSortedIndexBy from './internal/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));
+}
+
+export default sortedIndexBy;
diff --git a/sortedIndexOf.js b/sortedIndexOf.js
new file mode 100644
index 000000000..6c24cedfa
--- /dev/null
+++ b/sortedIndexOf.js
@@ -0,0 +1,30 @@
+import baseSortedIndex from './internal/baseSortedIndex';
+import eq from './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;
+}
+
+export default sortedIndexOf;
diff --git a/array/sortedLastIndex.js b/sortedLastIndex.js
similarity index 55%
rename from array/sortedLastIndex.js
rename to sortedLastIndex.js
index f817aa5e1..fed0beb48 100644
--- a/array/sortedLastIndex.js
+++ b/sortedLastIndex.js
@@ -1,4 +1,4 @@
-import createSortedIndex from '../internal/createSortedIndex';
+import baseSortedIndex from './internal/baseSortedIndex';
/**
* This method is like `_.sortedIndex` except that it returns the highest
@@ -10,16 +10,14 @@ import createSortedIndex from '../internal/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);
+}
export default sortedLastIndex;
diff --git a/sortedLastIndexBy.js b/sortedLastIndexBy.js
new file mode 100644
index 000000000..dee0af533
--- /dev/null
+++ b/sortedLastIndexBy.js
@@ -0,0 +1,26 @@
+import baseIteratee from './internal/baseIteratee';
+import baseSortedIndexBy from './internal/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);
+}
+
+export default sortedLastIndexBy;
diff --git a/sortedLastIndexOf.js b/sortedLastIndexOf.js
new file mode 100644
index 000000000..2d5b98caf
--- /dev/null
+++ b/sortedLastIndexOf.js
@@ -0,0 +1,30 @@
+import baseSortedIndex from './internal/baseSortedIndex';
+import eq from './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;
+}
+
+export default sortedLastIndexOf;
diff --git a/sortedUniq.js b/sortedUniq.js
new file mode 100644
index 000000000..87b88345a
--- /dev/null
+++ b/sortedUniq.js
@@ -0,0 +1,23 @@
+import baseSortedUniq from './internal/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)
+ : [];
+}
+
+export default sortedUniq;
diff --git a/sortedUniqBy.js b/sortedUniqBy.js
new file mode 100644
index 000000000..d674c6f91
--- /dev/null
+++ b/sortedUniqBy.js
@@ -0,0 +1,25 @@
+import baseIteratee from './internal/baseIteratee';
+import baseSortedUniqBy from './internal/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))
+ : [];
+}
+
+export default sortedUniqBy;
diff --git a/split.js b/split.js
new file mode 100644
index 000000000..94b7cf603
--- /dev/null
+++ b/split.js
@@ -0,0 +1,24 @@
+import toString from './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);
+}
+
+export default split;
diff --git a/function/spread.js b/spread.js
similarity index 90%
rename from function/spread.js
rename to spread.js
index 3f8a05b60..684585eec 100644
--- a/function/spread.js
+++ b/spread.js
@@ -1,3 +1,5 @@
+import apply from './internal/apply';
+
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -5,7 +7,7 @@ var FUNC_ERROR_TEXT = 'Expected a 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 _
@@ -37,7 +39,7 @@ function spread(func) {
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 77%
rename from string/startCase.js
rename to startCase.js
index 854a91f8b..ec7dc7cac 100644
--- a/string/startCase.js
+++ b/startCase.js
@@ -1,4 +1,5 @@
-import createCompounder from '../internal/createCompounder';
+import capitalize from './capitalize';
+import createCompounder from './internal/createCompounder';
/**
* Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
@@ -20,7 +21,7 @@ import createCompounder from '../internal/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);
});
export default startCase;
diff --git a/string/startsWith.js b/startsWith.js
similarity index 68%
rename from string/startsWith.js
rename to startsWith.js
index df9a92862..064fcc6ab 100644
--- a/string/startsWith.js
+++ b/startsWith.js
@@ -1,7 +1,6 @@
-import baseToString from '../internal/baseToString';
-
-/* Native method references for those with the same name as other `lodash` methods. */
-var nativeMin = Math.min;
+import baseClamp from './internal/baseClamp';
+import toInteger from './toInteger';
+import toString from './toString';
/**
* Checks if `string` starts with the given target string.
@@ -25,11 +24,8 @@ var nativeMin = Math.min;
* // => 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.default.js b/string.default.js
new file mode 100644
index 000000000..5cc66f246
--- /dev/null
+++ b/string.default.js
@@ -0,0 +1,41 @@
+import camelCase from './camelCase';
+import capitalize from './capitalize';
+import deburr from './deburr';
+import endsWith from './endsWith';
+import escape from './escape';
+import escapeRegExp from './escapeRegExp';
+import kebabCase from './kebabCase';
+import lowerCase from './lowerCase';
+import lowerFirst from './lowerFirst';
+import pad from './pad';
+import padEnd from './padEnd';
+import padStart from './padStart';
+import parseInt from './parseInt';
+import repeat from './repeat';
+import replace from './replace';
+import snakeCase from './snakeCase';
+import split from './split';
+import startCase from './startCase';
+import startsWith from './startsWith';
+import template from './template';
+import templateSettings from './templateSettings';
+import toLower from './toLower';
+import toUpper from './toUpper';
+import trim from './trim';
+import trimEnd from './trimEnd';
+import trimStart from './trimStart';
+import truncate from './truncate';
+import unescape from './unescape';
+import upperCase from './upperCase';
+import upperFirst from './upperFirst';
+import words from './words';
+
+export default {
+ 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
+};
diff --git a/string.js b/string.js
index ade8e0d35..030db7a3f 100644
--- a/string.js
+++ b/string.js
@@ -1,49 +1,32 @@
-import camelCase from './string/camelCase';
-import capitalize from './string/capitalize';
-import deburr from './string/deburr';
-import endsWith from './string/endsWith';
-import escape from './string/escape';
-import escapeRegExp from './string/escapeRegExp';
-import kebabCase from './string/kebabCase';
-import pad from './string/pad';
-import padLeft from './string/padLeft';
-import padRight from './string/padRight';
-import parseInt from './string/parseInt';
-import repeat from './string/repeat';
-import snakeCase from './string/snakeCase';
-import startCase from './string/startCase';
-import startsWith from './string/startsWith';
-import template from './string/template';
-import templateSettings from './string/templateSettings';
-import trim from './string/trim';
-import trimLeft from './string/trimLeft';
-import trimRight from './string/trimRight';
-import trunc from './string/trunc';
-import unescape from './string/unescape';
-import words from './string/words';
-
-export default {
- 'camelCase': camelCase,
- 'capitalize': capitalize,
- 'deburr': deburr,
- 'endsWith': endsWith,
- 'escape': escape,
- 'escapeRegExp': escapeRegExp,
- 'kebabCase': kebabCase,
- 'pad': pad,
- 'padLeft': padLeft,
- 'padRight': padRight,
- 'parseInt': parseInt,
- 'repeat': repeat,
- 'snakeCase': snakeCase,
- 'startCase': startCase,
- 'startsWith': startsWith,
- 'template': template,
- 'templateSettings': templateSettings,
- 'trim': trim,
- 'trimLeft': trimLeft,
- 'trimRight': trimRight,
- 'trunc': trunc,
- 'unescape': unescape,
- 'words': words
-};
+export { default as camelCase } from './camelCase';
+export { default as capitalize } from './capitalize';
+export { default as deburr } from './deburr';
+export { default as endsWith } from './endsWith';
+export { default as escape } from './escape';
+export { default as escapeRegExp } from './escapeRegExp';
+export { default as kebabCase } from './kebabCase';
+export { default as lowerCase } from './lowerCase';
+export { default as lowerFirst } from './lowerFirst';
+export { default as pad } from './pad';
+export { default as padEnd } from './padEnd';
+export { default as padStart } from './padStart';
+export { default as parseInt } from './parseInt';
+export { default as repeat } from './repeat';
+export { default as replace } from './replace';
+export { default as snakeCase } from './snakeCase';
+export { default as split } from './split';
+export { default as startCase } from './startCase';
+export { default as startsWith } from './startsWith';
+export { default as template } from './template';
+export { default as templateSettings } from './templateSettings';
+export { default as toLower } from './toLower';
+export { default as toUpper } from './toUpper';
+export { default as trim } from './trim';
+export { default as trimEnd } from './trimEnd';
+export { default as trimStart } from './trimStart';
+export { default as truncate } from './truncate';
+export { default as unescape } from './unescape';
+export { default as upperCase } from './upperCase';
+export { default as upperFirst } from './upperFirst';
+export { default as words } from './words';
+export { default as default } from './string.default';
diff --git a/string/escapeRegExp.js b/string/escapeRegExp.js
deleted file mode 100644
index 407635428..000000000
--- a/string/escapeRegExp.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import baseToString from '../internal/baseToString';
-import escapeRegExpChar from '../internal/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 || '(?:)');
-}
-
-export default escapeRegExp;
diff --git a/string/trim.js b/string/trim.js
deleted file mode 100644
index 2aeaf77b9..000000000
--- a/string/trim.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import baseToString from '../internal/baseToString';
-import charsLeftIndex from '../internal/charsLeftIndex';
-import charsRightIndex from '../internal/charsRightIndex';
-import isIterateeCall from '../internal/isIterateeCall';
-import trimmedLeftIndex from '../internal/trimmedLeftIndex';
-import trimmedRightIndex from '../internal/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);
-}
-
-export default trim;
diff --git a/string/trimLeft.js b/string/trimLeft.js
deleted file mode 100644
index 88d78581e..000000000
--- a/string/trimLeft.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import baseToString from '../internal/baseToString';
-import charsLeftIndex from '../internal/charsLeftIndex';
-import isIterateeCall from '../internal/isIterateeCall';
-import trimmedLeftIndex from '../internal/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 + '')));
-}
-
-export default trimLeft;
diff --git a/string/trimRight.js b/string/trimRight.js
deleted file mode 100644
index 31c4bdee9..000000000
--- a/string/trimRight.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import baseToString from '../internal/baseToString';
-import charsRightIndex from '../internal/charsRightIndex';
-import isIterateeCall from '../internal/isIterateeCall';
-import trimmedRightIndex from '../internal/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);
-}
-
-export default trimRight;
diff --git a/string/trunc.js b/string/trunc.js
deleted file mode 100644
index 2e7dcfde4..000000000
--- a/string/trunc.js
+++ /dev/null
@@ -1,105 +0,0 @@
-import baseToString from '../internal/baseToString';
-import isIterateeCall from '../internal/isIterateeCall';
-import isObject from '../lang/isObject';
-import isRegExp from '../lang/isRegExp';
-
-/** 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;
-}
-
-export default trunc;
diff --git a/string/words.js b/string/words.js
deleted file mode 100644
index 7a898b7a0..000000000
--- a/string/words.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import baseToString from '../internal/baseToString';
-import isIterateeCall from '../internal/isIterateeCall';
-
-/** 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) || [];
-}
-
-export default words;
diff --git a/subtract.js b/subtract.js
new file mode 100644
index 000000000..1ed16fdcd
--- /dev/null
+++ b/subtract.js
@@ -0,0 +1,26 @@
+/**
+ * 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;
+}
+
+export default subtract;
diff --git a/sum.js b/sum.js
new file mode 100644
index 000000000..9bba5cfa2
--- /dev/null
+++ b/sum.js
@@ -0,0 +1,23 @@
+import baseSum from './internal/baseSum';
+import identity from './identity';
+
+/**
+ * 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;
+}
+
+export default sum;
diff --git a/sumBy.js b/sumBy.js
new file mode 100644
index 000000000..ce1774839
--- /dev/null
+++ b/sumBy.js
@@ -0,0 +1,32 @@
+import baseIteratee from './internal/baseIteratee';
+import baseSum from './internal/baseSum';
+
+/**
+ * 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;
+}
+
+export default sumBy;
diff --git a/support.js b/support.js
deleted file mode 100644
index 18f6803ee..000000000
--- a/support.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * An object environment feature flags.
- *
- * @static
- * @memberOf _
- * @type Object
- */
-var support = {};
-
-export default support;
diff --git a/array/rest.js b/tail.js
similarity index 77%
rename from array/rest.js
rename to tail.js
index 285876cf2..cf3dcc6ef 100644
--- a/array/rest.js
+++ b/tail.js
@@ -5,17 +5,16 @@ import drop from './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);
}
-export default rest;
+export default tail;
diff --git a/array/take.js b/take.js
similarity index 64%
rename from array/take.js
rename to take.js
index 6f50b8be4..bd5ae3446 100644
--- a/array/take.js
+++ b/take.js
@@ -1,5 +1,5 @@
-import baseSlice from '../internal/baseSlice';
-import isIterateeCall from '../internal/isIterateeCall';
+import baseSlice from './internal/baseSlice';
+import toInteger from './toInteger';
/**
* Creates a slice of `array` with `n` elements taken from the beginning.
@@ -9,7 +9,7 @@ import isIterateeCall from '../internal/isIterateeCall';
* @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
*
@@ -26,13 +26,10 @@ import isIterateeCall from '../internal/isIterateeCall';
* // => []
*/
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 65%
rename from array/takeRight.js
rename to takeRight.js
index 2a7a40f51..014642298 100644
--- a/array/takeRight.js
+++ b/takeRight.js
@@ -1,5 +1,5 @@
-import baseSlice from '../internal/baseSlice';
-import isIterateeCall from '../internal/isIterateeCall';
+import baseSlice from './internal/baseSlice';
+import toInteger from './toInteger';
/**
* Creates a slice of `array` with `n` elements taken from the end.
@@ -9,7 +9,7 @@ import isIterateeCall from '../internal/isIterateeCall';
* @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
*
@@ -30,11 +30,9 @@ function takeRight(array, n, guard) {
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);
}
export default takeRight;
diff --git a/takeRightWhile.js b/takeRightWhile.js
new file mode 100644
index 000000000..300758160
--- /dev/null
+++ b/takeRightWhile.js
@@ -0,0 +1,44 @@
+import baseIteratee from './internal/baseIteratee';
+import baseWhile from './internal/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)
+ : [];
+}
+
+export default takeRightWhile;
diff --git a/takeWhile.js b/takeWhile.js
new file mode 100644
index 000000000..a4baa4256
--- /dev/null
+++ b/takeWhile.js
@@ -0,0 +1,44 @@
+import baseIteratee from './internal/baseIteratee';
+import baseWhile from './internal/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))
+ : [];
+}
+
+export default takeWhile;
diff --git a/chain/tap.js b/tap.js
similarity index 54%
rename from chain/tap.js
rename to tap.js
index 375bb647c..0a31e59d5 100644
--- a/chain/tap.js
+++ b/tap.js
@@ -1,15 +1,14 @@
/**
* 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
*
@@ -21,8 +20,8 @@
* .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 87%
rename from string/template.js
rename to template.js
index 43802125e..e8778ca35 100644
--- a/string/template.js
+++ b/template.js
@@ -1,15 +1,14 @@
-import assignOwnDefaults from '../internal/assignOwnDefaults';
-import assignWith from '../internal/assignWith';
-import attempt from '../utility/attempt';
-import baseAssign from '../internal/baseAssign';
-import baseToString from '../internal/baseToString';
-import baseValues from '../internal/baseValues';
-import escapeStringChar from '../internal/escapeStringChar';
-import isError from '../lang/isError';
-import isIterateeCall from '../internal/isIterateeCall';
-import keys from '../object/keys';
-import reInterpolate from '../internal/reInterpolate';
+import assignInDefaults from './internal/assignInDefaults';
+import assignInWith from './assignInWith';
+import attempt from './attempt';
+import baseValues from './internal/baseValues';
+import escapeStringChar from './internal/escapeStringChar';
+import isError from './isError';
+import isIterateeCall from './internal/isIterateeCall';
+import keys from './keys';
+import reInterpolate from './internal/reInterpolate';
import templateSettings from './templateSettings';
+import toString from './toString';
/** Used to match empty string literals in compiled template source. */
var reEmptyStringLeading = /\b__p \+= '';/g,
@@ -53,7 +52,7 @@ var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
* @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
*
@@ -121,18 +120,18 @@ var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
* };\
* ');
*/
-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);
@@ -173,8 +172,8 @@ function template(string, options, otherOptions) {
}
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 a42393b71..5bce93057 100644
--- a/string/templateSettings.js
+++ b/templateSettings.js
@@ -1,7 +1,7 @@
import escape from './escape';
-import reEscape from '../internal/reEscape';
-import reEvaluate from '../internal/reEvaluate';
-import reInterpolate from '../internal/reInterpolate';
+import reEscape from './internal/reEscape';
+import reEvaluate from './internal/reEvaluate';
+import reInterpolate from './internal/reInterpolate';
/**
* By default, the template delimiters used by lodash are like those in
diff --git a/function/throttle.js b/throttle.js
similarity index 71%
rename from function/throttle.js
rename to throttle.js
index cd38564fe..acf7d58ea 100644
--- a/function/throttle.js
+++ b/throttle.js
@@ -1,5 +1,5 @@
import debounce from './debounce';
-import isObject from '../lang/isObject';
+import isObject from './isObject';
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -7,10 +7,12 @@ var FUNC_ERROR_TEXT = 'Expected a function';
/**
* 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
@@ -36,11 +38,10 @@ var FUNC_ERROR_TEXT = 'Expected a function';
* 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) {
@@ -50,13 +51,11 @@ function throttle(func, wait, options) {
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 });
}
export default throttle;
diff --git a/chain/thru.js b/thru.js
similarity index 73%
rename from chain/thru.js
rename to thru.js
index e5e75637c..14813cf26 100644
--- a/chain/thru.js
+++ b/thru.js
@@ -3,10 +3,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
*
@@ -19,8 +18,8 @@
* .value();
* // => ['abc']
*/
-function thru(value, interceptor, thisArg) {
- return interceptor.call(thisArg, value);
+function thru(value, interceptor) {
+ return interceptor(value);
}
export default thru;
diff --git a/times.js b/times.js
new file mode 100644
index 000000000..06cda5d92
--- /dev/null
+++ b/times.js
@@ -0,0 +1,50 @@
+import baseTimes from './internal/baseTimes';
+import toFunction from './internal/toFunction';
+import toInteger from './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;
+}
+
+export default times;
diff --git a/toArray.js b/toArray.js
new file mode 100644
index 000000000..4b3edd2fa
--- /dev/null
+++ b/toArray.js
@@ -0,0 +1,57 @@
+import _Symbol from './internal/_Symbol';
+import copyArray from './internal/copyArray';
+import getTag from './internal/getTag';
+import isArrayLike from './isArrayLike';
+import isString from './isString';
+import iteratorToArray from './internal/iteratorToArray';
+import mapToArray from './internal/mapToArray';
+import setToArray from './internal/setToArray';
+import stringToArray from './internal/stringToArray';
+import values from './values';
+
+/** `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);
+}
+
+export default toArray;
diff --git a/toInteger.js b/toInteger.js
new file mode 100644
index 000000000..879ef02fa
--- /dev/null
+++ b/toInteger.js
@@ -0,0 +1,44 @@
+import toNumber from './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;
+}
+
+export default toInteger;
diff --git a/toIterator.js b/toIterator.js
new file mode 100644
index 000000000..c05ecf91d
--- /dev/null
+++ b/toIterator.js
@@ -0,0 +1,22 @@
+/**
+ * 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;
+}
+
+export default wrapperToIterator;
diff --git a/toJSON.js b/toJSON.js
new file mode 100644
index 000000000..bca71bc8e
--- /dev/null
+++ b/toJSON.js
@@ -0,0 +1 @@
+export { default } from './wrapperValue'
diff --git a/toLength.js b/toLength.js
new file mode 100644
index 000000000..82b240026
--- /dev/null
+++ b/toLength.js
@@ -0,0 +1,36 @@
+import baseClamp from './internal/baseClamp';
+import toInteger from './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;
+}
+
+export default toLength;
diff --git a/toLower.js b/toLower.js
new file mode 100644
index 000000000..4a8b452cf
--- /dev/null
+++ b/toLower.js
@@ -0,0 +1,26 @@
+import toString from './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();
+}
+
+export default toLower;
diff --git a/toNumber.js b/toNumber.js
new file mode 100644
index 000000000..ba7d85b49
--- /dev/null
+++ b/toNumber.js
@@ -0,0 +1,59 @@
+import isFunction from './isFunction';
+import isObject from './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);
+}
+
+export default toNumber;
diff --git a/toPairs.js b/toPairs.js
new file mode 100644
index 000000000..3aefd1751
--- /dev/null
+++ b/toPairs.js
@@ -0,0 +1,28 @@
+import baseToPairs from './internal/baseToPairs';
+import keys from './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));
+}
+
+export default toPairs;
diff --git a/toPairsIn.js b/toPairsIn.js
new file mode 100644
index 000000000..5b198c4c7
--- /dev/null
+++ b/toPairsIn.js
@@ -0,0 +1,28 @@
+import baseToPairs from './internal/baseToPairs';
+import keysIn from './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));
+}
+
+export default toPairsIn;
diff --git a/toPath.js b/toPath.js
new file mode 100644
index 000000000..fa0bd118b
--- /dev/null
+++ b/toPath.js
@@ -0,0 +1,34 @@
+import arrayMap from './internal/arrayMap';
+import isArray from './isArray';
+import stringToPath from './internal/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);
+}
+
+export default toPath;
diff --git a/lang/toPlainObject.js b/toPlainObject.js
similarity index 82%
rename from lang/toPlainObject.js
rename to toPlainObject.js
index 8ddb4d58f..9bab37ad7 100644
--- a/lang/toPlainObject.js
+++ b/toPlainObject.js
@@ -1,5 +1,5 @@
-import baseCopy from '../internal/baseCopy';
-import keysIn from '../object/keysIn';
+import copyObject from './internal/copyObject';
+import keysIn from './keysIn';
/**
* Converts `value` to a plain object flattening inherited enumerable
@@ -25,7 +25,7 @@ import keysIn from '../object/keysIn';
* // => { 'a': 1, 'b': 2, 'c': 3 }
*/
function toPlainObject(value) {
- return baseCopy(value, keysIn(value));
+ return copyObject(value, keysIn(value));
}
export default toPlainObject;
diff --git a/toSafeInteger.js b/toSafeInteger.js
new file mode 100644
index 000000000..c608ee09a
--- /dev/null
+++ b/toSafeInteger.js
@@ -0,0 +1,34 @@
+import baseClamp from './internal/baseClamp';
+import toInteger from './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);
+}
+
+export default toSafeInteger;
diff --git a/toString.js b/toString.js
new file mode 100644
index 000000000..b0ea461d1
--- /dev/null
+++ b/toString.js
@@ -0,0 +1,46 @@
+import _Symbol from './internal/_Symbol';
+import isSymbol from './isSymbol';
+
+/** 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;
+}
+
+export default toString;
diff --git a/toUpper.js b/toUpper.js
new file mode 100644
index 000000000..b1da10938
--- /dev/null
+++ b/toUpper.js
@@ -0,0 +1,26 @@
+import toString from './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();
+}
+
+export default toUpper;
diff --git a/object/transform.js b/transform.js
similarity index 58%
rename from object/transform.js
rename to transform.js
index d2bee9b84..fdbe2c7d8 100644
--- a/object/transform.js
+++ b/transform.js
@@ -1,19 +1,19 @@
-import arrayEach from '../internal/arrayEach';
-import baseCallback from '../internal/baseCallback';
-import baseCreate from '../internal/baseCreate';
-import baseForOwn from '../internal/baseForOwn';
-import isArray from '../lang/isArray';
-import isFunction from '../lang/isFunction';
-import isObject from '../lang/isObject';
-import isTypedArray from '../lang/isTypedArray';
+import arrayEach from './internal/arrayEach';
+import baseCreate from './internal/baseCreate';
+import baseForOwn from './internal/baseForOwn';
+import baseIteratee from './internal/baseIteratee';
+import isArray from './isArray';
+import isFunction from './isFunction';
+import isObject from './isObject';
+import isTypedArray from './isTypedArray';
/**
* 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 _
@@ -21,7 +21,6 @@ import isTypedArray from '../lang/isTypedArray';
* @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
*
@@ -31,14 +30,14 @@ import isTypedArray from '../lang/isTypedArray';
* });
* // => [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..adc9ad8f3
--- /dev/null
+++ b/trim.js
@@ -0,0 +1,48 @@
+import charsEndIndex from './internal/charsEndIndex';
+import charsStartIndex from './internal/charsStartIndex';
+import stringToArray from './internal/stringToArray';
+import toString from './toString';
+
+/** 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('');
+}
+
+export default trim;
diff --git a/trimEnd.js b/trimEnd.js
new file mode 100644
index 000000000..bf10e4902
--- /dev/null
+++ b/trimEnd.js
@@ -0,0 +1,42 @@
+import charsEndIndex from './internal/charsEndIndex';
+import stringToArray from './internal/stringToArray';
+import toString from './toString';
+
+/** 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('');
+}
+
+export default trimEnd;
diff --git a/trimStart.js b/trimStart.js
new file mode 100644
index 000000000..203873bb5
--- /dev/null
+++ b/trimStart.js
@@ -0,0 +1,42 @@
+import charsStartIndex from './internal/charsStartIndex';
+import stringToArray from './internal/stringToArray';
+import toString from './toString';
+
+/** 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('');
+}
+
+export default trimStart;
diff --git a/truncate.js b/truncate.js
new file mode 100644
index 000000000..7cc181fb3
--- /dev/null
+++ b/truncate.js
@@ -0,0 +1,118 @@
+import isObject from './isObject';
+import isRegExp from './isRegExp';
+import stringSize from './internal/stringSize';
+import stringToArray from './internal/stringToArray';
+import toInteger from './toInteger';
+import toString from './toString';
+
+/** 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;
+}
+
+export default truncate;
diff --git a/unary.js b/unary.js
new file mode 100644
index 000000000..e92aba57e
--- /dev/null
+++ b/unary.js
@@ -0,0 +1,21 @@
+import ary from './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);
+}
+
+export default unary;
diff --git a/string/unescape.js b/unescape.js
similarity index 86%
rename from string/unescape.js
rename to unescape.js
index 556af6350..488cf9982 100644
--- a/string/unescape.js
+++ b/unescape.js
@@ -1,5 +1,5 @@
-import baseToString from '../internal/baseToString';
-import unescapeHtmlChar from '../internal/unescapeHtmlChar';
+import toString from './toString';
+import unescapeHtmlChar from './internal/unescapeHtmlChar';
/** Used to match HTML entities and HTML characters. */
var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
@@ -24,7 +24,7 @@ var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
* // => '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 66%
rename from array/union.js
rename to union.js
index 226f956a2..88138f7e4 100644
--- a/array/union.js
+++ b/union.js
@@ -1,6 +1,6 @@
-import baseFlatten from '../internal/baseFlatten';
-import baseUniq from '../internal/baseUniq';
-import restParam from '../function/restParam';
+import baseFlatten from './internal/baseFlatten';
+import baseUniq from './internal/baseUniq';
+import rest from './rest';
/**
* Creates an array of unique values, in order, from all of the provided arrays
@@ -14,10 +14,10 @@ import restParam from '../function/restParam';
* @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..2a8c16825
--- /dev/null
+++ b/unionBy.js
@@ -0,0 +1,36 @@
+import baseFlatten from './internal/baseFlatten';
+import baseIteratee from './internal/baseIteratee';
+import baseUniq from './internal/baseUniq';
+import isArrayLikeObject from './isArrayLikeObject';
+import last from './last';
+import rest from './rest';
+
+/**
+ * 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));
+});
+
+export default unionBy;
diff --git a/unionWith.js b/unionWith.js
new file mode 100644
index 000000000..78dcf83af
--- /dev/null
+++ b/unionWith.js
@@ -0,0 +1,34 @@
+import baseFlatten from './internal/baseFlatten';
+import baseUniq from './internal/baseUniq';
+import isArrayLikeObject from './isArrayLikeObject';
+import last from './last';
+import rest from './rest';
+
+/**
+ * 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);
+});
+
+export default unionWith;
diff --git a/uniq.js b/uniq.js
new file mode 100644
index 000000000..24164bfde
--- /dev/null
+++ b/uniq.js
@@ -0,0 +1,25 @@
+import baseUniq from './internal/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)
+ : [];
+}
+
+export default uniq;
diff --git a/uniqBy.js b/uniqBy.js
new file mode 100644
index 000000000..e3a6e74b7
--- /dev/null
+++ b/uniqBy.js
@@ -0,0 +1,30 @@
+import baseIteratee from './internal/baseIteratee';
+import baseUniq from './internal/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))
+ : [];
+}
+
+export default uniqBy;
diff --git a/uniqWith.js b/uniqWith.js
new file mode 100644
index 000000000..1f36cf699
--- /dev/null
+++ b/uniqWith.js
@@ -0,0 +1,27 @@
+import baseUniq from './internal/baseUniq';
+
+/**
+ * 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)
+ : [];
+}
+
+export default uniqWith;
diff --git a/utility/uniqueId.js b/uniqueId.js
similarity index 80%
rename from utility/uniqueId.js
rename to uniqueId.js
index eb414fc72..e416f971b 100644
--- a/utility/uniqueId.js
+++ b/uniqueId.js
@@ -1,4 +1,4 @@
-import baseToString from '../internal/baseToString';
+import toString from './toString';
/** Used to generate unique IDs. */
var idCounter = 0;
@@ -8,7 +8,7 @@ var idCounter = 0;
*
* @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 @@ var idCounter = 0;
*/
function uniqueId(prefix) {
var id = ++idCounter;
- return baseToString(prefix) + id;
+ return toString(prefix) + id;
}
export default uniqueId;
diff --git a/unset.js b/unset.js
new file mode 100644
index 000000000..6f184b2e4
--- /dev/null
+++ b/unset.js
@@ -0,0 +1,31 @@
+import baseUnset from './internal/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);
+}
+
+export default unset;
diff --git a/array/unzip.js b/unzip.js
similarity index 62%
rename from array/unzip.js
rename to unzip.js
index 841b8174f..bda6c3f3b 100644
--- a/array/unzip.js
+++ b/unzip.js
@@ -1,9 +1,10 @@
-import arrayFilter from '../internal/arrayFilter';
-import arrayMap from '../internal/arrayMap';
-import baseProperty from '../internal/baseProperty';
-import isArrayLike from '../internal/isArrayLike';
+import arrayFilter from './internal/arrayFilter';
+import arrayMap from './internal/arrayMap';
+import baseProperty from './internal/baseProperty';
+import baseTimes from './internal/baseTimes';
+import isArrayLikeObject from './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;
/**
@@ -28,20 +29,16 @@ function unzip(array) {
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));
+ });
}
export default unzip;
diff --git a/unzipWith.js b/unzipWith.js
new file mode 100644
index 000000000..99f9ed634
--- /dev/null
+++ b/unzipWith.js
@@ -0,0 +1,37 @@
+import apply from './internal/apply';
+import arrayMap from './internal/arrayMap';
+import unzip from './unzip';
+
+/**
+ * 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);
+ });
+}
+
+export default unzipWith;
diff --git a/upperCase.js b/upperCase.js
new file mode 100644
index 000000000..6eca5dd2c
--- /dev/null
+++ b/upperCase.js
@@ -0,0 +1,26 @@
+import createCompounder from './internal/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();
+});
+
+export default upperCase;
diff --git a/upperFirst.js b/upperFirst.js
new file mode 100644
index 000000000..8cd4e8bcb
--- /dev/null
+++ b/upperFirst.js
@@ -0,0 +1,21 @@
+import createCaseFirst from './internal/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');
+
+export default upperFirst;
diff --git a/util.default.js b/util.default.js
new file mode 100644
index 000000000..d2b93e508
--- /dev/null
+++ b/util.default.js
@@ -0,0 +1,35 @@
+import attempt from './attempt';
+import bindAll from './bindAll';
+import cond from './cond';
+import conforms from './conforms';
+import constant from './constant';
+import flow from './flow';
+import flowRight from './flowRight';
+import identity from './identity';
+import iteratee from './iteratee';
+import matches from './matches';
+import matchesProperty from './matchesProperty';
+import method from './method';
+import methodOf from './methodOf';
+import mixin from './mixin';
+import noop from './noop';
+import nthArg from './nthArg';
+import over from './over';
+import overEvery from './overEvery';
+import overSome from './overSome';
+import property from './property';
+import propertyOf from './propertyOf';
+import range from './range';
+import rangeRight from './rangeRight';
+import times from './times';
+import toPath from './toPath';
+import uniqueId from './uniqueId';
+
+export default {
+ 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
+};
diff --git a/util.js b/util.js
new file mode 100644
index 000000000..21aea586c
--- /dev/null
+++ b/util.js
@@ -0,0 +1,27 @@
+export { default as attempt } from './attempt';
+export { default as bindAll } from './bindAll';
+export { default as cond } from './cond';
+export { default as conforms } from './conforms';
+export { default as constant } from './constant';
+export { default as flow } from './flow';
+export { default as flowRight } from './flowRight';
+export { default as identity } from './identity';
+export { default as iteratee } from './iteratee';
+export { default as matches } from './matches';
+export { default as matchesProperty } from './matchesProperty';
+export { default as method } from './method';
+export { default as methodOf } from './methodOf';
+export { default as mixin } from './mixin';
+export { default as noop } from './noop';
+export { default as nthArg } from './nthArg';
+export { default as over } from './over';
+export { default as overEvery } from './overEvery';
+export { default as overSome } from './overSome';
+export { default as property } from './property';
+export { default as propertyOf } from './propertyOf';
+export { default as range } from './range';
+export { default as rangeRight } from './rangeRight';
+export { default as times } from './times';
+export { default as toPath } from './toPath';
+export { default as uniqueId } from './uniqueId';
+export { default as default } from './util.default';
diff --git a/utility.js b/utility.js
deleted file mode 100644
index dd47a8245..000000000
--- a/utility.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import attempt from './utility/attempt';
-import callback from './utility/callback';
-import constant from './utility/constant';
-import identity from './utility/identity';
-import iteratee from './utility/iteratee';
-import matches from './utility/matches';
-import matchesProperty from './utility/matchesProperty';
-import method from './utility/method';
-import methodOf from './utility/methodOf';
-import mixin from './utility/mixin';
-import noop from './utility/noop';
-import property from './utility/property';
-import propertyOf from './utility/propertyOf';
-import range from './utility/range';
-import times from './utility/times';
-import uniqueId from './utility/uniqueId';
-
-export default {
- '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 bd5d9c60a..000000000
--- a/utility/callback.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import baseCallback from '../internal/baseCallback';
-import isIterateeCall from '../internal/isIterateeCall';
-import isObjectLike from '../internal/isObjectLike';
-import matches from './matches';
-
-/**
- * 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);
-}
-
-export default callback;
diff --git a/utility/iteratee.js b/utility/iteratee.js
deleted file mode 100644
index aeb12e4af..000000000
--- a/utility/iteratee.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import callback from './callback'
-export default callback;
diff --git a/utility/matches.js b/utility/matches.js
deleted file mode 100644
index aa29d1e19..000000000
--- a/utility/matches.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import baseClone from '../internal/baseClone';
-import baseMatches from '../internal/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));
-}
-
-export default matches;
diff --git a/utility/mixin.js b/utility/mixin.js
deleted file mode 100644
index d4eb600f4..000000000
--- a/utility/mixin.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import arrayCopy from '../internal/arrayCopy';
-import arrayPush from '../internal/arrayPush';
-import baseFunctions from '../internal/baseFunctions';
-import isFunction from '../lang/isFunction';
-import isObject from '../lang/isObject';
-import keys from '../object/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;
-}
-
-export default mixin;
diff --git a/utility/range.js b/utility/range.js
deleted file mode 100644
index b8c31a7a2..000000000
--- a/utility/range.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import isIterateeCall from '../internal/isIterateeCall';
-
-/* 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;
-}
-
-export default range;
diff --git a/utility/times.js b/utility/times.js
deleted file mode 100644
index c4a2c2cde..000000000
--- a/utility/times.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import bindCallback from '../internal/bindCallback';
-import root from '../internal/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;
-}
-
-export default times;
diff --git a/value.js b/value.js
new file mode 100644
index 000000000..bca71bc8e
--- /dev/null
+++ b/value.js
@@ -0,0 +1 @@
+export { default } from './wrapperValue'
diff --git a/valueOf.js b/valueOf.js
new file mode 100644
index 000000000..bca71bc8e
--- /dev/null
+++ b/valueOf.js
@@ -0,0 +1 @@
+export { default } from './wrapperValue'
diff --git a/object/values.js b/values.js
similarity index 84%
rename from object/values.js
rename to values.js
index a1c7d6287..b1525e329 100644
--- a/object/values.js
+++ b/values.js
@@ -1,4 +1,4 @@
-import baseValues from '../internal/baseValues';
+import baseValues from './internal/baseValues';
import keys from './keys';
/**
@@ -27,7 +27,7 @@ import keys from './keys';
* // => ['h', 'i']
*/
function values(object) {
- return baseValues(object, keys(object));
+ return object ? baseValues(object, keys(object)) : [];
}
export default values;
diff --git a/object/valuesIn.js b/valuesIn.js
similarity index 80%
rename from object/valuesIn.js
rename to valuesIn.js
index c766fd062..3cea6d2ae 100644
--- a/object/valuesIn.js
+++ b/valuesIn.js
@@ -1,9 +1,8 @@
-import baseValues from '../internal/baseValues';
+import baseValues from './internal/baseValues';
import keysIn from './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.
*
@@ -25,7 +24,7 @@ import keysIn from './keysIn';
* // => [1, 2, 3] (iteration order is not guaranteed)
*/
function valuesIn(object) {
- return baseValues(object, keysIn(object));
+ return object == null ? baseValues(object, keysIn(object)) : [];
}
export default valuesIn;
diff --git a/array/without.js b/without.js
similarity index 69%
rename from array/without.js
rename to without.js
index e49135fa9..1f67bbb62 100644
--- a/array/without.js
+++ b/without.js
@@ -1,6 +1,6 @@
-import baseDifference from '../internal/baseDifference';
-import isArrayLike from '../internal/isArrayLike';
-import restParam from '../function/restParam';
+import baseDifference from './internal/baseDifference';
+import isArrayLikeObject from './isArrayLikeObject';
+import rest from './rest';
/**
* Creates an array excluding all provided values using
@@ -18,8 +18,8 @@ import restParam from '../function/restParam';
* _.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..f7e6ad6c7
--- /dev/null
+++ b/words.js
@@ -0,0 +1,80 @@
+import toString from './toString';
+
+/** 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) || [];
+}
+
+export default words;
diff --git a/function/wrap.js b/wrap.js
similarity index 75%
rename from function/wrap.js
rename to wrap.js
index 92a1b6237..317ba6cbb 100644
--- a/function/wrap.js
+++ b/wrap.js
@@ -1,8 +1,5 @@
-import createWrapper from '../internal/createWrapper';
-import identity from '../utility/identity';
-
-/** Used to compose bitmasks for wrapper metadata. */
-var PARTIAL_FLAG = 32;
+import identity from './identity';
+import partial from './partial';
/**
* Creates a function that provides `value` to the wrapper function as its
@@ -27,7 +24,7 @@ var PARTIAL_FLAG = 32;
*/
function wrap(value, wrapper) {
wrapper = wrapper == null ? identity : wrapper;
- return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);
+ return partial(wrapper, value);
}
export default wrap;
diff --git a/wrapperAt.js b/wrapperAt.js
new file mode 100644
index 000000000..c86f84f8d
--- /dev/null
+++ b/wrapperAt.js
@@ -0,0 +1,48 @@
+import LazyWrapper from './internal/LazyWrapper';
+import LodashWrapper from './internal/LodashWrapper';
+import baseAt from './internal/baseAt';
+import baseFlatten from './internal/baseFlatten';
+import isIndex from './internal/isIndex';
+import rest from './rest';
+import thru from './thru';
+
+/**
+ * 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;
+ });
+});
+
+export default wrapperAt;
diff --git a/chain/wrapperChain.js b/wrapperChain.js
similarity index 88%
rename from chain/wrapperChain.js
rename to wrapperChain.js
index 41568a312..ff5bf8cfb 100644
--- a/chain/wrapperChain.js
+++ b/wrapperChain.js
@@ -5,7 +5,7 @@ import chain from './chain';
*
* @name chain
* @memberOf _
- * @category Chain
+ * @category Seq
* @returns {Object} Returns the new `lodash` wrapper instance.
* @example
*
@@ -15,12 +15,13 @@ import chain from './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..0dd9eaa8d
--- /dev/null
+++ b/wrapperFlatMap.js
@@ -0,0 +1,22 @@
+/**
+ * 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();
+}
+
+export default wrapperFlatMap;
diff --git a/wrapperLodash.js b/wrapperLodash.js
new file mode 100644
index 000000000..90b91678e
--- /dev/null
+++ b/wrapperLodash.js
@@ -0,0 +1,139 @@
+import LazyWrapper from './internal/LazyWrapper';
+import LodashWrapper from './internal/LodashWrapper';
+import baseLodash from './internal/baseLodash';
+import isArray from './isArray';
+import isObjectLike from './isObjectLike';
+import wrapperClone from './internal/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;
+
+export default lodash;
diff --git a/chain/wrapperReverse.js b/wrapperReverse.js
similarity index 52%
rename from chain/wrapperReverse.js
rename to wrapperReverse.js
index 124965afb..6915c6e39 100644
--- a/chain/wrapperReverse.js
+++ b/wrapperReverse.js
@@ -1,17 +1,17 @@
-import LazyWrapper from '../internal/LazyWrapper';
-import LodashWrapper from '../internal/LodashWrapper';
+import LazyWrapper from './internal/LazyWrapper';
+import LodashWrapper from './internal/LodashWrapper';
+import reverse from './reverse';
import thru from './thru';
/**
- * 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];
@@ -24,20 +24,16 @@ import thru from './thru';
*/
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);
}
export default wrapperReverse;
diff --git a/chain/wrapperValue.js b/wrapperValue.js
similarity index 82%
rename from chain/wrapperValue.js
rename to wrapperValue.js
index 59662bb79..47102c789 100644
--- a/chain/wrapperValue.js
+++ b/wrapperValue.js
@@ -1,4 +1,4 @@
-import baseWrapperValue from '../internal/baseWrapperValue';
+import baseWrapperValue from './internal/baseWrapperValue';
/**
* Executes the chained sequence to extract the unwrapped value.
@@ -6,7 +6,7 @@ import baseWrapperValue from '../internal/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..82672e7c5
--- /dev/null
+++ b/xor.js
@@ -0,0 +1,24 @@
+import arrayFilter from './internal/arrayFilter';
+import baseXor from './internal/baseXor';
+import isArrayLikeObject from './isArrayLikeObject';
+import rest from './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));
+});
+
+export default xor;
diff --git a/xorBy.js b/xorBy.js
new file mode 100644
index 000000000..d0667208f
--- /dev/null
+++ b/xorBy.js
@@ -0,0 +1,36 @@
+import arrayFilter from './internal/arrayFilter';
+import baseIteratee from './internal/baseIteratee';
+import baseXor from './internal/baseXor';
+import isArrayLikeObject from './isArrayLikeObject';
+import last from './last';
+import rest from './rest';
+
+/**
+ * This method is like `_.xor` except that it accepts `iteratee` which is
+ * invoked for each element of each `arrays` to generate the criterion by which
+ * uniqueness is computed. The iteratee is invoked with one argument: (value).
+ *
+ * @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));
+});
+
+export default xorBy;
diff --git a/xorWith.js b/xorWith.js
new file mode 100644
index 000000000..ea66c8fb0
--- /dev/null
+++ b/xorWith.js
@@ -0,0 +1,34 @@
+import arrayFilter from './internal/arrayFilter';
+import baseXor from './internal/baseXor';
+import isArrayLikeObject from './isArrayLikeObject';
+import last from './last';
+import rest from './rest';
+
+/**
+ * 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);
+});
+
+export default xorWith;
diff --git a/array/zip.js b/zip.js
similarity index 87%
rename from array/zip.js
rename to zip.js
index 6a54d801d..90ee40fca 100644
--- a/array/zip.js
+++ b/zip.js
@@ -1,4 +1,4 @@
-import restParam from '../function/restParam';
+import rest from './rest';
import unzip from './unzip';
/**
@@ -16,6 +16,6 @@ import unzip from './unzip';
* _.zip(['fred', 'barney'], [30, 40], [true, false]);
* // => [['fred', 30, true], ['barney', 40, false]]
*/
-var zip = restParam(unzip);
+var zip = rest(unzip);
export default zip;
diff --git a/zipObject.js b/zipObject.js
new file mode 100644
index 000000000..98dc1d7c7
--- /dev/null
+++ b/zipObject.js
@@ -0,0 +1,30 @@
+import baseSet from './internal/baseSet';
+
+/**
+ * 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;
+}
+
+export default zipObject;
diff --git a/zipWith.js b/zipWith.js
new file mode 100644
index 000000000..36eda1a9e
--- /dev/null
+++ b/zipWith.js
@@ -0,0 +1,30 @@
+import rest from './rest';
+import unzipWith from './unzipWith';
+
+/**
+ * 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);
+});
+
+export default zipWith;