diff --git a/README.md b/README.md index 74c3bc5ef..839029008 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash-es v3.1.0 +# lodash-es v3.2.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. @@ -7,4 +7,4 @@ Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli): $ lodash modularize modern exports=es -o ./ ``` -See the [package source](https://github.com/lodash/lodash/tree/3.1.0-es) for more details. +See the [package source](https://github.com/lodash/lodash/tree/3.2.0-es) for more details. diff --git a/array.js b/array.js index 0f83e0c74..93303c6d2 100644 --- a/array.js +++ b/array.js @@ -5,6 +5,7 @@ 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'; @@ -46,6 +47,7 @@ export default { 'dropRight': dropRight, 'dropRightWhile': dropRightWhile, 'dropWhile': dropWhile, + 'fill': fill, 'findIndex': findIndex, 'findLastIndex': findLastIndex, 'first': first, diff --git a/array/chunk.js b/array/chunk.js index b402309b0..0f46f5d4b 100644 --- a/array/chunk.js +++ b/array/chunk.js @@ -16,7 +16,7 @@ var nativeMax = Math.max; * @memberOf _ * @category Array * @param {Array} array The array to process. - * @param {numer} [size=1] The length of each chunk. + * @param {number} [size=1] The length of each chunk. * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. * @returns {Array} Returns the new array containing chunks. * @example diff --git a/array/drop.js b/array/drop.js index a90f8bb3f..bbb1cc162 100644 --- a/array/drop.js +++ b/array/drop.js @@ -6,7 +6,6 @@ import isIterateeCall from '../internal/isIterateeCall'; * * @static * @memberOf _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. diff --git a/array/dropRight.js b/array/dropRight.js index c22bec923..96dfebb1f 100644 --- a/array/dropRight.js +++ b/array/dropRight.js @@ -6,7 +6,6 @@ import isIterateeCall from '../internal/isIterateeCall'; * * @static * @memberOf _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. diff --git a/array/dropRightWhile.js b/array/dropRightWhile.js index 3e9c8883c..59edba191 100644 --- a/array/dropRightWhile.js +++ b/array/dropRightWhile.js @@ -6,20 +6,23 @@ import baseSlice from '../internal/baseSlice'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given + * 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 _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per element. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the slice of `array`. * @example @@ -28,18 +31,22 @@ import baseSlice from '../internal/baseSlice'; * // => [1] * * var users = [ - * { 'user': 'barney', 'status': 'busy', 'active': false }, - * { 'user': 'fred', 'status': 'busy', 'active': true }, - * { 'user': 'pebbles', 'status': 'away', 'active': true } + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } * ]; * - * // using the "_.property" callback shorthand - * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // 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 "_.matches" callback shorthand - * _.pluck(_.dropRightWhile(users, { 'status': 'away' }), 'user'); - * // => ['barney', 'fred'] + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] */ function dropRightWhile(array, predicate, thisArg) { var length = array ? array.length : 0; diff --git a/array/dropWhile.js b/array/dropWhile.js index 62a888f83..2084211ab 100644 --- a/array/dropWhile.js +++ b/array/dropWhile.js @@ -6,20 +6,23 @@ import baseSlice from '../internal/baseSlice'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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 _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per element. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the slice of `array`. * @example @@ -28,18 +31,22 @@ import baseSlice from '../internal/baseSlice'; * // => [3] * * var users = [ - * { 'user': 'barney', 'status': 'busy', 'active': true }, - * { 'user': 'fred', 'status': 'busy', 'active': false }, - * { 'user': 'pebbles', 'status': 'away', 'active': true } + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } * ]; * - * // using the "_.property" callback shorthand - * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); * // => ['fred', 'pebbles'] * - * // using the "_.matches" callback shorthand - * _.pluck(_.dropWhile(users, { 'status': 'busy' }), 'user'); + * // 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) { var length = array ? array.length : 0; diff --git a/array/fill.js b/array/fill.js new file mode 100644 index 000000000..3a3e3772f --- /dev/null +++ b/array/fill.js @@ -0,0 +1,31 @@ +import baseFill from '../internal/baseFill'; +import isIterateeCall from '../internal/isIterateeCall'; + +/** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ +function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); +} + +export default fill; diff --git a/array/findIndex.js b/array/findIndex.js index 1c94a3efd..0a29e007c 100644 --- a/array/findIndex.js +++ b/array/findIndex.js @@ -4,10 +4,14 @@ import baseCallback from '../internal/baseCallback'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -16,28 +20,31 @@ import baseCallback from '../internal/baseCallback'; * @category Array * @param {Array} array The array to search. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * 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', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } * ]; * - * _.findIndex(users, function(chr) { return chr.age < 40; }); + * _.findIndex(users, function(chr) { return chr.user == 'barney'; }); * // => 0 * - * // using the "_.matches" callback shorthand - * _.findIndex(users, { 'age': 1 }); - * // => 2 - * - * // using the "_.property" callback shorthand - * _.findIndex(users, 'active'); + * // 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 */ function findIndex(array, predicate, thisArg) { var index = -1, diff --git a/array/findLastIndex.js b/array/findLastIndex.js index 4adbf204f..d347ddb38 100644 --- a/array/findLastIndex.js +++ b/array/findLastIndex.js @@ -4,10 +4,14 @@ import baseCallback from '../internal/baseCallback'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -16,26 +20,29 @@ import baseCallback from '../internal/baseCallback'; * @category Array * @param {Array} array The array to search. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * 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', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': false } + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } * ]; * - * _.findLastIndex(users, function(chr) { return chr.age < 40; }); + * _.findLastIndex(users, function(chr) { return chr.user == 'pebbles'; }); * // => 2 * - * // using the "_.matches" callback shorthand - * _.findLastIndex(users, { 'age': 40 }); + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); * // => 1 * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.findLastIndex(users, 'active'); * // => 0 */ diff --git a/array/remove.js b/array/remove.js index 88830628b..2af31b45d 100644 --- a/array/remove.js +++ b/array/remove.js @@ -11,10 +11,14 @@ var splice = arrayProto.splice; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -25,8 +29,7 @@ var splice = arrayProto.splice; * @category Array * @param {Array} array The array to modify. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the new array of removed elements. * @example diff --git a/array/sortedIndex.js b/array/sortedIndex.js index b1e4995a8..c4fd74ca1 100644 --- a/array/sortedIndex.js +++ b/array/sortedIndex.js @@ -9,10 +9,14 @@ import binaryIndexBy from '../internal/binaryIndexBy'; * to compute their sort ranking. The iteratee is bound to `thisArg` and * invoked with one argument; (value). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -22,8 +26,7 @@ import binaryIndexBy from '../internal/binaryIndexBy'; * @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. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {number} Returns the index at which `value` should be inserted * into `array`. @@ -43,7 +46,7 @@ import binaryIndexBy from '../internal/binaryIndexBy'; * }, dict); * // => 1 * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); * // => 1 */ diff --git a/array/sortedLastIndex.js b/array/sortedLastIndex.js index 4a623d46d..7eb354834 100644 --- a/array/sortedLastIndex.js +++ b/array/sortedLastIndex.js @@ -13,8 +13,7 @@ import binaryIndexBy from '../internal/binaryIndexBy'; * @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. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {number} Returns the index at which `value` should be inserted * into `array`. diff --git a/array/take.js b/array/take.js index cbe87f849..6f50b8be4 100644 --- a/array/take.js +++ b/array/take.js @@ -6,7 +6,6 @@ import isIterateeCall from '../internal/isIterateeCall'; * * @static * @memberOf _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. diff --git a/array/takeRight.js b/array/takeRight.js index 25eeff60e..2a7a40f51 100644 --- a/array/takeRight.js +++ b/array/takeRight.js @@ -6,7 +6,6 @@ import isIterateeCall from '../internal/isIterateeCall'; * * @static * @memberOf _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. diff --git a/array/takeRightWhile.js b/array/takeRightWhile.js index fd131e92f..29586033d 100644 --- a/array/takeRightWhile.js +++ b/array/takeRightWhile.js @@ -6,20 +6,23 @@ import baseSlice from '../internal/baseSlice'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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 _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per element. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the slice of `array`. * @example @@ -28,18 +31,22 @@ import baseSlice from '../internal/baseSlice'; * // => [2, 3] * * var users = [ - * { 'user': 'barney', 'status': 'busy', 'active': false }, - * { 'user': 'fred', 'status': 'busy', 'active': true }, - * { 'user': 'pebbles', 'status': 'away', 'active': true } + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } * ]; * - * // using the "_.property" callback shorthand - * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // 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 "_.matches" callback shorthand - * _.pluck(_.takeRightWhile(users, { 'status': 'away' }), 'user'); - * // => ['pebbles'] + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] */ function takeRightWhile(array, predicate, thisArg) { var length = array ? array.length : 0; diff --git a/array/takeWhile.js b/array/takeWhile.js index c78743040..1ece4acac 100644 --- a/array/takeWhile.js +++ b/array/takeWhile.js @@ -6,20 +6,23 @@ import baseSlice from '../internal/baseSlice'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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 _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per element. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the slice of `array`. * @example @@ -28,18 +31,22 @@ import baseSlice from '../internal/baseSlice'; * // => [1, 2] * * var users = [ - * { 'user': 'barney', 'status': 'busy', 'active': true }, - * { 'user': 'fred', 'status': 'busy', 'active': false }, - * { 'user': 'pebbles', 'status': 'away', 'active': true } + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } * ]; * - * // using the "_.property" callback shorthand - * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); * // => ['barney'] * - * // using the "_.matches" callback shorthand - * _.pluck(_.takeWhile(users, { 'status': 'busy' }), 'user'); + * // 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) { var length = array ? array.length : 0; diff --git a/array/uniq.js b/array/uniq.js index 1e53b2fd1..bea628402 100644 --- a/array/uniq.js +++ b/array/uniq.js @@ -11,10 +11,14 @@ import sortedUniq from '../internal/sortedUniq'; * uniqueness is computed. The `iteratee` is bound to `thisArg` and invoked * with three arguments; (value, index, array). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -30,8 +34,6 @@ import sortedUniq from '../internal/sortedUniq'; * @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. - * If a property name or object is provided it is used to create a "_.property" - * or "_.matches" style callback respectively. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Array} Returns the new duplicate-value-free array. * @example @@ -47,7 +49,7 @@ import sortedUniq from '../internal/sortedUniq'; * _.uniq([1, 2.5, 1.5, 2], function(n) { return this.floor(n); }, Math); * // => [1, 2.5] * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ diff --git a/chain.js b/chain.js index 1480ba20d..b8e00af08 100644 --- a/chain.js +++ b/chain.js @@ -1,6 +1,9 @@ import chain from './chain/chain'; +import commit from './chain/commit'; 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'; @@ -11,8 +14,11 @@ import wrapperChain from './chain/wrapperChain'; export default { 'chain': chain, + 'commit': commit, 'lodash': lodash, + 'plant': plant, 'reverse': reverse, + 'run': run, 'tap': tap, 'thru': thru, 'toJSON': toJSON, diff --git a/chain/chain.js b/chain/chain.js index dde9cb2d1..d16e9523b 100644 --- a/chain/chain.js +++ b/chain/chain.js @@ -8,7 +8,7 @@ import lodash from './lodash'; * @memberOf _ * @category Chain * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` object. + * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var users = [ diff --git a/chain/commit.js b/chain/commit.js new file mode 100644 index 000000000..3a1110c5a --- /dev/null +++ b/chain/commit.js @@ -0,0 +1,2 @@ +import wrapperCommit from './wrapperCommit' +export default wrapperCommit; diff --git a/chain/lodash.js b/chain/lodash.js index 8c8c258c1..4f6b2e21b 100644 --- a/chain/lodash.js +++ b/chain/lodash.js @@ -1,7 +1,8 @@ +import LazyWrapper from '../internal/LazyWrapper'; import LodashWrapper from '../internal/LodashWrapper'; -import arrayCopy from '../internal/arrayCopy'; import isArray from '../lang/isArray'; import isObjectLike from '../internal/isObjectLike'; +import wrapperClone from '../internal/wrapperClone'; /** Used for native method references. */ var objectProto = Object.prototype; @@ -10,7 +11,7 @@ var objectProto = Object.prototype; var hasOwnProperty = objectProto.hasOwnProperty; /** - * Creates a `lodash` object which wraps `value` to enable intuitive chaining. + * Creates a `lodash` object which wraps `value` to enable implicit chaining. * Methods that operate on and return arrays, collections, and functions can * be chained together. Methods that return a boolean or single value will * automatically end the chain returning the unwrapped value. Explicit chaining @@ -29,29 +30,31 @@ var hasOwnProperty = objectProto.hasOwnProperty; * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, * and `unshift` * - * The wrapper functions that support shortcut fusion are: - * `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `first`, - * `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, `slice`, - * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `where` + * 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 functions are: + * The chainable wrapper methods are: * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, - * `callback`, `chain`, `chunk`, `compact`, `concat`, `constant`, `countBy`, - * `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, `difference`, - * `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `flatten`, - * `flattenDeep`, `flow`, `flowRight`, `forEach`, `forEachRight`, `forIn`, - * `forInRight`, `forOwn`, `forOwnRight`, `functions`, `groupBy`, `indexBy`, - * `initial`, `intersection`, `invert`, `invoke`, `keys`, `keysIn`, `map`, - * `mapValues`, `matches`, `memoize`, `merge`, `mixin`, `negate`, `noop`, - * `omit`, `once`, `pairs`, `partial`, `partialRight`, `partition`, `pick`, - * `pluck`, `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, - * `rearg`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `sortByAll`, `splice`, `take`, `takeRight`, `takeRightWhile`, - * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, - * `transform`, `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, - * `where`, `without`, `wrap`, `xor`, `zip`, and `zipObject` + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, + * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, + * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, + * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, + * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, + * `keysIn`, `map`, `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, + * `mixin`, `negate`, `noop`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `reverse`, + * `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, `splice`, `spread`, + * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, + * `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`, + * `unshift`, `unzip`, `values`, `valuesIn`, `where`, `without`, `wrap`, `xor`, + * `zip`, and `zipObject` * - * The wrapper functions that are **not** chainable by default are: + * The wrapper methods that are **not** chainable by default are: * `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, @@ -66,14 +69,14 @@ var hasOwnProperty = objectProto.hasOwnProperty; * `startCase`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, * `trunc`, `unescape`, `uniqueId`, `value`, and `words` * - * The wrapper function `sample` will return a wrapped value when `n` is provided, + * 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 a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var wrapped = _([1, 2, 3]); @@ -92,18 +95,15 @@ var hasOwnProperty = objectProto.hasOwnProperty; * // => true */ function lodash(value) { - if (isObjectLike(value) && !isArray(value)) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { if (value instanceof LodashWrapper) { return value; } - if (hasOwnProperty.call(value, '__wrapped__')) { - return new LodashWrapper(value.__wrapped__, value.__chain__, arrayCopy(value.__actions__)); + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); } } return new LodashWrapper(value); } -// Ensure `new LodashWrapper` is an instance of `lodash`. -LodashWrapper.prototype = lodash.prototype; - export default lodash; diff --git a/chain/plant.js b/chain/plant.js new file mode 100644 index 000000000..6ccd45ee5 --- /dev/null +++ b/chain/plant.js @@ -0,0 +1,2 @@ +import wrapperPlant from './wrapperPlant' +export default wrapperPlant; diff --git a/chain/run.js b/chain/run.js new file mode 100644 index 000000000..59ae6ce2a --- /dev/null +++ b/chain/run.js @@ -0,0 +1,2 @@ +import wrapperValue from './wrapperValue' +export default wrapperValue; diff --git a/chain/wrapperChain.js b/chain/wrapperChain.js index 819873b17..41568a312 100644 --- a/chain/wrapperChain.js +++ b/chain/wrapperChain.js @@ -6,7 +6,7 @@ import chain from './chain'; * @name chain * @memberOf _ * @category Chain - * @returns {*} Returns the `lodash` object. + * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var users = [ diff --git a/chain/wrapperCommit.js b/chain/wrapperCommit.js new file mode 100644 index 000000000..0ce1dd59f --- /dev/null +++ b/chain/wrapperCommit.js @@ -0,0 +1,32 @@ +import LodashWrapper from '../internal/LodashWrapper'; + +/** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapper = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapper = wrapper.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapper.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ +function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); +} + +export default wrapperCommit; diff --git a/chain/wrapperPlant.js b/chain/wrapperPlant.js new file mode 100644 index 000000000..f404e2d01 --- /dev/null +++ b/chain/wrapperPlant.js @@ -0,0 +1,45 @@ +import LodashWrapper from '../internal/LodashWrapper'; +import wrapperClone from '../internal/wrapperClone'; + +/** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapper = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapper = wrapper.plant(other); + * + * otherWrapper.value(); + * // => [9, 16] + * + * wrapper.value(); + * // => [1, 4] + */ +function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof LodashWrapper) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; +} + +export default wrapperPlant; diff --git a/chain/wrapperReverse.js b/chain/wrapperReverse.js index 21cbfe02d..a7e2063df 100644 --- a/chain/wrapperReverse.js +++ b/chain/wrapperReverse.js @@ -11,7 +11,7 @@ import thru from './thru'; * @name reverse * @memberOf _ * @category Chain - * @returns {Object} Returns the new reversed `lodash` object. + * @returns {Object} Returns the new reversed `lodash` wrapper instance. * @example * * var array = [1, 2, 3]; @@ -28,7 +28,7 @@ function wrapperReverse() { if (this.__actions__.length) { value = new LazyWrapper(this); } - return new LodashWrapper(value.reverse()); + return new LodashWrapper(value.reverse(), this.__chain__); } return this.thru(function(value) { return value.reverse(); diff --git a/chain/wrapperValue.js b/chain/wrapperValue.js index eeeb58ac5..59662bb79 100644 --- a/chain/wrapperValue.js +++ b/chain/wrapperValue.js @@ -5,7 +5,7 @@ import baseWrapperValue from '../internal/baseWrapperValue'; * * @name value * @memberOf _ - * @alias toJSON, valueOf + * @alias run, toJSON, valueOf * @category Chain * @returns {*} Returns the resolved unwrapped value. * @example diff --git a/collection/countBy.js b/collection/countBy.js index 0181a1327..b7fd01173 100644 --- a/collection/countBy.js +++ b/collection/countBy.js @@ -13,10 +13,14 @@ var hasOwnProperty = objectProto.hasOwnProperty; * The `iteratee` is bound to `thisArg` and invoked with three arguments; * (value, index|key, collection). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -25,8 +29,7 @@ var hasOwnProperty = objectProto.hasOwnProperty; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Object} Returns the composed aggregate object. * @example diff --git a/collection/every.js b/collection/every.js index 75f57cf89..0ee1d9a7a 100644 --- a/collection/every.js +++ b/collection/every.js @@ -8,10 +8,14 @@ import isArray from '../lang/isArray'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -21,27 +25,30 @@ import isArray from '../lang/isArray'; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * 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']); + * _.every([true, 1, null, 'yes'], Boolean); * // => false * * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } * ]; * - * // using the "_.property" callback shorthand - * _.every(users, 'age'); + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); * // => true * - * // using the "_.matches" callback shorthand - * _.every(users, { 'age': 36 }); + * // using the `_.property` callback shorthand + * _.every(users, 'active'); * // => false */ function every(collection, predicate, thisArg) { diff --git a/collection/filter.js b/collection/filter.js index 660fddfbb..8a485ad14 100644 --- a/collection/filter.js +++ b/collection/filter.js @@ -8,10 +8,14 @@ import isArray from '../lang/isArray'; * `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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -21,8 +25,7 @@ import isArray from '../lang/isArray'; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the new filtered array. * @example @@ -31,16 +34,20 @@ import isArray from '../lang/isArray'; * // => [2, 4] * * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } * ]; * - * // using the "_.property" callback shorthand - * _.pluck(_.filter(users, 'active'), 'user'); + * // 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 "_.matches" callback shorthand - * _.pluck(_.filter(users, { 'age': 36 }), 'user'); + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); * // => ['barney'] */ function filter(collection, predicate, thisArg) { diff --git a/collection/find.js b/collection/find.js index 73b289f02..6f14c749b 100644 --- a/collection/find.js +++ b/collection/find.js @@ -9,10 +9,14 @@ import isArray from '../lang/isArray'; * `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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -22,28 +26,31 @@ import isArray from '../lang/isArray'; * @category Collection * @param {Array|Object|string} collection The collection to search. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {*} Returns the matched element, else `undefined`. * @example * * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } + * { '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 }), 'user'); + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); * // => 'pebbles' * - * // using the "_.property" callback shorthand - * _.result(_.find(users, 'active'), 'user'); + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' */ function find(collection, predicate, thisArg) { if (isArray(collection)) { diff --git a/collection/findLast.js b/collection/findLast.js index 58ba6f508..3c186d463 100644 --- a/collection/findLast.js +++ b/collection/findLast.js @@ -11,8 +11,7 @@ import baseFind from '../internal/baseFind'; * @category Collection * @param {Array|Object|string} collection The collection to search. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {*} Returns the matched element, else `undefined`. * @example diff --git a/collection/findWhere.js b/collection/findWhere.js index bcc0fb0e6..ac4b6bde9 100644 --- a/collection/findWhere.js +++ b/collection/findWhere.js @@ -6,6 +6,11 @@ import find from './find'; * 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 @@ -15,14 +20,14 @@ import find from './find'; * @example * * var users = [ - * { 'user': 'barney', 'age': 36, 'status': 'busy' }, - * { 'user': 'fred', 'age': 40, 'status': 'busy' } + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } * ]; * - * _.result(_.findWhere(users, { 'status': 'busy' }), 'user'); + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); * // => 'barney' * - * _.result(_.findWhere(users, { 'age': 40 }), 'user'); + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); * // => 'fred' */ function findWhere(collection, source) { diff --git a/collection/groupBy.js b/collection/groupBy.js index ac7ff3836..004f64f42 100644 --- a/collection/groupBy.js +++ b/collection/groupBy.js @@ -13,10 +13,14 @@ var hasOwnProperty = objectProto.hasOwnProperty; * The `iteratee` is bound to `thisArg` and invoked with three arguments; * (value, index|key, collection). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -25,8 +29,7 @@ var hasOwnProperty = objectProto.hasOwnProperty; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Object} Returns the composed aggregate object. * @example @@ -37,7 +40,7 @@ var hasOwnProperty = objectProto.hasOwnProperty; * _.groupBy([4.2, 6.1, 6.4], function(n) { return this.floor(n); }, Math); * // => { '4': [4.2], '6': [6.1, 6.4] } * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ diff --git a/collection/indexBy.js b/collection/indexBy.js index fbf9b2386..960f38261 100644 --- a/collection/indexBy.js +++ b/collection/indexBy.js @@ -7,10 +7,14 @@ import createAggregator from '../internal/createAggregator'; * iteratee function is bound to `thisArg` and invoked with three arguments; * (value, index|key, collection). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -19,8 +23,7 @@ import createAggregator from '../internal/createAggregator'; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Object} Returns the composed aggregate object. * @example diff --git a/collection/map.js b/collection/map.js index 28bd14342..de73e94ac 100644 --- a/collection/map.js +++ b/collection/map.js @@ -8,21 +8,34 @@ import isArray from '../lang/isArray'; * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three * arguments; (value, index|key, collection). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * + * Many lodash methods are guarded to work as interatees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, `drop`, + * `dropRight`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`, `slice`, + * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`, `trimRight`, + * `trunc`, `random`, `range`, `sample`, `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. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. + * create a `_.property` or `_.matches` style callback respectively. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Array} Returns the new mapped array. * @example @@ -38,7 +51,7 @@ import isArray from '../lang/isArray'; * { 'user': 'fred' } * ]; * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.map(users, 'user'); * // => ['barney', 'fred'] */ diff --git a/collection/max.js b/collection/max.js index 56d9f865b..b73d9db98 100644 --- a/collection/max.js +++ b/collection/max.js @@ -8,10 +8,14 @@ import createExtremum from '../internal/createExtremum'; * is ranked. The `iteratee` is bound to `thisArg` and invoked with three * arguments; (value, index, collection). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -20,8 +24,6 @@ import createExtremum from '../internal/createExtremum'; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * If a property name or object is provided it is used to create a "_.property" - * or "_.matches" style callback respectively. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {*} Returns the maximum value. * @example @@ -40,7 +42,7 @@ import createExtremum from '../internal/createExtremum'; * _.max(users, function(chr) { return chr.age; }); * // => { 'user': 'fred', 'age': 40 }; * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.max(users, 'age'); * // => { 'user': 'fred', 'age': 40 }; */ diff --git a/collection/min.js b/collection/min.js index 70e43a3a8..e7c04bafe 100644 --- a/collection/min.js +++ b/collection/min.js @@ -8,10 +8,14 @@ import createExtremum from '../internal/createExtremum'; * is ranked. The `iteratee` is bound to `thisArg` and invoked with three * arguments; (value, index, collection). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -20,8 +24,6 @@ import createExtremum from '../internal/createExtremum'; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * If a property name or object is provided it is used to create a "_.property" - * or "_.matches" style callback respectively. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {*} Returns the minimum value. * @example @@ -40,7 +42,7 @@ import createExtremum from '../internal/createExtremum'; * _.min(users, function(chr) { return chr.age; }); * // => { 'user': 'barney', 'age': 36 }; * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.min(users, 'age'); * // => { 'user': 'barney', 'age': 36 }; */ diff --git a/collection/partition.js b/collection/partition.js index 21517417f..78d6bc944 100644 --- a/collection/partition.js +++ b/collection/partition.js @@ -6,10 +6,14 @@ import createAggregator from '../internal/createAggregator'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -18,8 +22,7 @@ import createAggregator from '../internal/createAggregator'; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the array of grouped elements. * @example @@ -36,12 +39,18 @@ import createAggregator from '../internal/createAggregator'; * { 'user': 'pebbles', 'age': 1, 'active': false } * ]; * - * // using the "_.matches" callback shorthand - * _.map(_.partition(users, { 'age': 1 }), function(array) { return _.pluck(array, 'user'); }); + * 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 "_.property" callback shorthand - * _.map(_.partition(users, 'active'), function(array) { return _.pluck(array, 'user'); }); + * // 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) { diff --git a/collection/pluck.js b/collection/pluck.js index e59665340..805b96352 100644 --- a/collection/pluck.js +++ b/collection/pluck.js @@ -25,7 +25,7 @@ import map from './map'; * // => [36, 40] (iteration order is not guaranteed) */ function pluck(collection, key) { - return map(collection, baseProperty(key + '')); + return map(collection, baseProperty(key)); } export default pluck; diff --git a/collection/reduce.js b/collection/reduce.js index c19dce38a..29719a57d 100644 --- a/collection/reduce.js +++ b/collection/reduce.js @@ -12,6 +12,12 @@ import isArray from '../lang/isArray'; * 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 interatees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `merge`, and `sortAllBy` + * * @static * @memberOf _ * @alias foldl, inject diff --git a/collection/reject.js b/collection/reject.js index 801e46d5d..9a5f15002 100644 --- a/collection/reject.js +++ b/collection/reject.js @@ -7,10 +7,14 @@ import isArray from '../lang/isArray'; * The opposite of `_.filter`; this method returns the elements of `collection` * that `predicate` does **not** return truthy for. * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -19,8 +23,7 @@ import isArray from '../lang/isArray'; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the new filtered array. * @example @@ -33,13 +36,17 @@ import isArray from '../lang/isArray'; * { 'user': 'fred', 'age': 40, 'active': true } * ]; * - * // using the "_.property" callback shorthand - * _.pluck(_.reject(users, 'active'), 'user'); + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); * // => ['barney'] * - * // using the "_.matches" callback shorthand - * _.pluck(_.reject(users, { 'age': 36 }), 'user'); + * // 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; diff --git a/collection/some.js b/collection/some.js index c3d1a4305..fdf7f5140 100644 --- a/collection/some.js +++ b/collection/some.js @@ -9,10 +9,14 @@ import isArray from '../lang/isArray'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -22,8 +26,7 @@ import isArray from '../lang/isArray'; * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. @@ -33,17 +36,21 @@ import isArray from '../lang/isArray'; * // => true * * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } * ]; * - * // using the "_.property" callback shorthand - * _.some(users, 'active'); + * // using the `_.matches` callback shorthand + * _.some(users, { user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); * // => true * - * // using the "_.matches" callback shorthand - * _.some(users, { 'age': 1 }); - * // => false + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true */ function some(collection, predicate, thisArg) { var func = isArray(collection) ? arraySome : baseSome; diff --git a/collection/sortBy.js b/collection/sortBy.js index f9b762bf5..53e9a5e31 100644 --- a/collection/sortBy.js +++ b/collection/sortBy.js @@ -12,10 +12,14 @@ import isLength from '../internal/isLength'; * The `iteratee` is bound to `thisArg` and invoked with three arguments; * (value, index|key, collection). * - * If a property name is provided for `predicate` the created "_.property" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -25,7 +29,7 @@ import isLength from '../internal/isLength'; * @param {Array|Object|string} collection The collection to iterate over. * @param {Array|Function|Object|string} [iteratee=_.identity] The function * invoked per iteration. If a property name or an object is provided it is - * used to create a "_.property" or "_.matches" style callback respectively. + * used to create a `_.property` or `_.matches` style callback respectively. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Array} Returns the new sorted array. * @example @@ -42,7 +46,7 @@ import isLength from '../internal/isLength'; * { 'user': 'barney' } * ]; * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.pluck(_.sortBy(users, 'user'), 'user'); * // => ['barney', 'fred', 'pebbles'] */ diff --git a/collection/sortByAll.js b/collection/sortByAll.js index e7ea4712a..51d2be63f 100644 --- a/collection/sortByAll.js +++ b/collection/sortByAll.js @@ -38,7 +38,7 @@ function sortByAll(collection) { props = baseFlatten(args, false, false, 1), result = isLength(length) ? Array(length) : []; - baseEach(collection, function(value, key, collection) { + baseEach(collection, function(value) { var length = props.length, criteria = Array(length); diff --git a/collection/where.js b/collection/where.js index 4f5352290..f0dc1a3d9 100644 --- a/collection/where.js +++ b/collection/where.js @@ -6,6 +6,11 @@ import filter from './filter'; * 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 @@ -15,18 +20,15 @@ import filter from './filter'; * @example * * var users = [ - * { 'user': 'barney', 'age': 36, 'status': 'busy', 'pets': ['hoppy'] }, - * { 'user': 'fred', 'age': 40, 'status': 'busy', 'pets': ['baby puss', 'dino'] } + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } * ]; * - * _.pluck(_.where(users, { 'age': 36 }), 'user'); + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); * // => ['barney'] * * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); * // => ['fred'] - * - * _.pluck(_.where(users, { 'status': 'busy' }), 'user'); - * // => ['barney', 'fred'] */ function where(collection, source) { return filter(collection, baseMatches(source)); diff --git a/function.js b/function.js index 121b2b105..389ed5fd5 100644 --- a/function.js +++ b/function.js @@ -19,6 +19,7 @@ import once from './function/once'; import partial from './function/partial'; import partialRight from './function/partialRight'; import rearg from './function/rearg'; +import spread from './function/spread'; import throttle from './function/throttle'; import wrap from './function/wrap'; @@ -44,6 +45,7 @@ export default { 'partial': partial, 'partialRight': partialRight, 'rearg': rearg, + 'spread': spread, 'throttle': throttle, 'wrap': wrap }; diff --git a/function/after.js b/function/after.js index 590c4ffa0..487f26837 100644 --- a/function/after.js +++ b/function/after.js @@ -1,4 +1,3 @@ -import isFunction from '../lang/isFunction'; import root from '../internal/root'; /** Used as the `TypeError` message for "Functions" methods. */ @@ -31,8 +30,8 @@ var nativeIsFinite = root.isFinite; * // => logs 'done saving!' after the two async saves have completed */ function after(n, func) { - if (!isFunction(func)) { - if (isFunction(n)) { + if (typeof func != 'function') { + if (typeof n == 'function') { var temp = n; n = func; func = temp; diff --git a/function/before.js b/function/before.js index 8ddaae6d6..40af146e7 100644 --- a/function/before.js +++ b/function/before.js @@ -1,5 +1,3 @@ -import isFunction from '../lang/isFunction'; - /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; @@ -21,8 +19,8 @@ var FUNC_ERROR_TEXT = 'Expected a function'; */ function before(n, func) { var result; - if (!isFunction(func)) { - if (isFunction(n)) { + if (typeof func != 'function') { + if (typeof n == 'function') { var temp = n; n = func; func = temp; diff --git a/function/debounce.js b/function/debounce.js index c54cdd784..59e331885 100644 --- a/function/debounce.js +++ b/function/debounce.js @@ -1,4 +1,3 @@ -import isFunction from '../lang/isFunction'; import isObject from '../lang/isObject'; import now from '../date/now'; @@ -82,7 +81,7 @@ function debounce(func, wait, options) { maxWait = false, trailing = true; - if (!isFunction(func)) { + if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = wait < 0 ? 0 : wait; diff --git a/function/flow.js b/function/flow.js index 25b8b2bf9..580f5894b 100644 --- a/function/flow.js +++ b/function/flow.js @@ -33,7 +33,7 @@ function flow() { length = funcs.length; if (!length) { - return function() {}; + return function() { return arguments[0]; }; } if (!arrayEvery(funcs, isFunction)) { throw new TypeError(FUNC_ERROR_TEXT); diff --git a/function/flowRight.js b/function/flowRight.js index 6914c198e..64e88a9a4 100644 --- a/function/flowRight.js +++ b/function/flowRight.js @@ -33,7 +33,7 @@ function flowRight() { fromIndex = funcs.length - 1; if (fromIndex < 0) { - return function() {}; + return function() { return arguments[0]; }; } if (!arrayEvery(funcs, isFunction)) { throw new TypeError(FUNC_ERROR_TEXT); diff --git a/function/memoize.js b/function/memoize.js index 6e921ef6c..5d90cb8ad 100644 --- a/function/memoize.js +++ b/function/memoize.js @@ -1,5 +1,4 @@ import MapCache from '../internal/MapCache'; -import isFunction from '../lang/isFunction'; /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; @@ -58,7 +57,7 @@ var FUNC_ERROR_TEXT = 'Expected a function'; * // => { 'user': 'barney' } */ function memoize(func, resolver) { - if (!isFunction(func) || (resolver && !isFunction(resolver))) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { throw new TypeError(FUNC_ERROR_TEXT); } var memoized = function() { diff --git a/function/negate.js b/function/negate.js index 1222b2466..0d62eb9c6 100644 --- a/function/negate.js +++ b/function/negate.js @@ -1,5 +1,3 @@ -import isFunction from '../lang/isFunction'; - /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; @@ -23,7 +21,7 @@ var FUNC_ERROR_TEXT = 'Expected a function'; * // => [1, 3, 5] */ function negate(predicate) { - if (!isFunction(predicate)) { + if (typeof predicate != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } return function() { diff --git a/function/once.js b/function/once.js index a6e3aca72..ecfc4affe 100644 --- a/function/once.js +++ b/function/once.js @@ -7,7 +7,6 @@ import before from './before'; * * @static * @memberOf _ - * @type Function * @category Function * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. diff --git a/function/spread.js b/function/spread.js new file mode 100644 index 000000000..e0c9dfa79 --- /dev/null +++ b/function/spread.js @@ -0,0 +1,43 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that invokes `func` with the `this` binding of the + * created function and the array of arguments provided to the created + * function much like [Function#apply](http://es5.github.io/#x15.3.4.3). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {*} Returns the new function. + * @example + * + * var spread = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * spread(['Fred', 'hello']); + * // => 'Fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ +function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; +} + +export default spread; diff --git a/function/throttle.js b/function/throttle.js index ae001a682..e199e7d0c 100644 --- a/function/throttle.js +++ b/function/throttle.js @@ -1,5 +1,4 @@ import debounce from './debounce'; -import isFunction from '../lang/isFunction'; import isObject from '../lang/isObject'; /** Used as the `TypeError` message for "Functions" methods. */ @@ -54,7 +53,7 @@ function throttle(func, wait, options) { var leading = true, trailing = true; - if (!isFunction(func)) { + if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } if (options === false) { diff --git a/internal/LazyWrapper.js b/internal/LazyWrapper.js index 5c463ee3a..9ca6a515a 100644 --- a/internal/LazyWrapper.js +++ b/internal/LazyWrapper.js @@ -8,14 +8,14 @@ var POSITIVE_INFINITY = Number.POSITIVE_INFINITY; * @param {*} value The value to wrap. */ function LazyWrapper(value) { - this.actions = null; - this.dir = 1; - this.dropCount = 0; - this.filtered = false; - this.iteratees = null; - this.takeCount = POSITIVE_INFINITY; - this.views = null; - this.wrapped = value; + this.__wrapped__ = value; + this.__actions__ = null; + this.__dir__ = 1; + this.__dropCount__ = 0; + this.__filtered__ = false; + this.__iteratees__ = null; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = null; } export default LazyWrapper; diff --git a/internal/LodashWrapper.js b/internal/LodashWrapper.js index 95a1e3675..5a5a8b007 100644 --- a/internal/LodashWrapper.js +++ b/internal/LodashWrapper.js @@ -7,9 +7,9 @@ * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. */ function LodashWrapper(value, chainAll, actions) { + this.__wrapped__ = value; this.__actions__ = actions || []; this.__chain__ = !!chainAll; - this.__wrapped__ = value; } export default LodashWrapper; diff --git a/internal/baseAssign.js b/internal/baseAssign.js index c64e89e4b..53eae6349 100644 --- a/internal/baseAssign.js +++ b/internal/baseAssign.js @@ -17,7 +17,7 @@ function baseAssign(object, source, customizer) { return baseCopy(source, object, props); } var index = -1, - length = props.length + length = props.length; while (++index < length) { var key = props[index], diff --git a/internal/baseCallback.js b/internal/baseCallback.js index 6c7cce7ff..c25a72354 100644 --- a/internal/baseCallback.js +++ b/internal/baseCallback.js @@ -1,4 +1,5 @@ import baseMatches from './baseMatches'; +import baseMatchesProperty from './baseMatchesProperty'; import baseProperty from './baseProperty'; import bindCallback from './bindCallback'; import identity from '../utility/identity'; @@ -24,10 +25,12 @@ function baseCallback(func, thisArg, argCount) { if (func == null) { return identity; } - // Handle "_.property" and "_.matches" style callback shorthands. - return type == 'object' - ? baseMatches(func) - : baseProperty(func + ''); + if (type == 'object') { + return baseMatches(func); + } + return typeof thisArg == 'undefined' + ? baseProperty(func + '') + : baseMatchesProperty(func + '', thisArg); } export default baseCallback; diff --git a/internal/baseDelay.js b/internal/baseDelay.js index 65b0bf545..6cdc35111 100644 --- a/internal/baseDelay.js +++ b/internal/baseDelay.js @@ -1,5 +1,4 @@ import baseSlice from './baseSlice'; -import isFunction from '../lang/isFunction'; /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; @@ -15,7 +14,7 @@ var FUNC_ERROR_TEXT = 'Expected a function'; * @returns {number} Returns the timer id. */ function baseDelay(func, wait, args, fromIndex) { - if (!isFunction(func)) { + if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } return setTimeout(function() { func.apply(undefined, baseSlice(args, fromIndex)); }, wait); diff --git a/internal/baseFill.js b/internal/baseFill.js new file mode 100644 index 000000000..458c80d04 --- /dev/null +++ b/internal/baseFill.js @@ -0,0 +1,31 @@ +/** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ +function baseFill(array, value, start, end) { + var length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (typeof end == 'undefined' || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : end >>> 0; + start >>>= 0; + + while (start < length) { + array[start++] = value; + } + return array; +} + +export default baseFill; diff --git a/internal/baseIsMatch.js b/internal/baseIsMatch.js index 4c3427350..09ced8b11 100644 --- a/internal/baseIsMatch.js +++ b/internal/baseIsMatch.js @@ -11,7 +11,7 @@ var hasOwnProperty = objectProto.hasOwnProperty; * shorthands or `this` binding. * * @private - * @param {Object} source The object to inspect. + * @param {Object} object The object to inspect. * @param {Array} props The source property names to match. * @param {Array} values The source values to match. * @param {Array} strictCompareFlags Strict comparison flags for source values. diff --git a/internal/baseMatches.js b/internal/baseMatches.js index 6ac3cb3dd..6d0bd1a3f 100644 --- a/internal/baseMatches.js +++ b/internal/baseMatches.js @@ -9,8 +9,7 @@ var objectProto = Object.prototype; var hasOwnProperty = objectProto.hasOwnProperty; /** - * The base implementation of `_.matches` which supports specifying whether - * `source` should be cloned. + * The base implementation of `_.matches` which does not clone `source`. * * @private * @param {Object} source The object of property values to match. @@ -26,7 +25,7 @@ function baseMatches(source) { if (isStrictComparable(value)) { return function(object) { - return object != null && value === object[key] && hasOwnProperty.call(object, key); + return object != null && object[key] === value && hasOwnProperty.call(object, key); }; } } diff --git a/internal/baseMatchesProperty.js b/internal/baseMatchesProperty.js new file mode 100644 index 000000000..241c4c9d3 --- /dev/null +++ b/internal/baseMatchesProperty.js @@ -0,0 +1,24 @@ +import baseIsEqual from './baseIsEqual'; +import isStrictComparable from './isStrictComparable'; + +/** + * The base implementation of `_.matchesProperty` which does not coerce `key` + * to a string. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} value The value to compare. + * @returns {Function} Returns the new function. + */ +function baseMatchesProperty(key, value) { + if (isStrictComparable(value)) { + return function(object) { + return object != null && object[key] === value; + }; + } + return function(object) { + return object != null && baseIsEqual(value, object[key], null, true); + }; +} + +export default baseMatchesProperty; diff --git a/internal/baseReduce.js b/internal/baseReduce.js index d84183888..ad240c357 100644 --- a/internal/baseReduce.js +++ b/internal/baseReduce.js @@ -16,7 +16,7 @@ function baseReduce(collection, iteratee, accumulator, initFromCollection, eachF eachFunc(collection, function(value, index, collection) { accumulator = initFromCollection ? (initFromCollection = false, value) - : iteratee(accumulator, value, index, collection) + : iteratee(accumulator, value, index, collection); }); return accumulator; } diff --git a/internal/createAggregator.js b/internal/createAggregator.js index 1600f21f2..32dc868ac 100644 --- a/internal/createAggregator.js +++ b/internal/createAggregator.js @@ -5,8 +5,7 @@ import isArray from '../lang/isArray'; /** * Creates a function that aggregates a collection, creating an accumulator * object composed from the results of running each element in the collection - * through an iteratee. The `setter` sets the keys and values of the accumulator - * object. If `initializer` is provided initializes the accumulator object. + * through an iteratee. * * @private * @param {Function} setter The function to set keys and values of the accumulator object. diff --git a/internal/createWrapper.js b/internal/createWrapper.js index 59027949e..5d4a4eaa1 100644 --- a/internal/createWrapper.js +++ b/internal/createWrapper.js @@ -3,7 +3,6 @@ import createBindWrapper from './createBindWrapper'; import createHybridWrapper from './createHybridWrapper'; import createPartialWrapper from './createPartialWrapper'; import getData from './getData'; -import isFunction from '../lang/isFunction'; import mergeData from './mergeData'; import setData from './setData'; @@ -46,7 +45,7 @@ var nativeMax = Math.max; */ function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { var isBindKey = bitmask & BIND_KEY_FLAG; - if (!isBindKey && !isFunction(func)) { + if (!isBindKey && typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } var length = partials ? partials.length : 0; @@ -76,9 +75,9 @@ function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, a 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(null, newData); + result = createPartialWrapper.apply(undefined, newData); } else { - result = createHybridWrapper.apply(null, newData); + result = createHybridWrapper.apply(undefined, newData); } var setter = data ? baseSetData : setData; return setter(result, newData); diff --git a/internal/lazyClone.js b/internal/lazyClone.js index 25daa9316..8f79db195 100644 --- a/internal/lazyClone.js +++ b/internal/lazyClone.js @@ -10,18 +10,18 @@ import arrayCopy from './arrayCopy'; * @returns {Object} Returns the cloned `LazyWrapper` object. */ function lazyClone() { - var actions = this.actions, - iteratees = this.iteratees, - views = this.views, - result = new LazyWrapper(this.wrapped); + var actions = this.__actions__, + iteratees = this.__iteratees__, + views = this.__views__, + result = new LazyWrapper(this.__wrapped__); - result.actions = actions ? arrayCopy(actions) : null; - result.dir = this.dir; - result.dropCount = this.dropCount; - result.filtered = this.filtered; - result.iteratees = iteratees ? arrayCopy(iteratees) : null; - result.takeCount = this.takeCount; - result.views = views ? arrayCopy(views) : null; + result.__actions__ = actions ? arrayCopy(actions) : null; + result.__dir__ = this.__dir__; + result.__dropCount__ = this.__dropCount__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null; + result.__takeCount__ = this.__takeCount__; + result.__views__ = views ? arrayCopy(views) : null; return result; } diff --git a/internal/lazyReverse.js b/internal/lazyReverse.js index cd529d11a..ef282d39c 100644 --- a/internal/lazyReverse.js +++ b/internal/lazyReverse.js @@ -9,13 +9,13 @@ import LazyWrapper from './LazyWrapper'; * @returns {Object} Returns the new reversed `LazyWrapper` object. */ function lazyReverse() { - if (this.filtered) { + if (this.__filtered__) { var result = new LazyWrapper(this); - result.dir = -1; - result.filtered = true; + result.__dir__ = -1; + result.__filtered__ = true; } else { result = this.clone(); - result.dir *= -1; + result.__dir__ *= -1; } return result; } diff --git a/internal/lazyValue.js b/internal/lazyValue.js index 69e9b5b13..2f1a01b96 100644 --- a/internal/lazyValue.js +++ b/internal/lazyValue.js @@ -18,20 +18,20 @@ var nativeMin = Math.min; * @returns {*} Returns the unwrapped value. */ function lazyValue() { - var array = this.wrapped.value(); + var array = this.__wrapped__.value(); if (!isArray(array)) { - return baseWrapperValue(array, this.actions); + return baseWrapperValue(array, this.__actions__); } - var dir = this.dir, + var dir = this.__dir__, isRight = dir < 0, - view = getView(0, array.length, this.views), + view = getView(0, array.length, this.__views__), start = view.start, end = view.end, length = end - start, - dropCount = this.dropCount, - takeCount = nativeMin(length, this.takeCount - dropCount), + dropCount = this.__dropCount__, + takeCount = nativeMin(length, this.__takeCount__), index = isRight ? end : start - 1, - iteratees = this.iteratees, + iteratees = this.__iteratees__, iterLength = iteratees ? iteratees.length : 0, resIndex = 0, result = []; diff --git a/internal/wrapperClone.js b/internal/wrapperClone.js new file mode 100644 index 000000000..57b88baf2 --- /dev/null +++ b/internal/wrapperClone.js @@ -0,0 +1,18 @@ +import LazyWrapper from './LazyWrapper'; +import LodashWrapper from './LodashWrapper'; +import arrayCopy from './arrayCopy'; + +/** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ +function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); +} + +export default wrapperClone; diff --git a/lang/isEqual.js b/lang/isEqual.js index 507b6109d..b9002babc 100644 --- a/lang/isEqual.js +++ b/lang/isEqual.js @@ -10,7 +10,8 @@ import isStrictComparable from '../internal/isStrictComparable'; * arguments; (value, other [, index|key]). * * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Functions and DOM nodes + * 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. * diff --git a/lang/isMatch.js b/lang/isMatch.js index 6e017717b..e4406ce6b 100644 --- a/lang/isMatch.js +++ b/lang/isMatch.js @@ -24,7 +24,7 @@ var hasOwnProperty = objectProto.hasOwnProperty; * @static * @memberOf _ * @category Lang - * @param {Object} source The object to inspect. + * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @param {Function} [customizer] The function to customize comparing values. * @param {*} [thisArg] The `this` binding of `customizer`. diff --git a/lodash.js b/lodash.js index 32faa2aaa..6d04a7404 100644 --- a/lodash.js +++ b/lodash.js @@ -1,6 +1,6 @@ /** * @license - * lodash 3.1.0 (Custom Build) + * lodash 3.2.0 (Custom Build) * Build: `lodash modularize modern exports="es" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.7.0 @@ -21,10 +21,12 @@ import LazyWrapper from './internal/LazyWrapper'; import LodashWrapper from './internal/LodashWrapper'; import arrayEach from './internal/arrayEach'; import baseCallback from './internal/baseCallback'; +import baseCreate from './internal/baseCreate'; import baseForOwn from './internal/baseForOwn'; import baseFunctions from './internal/baseFunctions'; import baseMatches from './internal/baseMatches'; import baseProperty from './internal/baseProperty'; +import identity from './utility/identity'; import isArray from './lang/isArray'; import isObject from './lang/isObject'; import keys from './object/keys'; @@ -37,7 +39,7 @@ import support from './support'; import thru from './chain/thru'; /** Used as the semantic version number. */ -var VERSION = '3.1.0'; +var VERSION = '3.2.0'; /** Used to indicate the type of lazy iteratees. */ var LAZY_FILTER_FLAG = 0, @@ -47,13 +49,20 @@ var LAZY_FILTER_FLAG = 0, var arrayProto = Array.prototype; /** Native method references. */ -var push = arrayProto.push, - unshift = arrayProto.unshift; +var floor = Math.floor, + push = arrayProto.push; /* Native method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max, nativeMin = Math.min; +// Ensure `new LodashWrapper` is an instance of `lodash`. +LodashWrapper.prototype = baseCreate(lodash.prototype); + +// Ensure `new LazyWraper` is an instance of `LodashWrapper` +LazyWrapper.prototype = baseCreate(LodashWrapper.prototype); +LazyWrapper.prototype.constructor = LazyWrapper; + // wrap `_.mixin` so it works when provided only one argument var mixin = (function(func) { return function(object, source, options) { @@ -99,6 +108,7 @@ 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; @@ -122,6 +132,7 @@ lodash.keysIn = object.keysIn; lodash.map = collection.map; lodash.mapValues = object.mapValues; lodash.matches = utility.matches; +lodash.matchesProperty = utility.matchesProperty; lodash.memoize = func.memoize; lodash.merge = object.merge; lodash.mixin = mixin; @@ -147,6 +158,7 @@ lodash.shuffle = collection.shuffle; lodash.slice = array.slice; lodash.sortBy = collection.sortBy; lodash.sortByAll = collection.sortByAll; +lodash.spread = func.spread; lodash.take = array.take; lodash.takeRight = array.takeRight; lodash.takeRightWhile = array.takeRightWhile; @@ -207,7 +219,7 @@ lodash.findLastKey = object.findLastKey; lodash.findWhere = collection.findWhere; lodash.first = array.first; lodash.has = object.has; -lodash.identity = utility.identity; +lodash.identity = identity; lodash.includes = collection.includes; lodash.indexOf = array.indexOf; lodash.isArguments = lang.isArguments; @@ -315,14 +327,15 @@ arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], // Add `LazyWrapper` methods that accept an `iteratee` value. arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { - var isFilter = index == LAZY_FILTER_FLAG; + var isFilter = index == LAZY_FILTER_FLAG, + isWhile = index == LAZY_WHILE_FLAG; LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { var result = this.clone(), - filtered = result.filtered, - iteratees = result.iteratees || (result.iteratees = []); + filtered = result.__filtered__, + iteratees = result.__iteratees__ || (result.__iteratees__ = []); - result.filtered = filtered || isFilter || (index == LAZY_WHILE_FLAG && result.dir < 0); + result.__filtered__ = filtered || isFilter || (isWhile && result.__dir__ < 0); iteratees.push({ 'iteratee': baseCallback(iteratee, thisArg, 3), 'type': index }); return result; }; @@ -330,19 +343,19 @@ arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { // Add `LazyWrapper` methods for `_.drop` and `_.take` variants. arrayEach(['drop', 'take'], function(methodName, index) { - var countName = methodName + 'Count', + var countName = '__' + methodName + 'Count__', whileName = methodName + 'While'; LazyWrapper.prototype[methodName] = function(n) { - n = n == null ? 1 : nativeMax(+n || 0, 0); + n = n == null ? 1 : nativeMax(floor(n) || 0, 0); var result = this.clone(); - if (result.filtered) { + if (result.__filtered__) { var value = result[countName]; result[countName] = index ? nativeMin(value, n) : (value + n); } else { - var views = result.views || (result.views = []); - views.push({ 'size': n, 'type': methodName + (result.dir < 0 ? 'Right' : '') }); + var views = result.__views__ || (result.__views__ = []); + views.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); } return result; }; @@ -358,7 +371,7 @@ arrayEach(['drop', 'take'], function(methodName, index) { // Add `LazyWrapper` methods for `_.first` and `_.last`. arrayEach(['first', 'last'], function(methodName, index) { - var takeName = 'take' + (index ? 'Right': ''); + var takeName = 'take' + (index ? 'Right' : ''); LazyWrapper.prototype[methodName] = function() { return this[takeName](1).value()[0]; @@ -380,27 +393,26 @@ arrayEach(['pluck', 'where'], function(methodName, index) { createCallback = index ? baseMatches : baseProperty; LazyWrapper.prototype[methodName] = function(value) { - return this[operationName](createCallback(index ? value : (value + ''))); + return this[operationName](createCallback(value)); }; }); -LazyWrapper.prototype.dropWhile = function(iteratee, thisArg) { - var done, - lastIndex, - isRight = this.dir < 0; +LazyWrapper.prototype.compact = function() { + return this.filter(identity); +}; - iteratee = baseCallback(iteratee, thisArg, 3); +LazyWrapper.prototype.dropWhile = function(predicate, thisArg) { + var done; + predicate = baseCallback(predicate, thisArg, 3); return this.filter(function(value, index, array) { - done = done && (isRight ? index < lastIndex : index > lastIndex); - lastIndex = index; - return done || (done = !iteratee(value, index, array)); + return done || (done = !predicate(value, index, array)); }); }; -LazyWrapper.prototype.reject = function(iteratee, thisArg) { - iteratee = baseCallback(iteratee, thisArg, 3); +LazyWrapper.prototype.reject = function(predicate, thisArg) { + predicate = baseCallback(predicate, thisArg, 3); return this.filter(function(value, index, array) { - return !iteratee(value, index, array); + return !predicate(value, index, array); }); }; @@ -415,6 +427,10 @@ LazyWrapper.prototype.slice = function(start, end) { return result; }; +LazyWrapper.prototype.toArray = function() { + return this.drop(0); +}; + // Add `LazyWrapper` methods to `lodash.prototype`. baseForOwn(LazyWrapper.prototype, function(func, methodName) { var lodashFunc = lodash[methodName], @@ -442,8 +458,8 @@ baseForOwn(LazyWrapper.prototype, function(func, methodName) { var wrapper = onlyLazy ? value : new LazyWrapper(this), result = func.apply(wrapper, args); - if (!retUnwrapped && (isHybrid || result.actions)) { - var actions = result.actions || (result.actions = []); + if (!retUnwrapped && (isHybrid || result.__actions__)) { + var actions = result.__actions__ || (result.__actions__ = []); actions.push({ 'func': thru, 'args': [interceptor], 'thisArg': lodash }); } return new LodashWrapper(result, chainAll); @@ -476,9 +492,11 @@ LazyWrapper.prototype.value = lazyValue; // Add chaining functions to the lodash wrapper. lodash.prototype.chain = chain.wrapperChain; +lodash.prototype.commit = chain.commit; +lodash.prototype.plant = chain.plant; lodash.prototype.reverse = chain.reverse; lodash.prototype.toString = chain.toString; -lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = chain.value; +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; diff --git a/object/findKey.js b/object/findKey.js index 278362994..8bbb7f2ae 100644 --- a/object/findKey.js +++ b/object/findKey.js @@ -6,10 +6,14 @@ import baseForOwn from '../internal/baseForOwn'; * This method is like `_.findIndex` 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -18,8 +22,7 @@ import baseForOwn from '../internal/baseForOwn'; * @category Object * @param {Object} object The object to search. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example @@ -33,11 +36,15 @@ import baseForOwn from '../internal/baseForOwn'; * _.findKey(users, function(chr) { return chr.age < 40; }); * // => 'barney' (iteration order is not guaranteed) * - * // using the "_.matches" callback shorthand - * _.findKey(users, { 'age': 1 }); + * // using the `_.matches` callback shorthand + * _.findKey(users, { 'age': 1, 'active': true }); * // => 'pebbles' * - * // using the "_.property" callback shorthand + * // using the `_.matchesProperty` callback shorthand + * _.findKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand * _.findKey(users, 'active'); * // => 'barney' */ diff --git a/object/findLastKey.js b/object/findLastKey.js index 10e63fedf..a9361107c 100644 --- a/object/findLastKey.js +++ b/object/findLastKey.js @@ -6,10 +6,14 @@ import baseForOwnRight from '../internal/baseForOwnRight'; * 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" + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `predicate` the created "_.matches" style + * 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`. * @@ -18,8 +22,7 @@ import baseForOwnRight from '../internal/baseForOwnRight'; * @category Object * @param {Object} object The object to search. * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example @@ -33,11 +36,15 @@ import baseForOwnRight from '../internal/baseForOwnRight'; * _.findLastKey(users, function(chr) { return chr.age < 40; }); * // => returns `pebbles` assuming `_.findKey` returns `barney` * - * // using the "_.matches" callback shorthand - * _.findLastKey(users, { 'age': 36 }); + * // using the `_.matches` callback shorthand + * _.findLastKey(users, { 'age': 36, 'active': true }); * // => 'barney' * - * // using the "_.property" callback shorthand + * // using the `_.matchesProperty` callback shorthand + * _.findLastKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand * _.findLastKey(users, 'active'); * // => 'pebbles' */ diff --git a/object/keysIn.js b/object/keysIn.js index 34f0b9510..117338658 100644 --- a/object/keysIn.js +++ b/object/keysIn.js @@ -46,7 +46,7 @@ function keysIn(object) { var Ctor = object.constructor, index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype == object, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, result = Array(length), skipIndexes = length > 0; diff --git a/object/mapValues.js b/object/mapValues.js index 929fa09c7..74ec2a1d9 100644 --- a/object/mapValues.js +++ b/object/mapValues.js @@ -7,10 +7,14 @@ import baseForOwn from '../internal/baseForOwn'; * 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" + * If a property name is provided for `iteratee` the created `_.property` * style callback returns the property value of the given element. * - * If an object is provided for `iteratee` the created "_.matches" style + * 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`. * @@ -19,8 +23,7 @@ import baseForOwn from '../internal/baseForOwn'; * @category Object * @param {Object} object The object to iterate over. * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. + * per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {Object} Returns the new mapped object. * @example @@ -33,7 +36,7 @@ import baseForOwn from '../internal/baseForOwn'; * 'pebbles': { 'user': 'pebbles', 'age': 1 } * }; * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.mapValues(users, 'age'); * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ diff --git a/object/transform.js b/object/transform.js index dfbfff41a..f2849b2c6 100644 --- a/object/transform.js +++ b/object/transform.js @@ -3,6 +3,7 @@ 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'; @@ -47,7 +48,7 @@ function transform(object, iteratee, accumulator, thisArg) { if (isArr) { accumulator = isArray(object) ? new Ctor : []; } else { - accumulator = baseCreate(typeof Ctor == 'function' && Ctor.prototype); + accumulator = baseCreate(isFunction(Ctor) && Ctor.prototype); } } else { accumulator = {}; diff --git a/package.json b/package.json index 68bb2c915..640885db4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash-es", - "version": "3.1.0", + "version": "3.2.0", "description": "The modern build of lodash exported as ES modules.", "homepage": "https://lodash.com/custom-builds", "license": "MIT", diff --git a/string/trimLeft.js b/string/trimLeft.js index 134e35aa0..88d78581e 100644 --- a/string/trimLeft.js +++ b/string/trimLeft.js @@ -28,7 +28,7 @@ function trimLeft(string, chars, guard) { return string; } if (guard ? isIterateeCall(value, chars, guard) : chars == null) { - return string.slice(trimmedLeftIndex(string)) + return string.slice(trimmedLeftIndex(string)); } return string.slice(charsLeftIndex(string, (chars + ''))); } diff --git a/string/trimRight.js b/string/trimRight.js index 24fa43fdc..31c4bdee9 100644 --- a/string/trimRight.js +++ b/string/trimRight.js @@ -28,7 +28,7 @@ function trimRight(string, chars, guard) { return string; } if (guard ? isIterateeCall(value, chars, guard) : chars == null) { - return string.slice(0, trimmedRightIndex(string) + 1) + return string.slice(0, trimmedRightIndex(string) + 1); } return string.slice(0, charsRightIndex(string, (chars + '')) + 1); } diff --git a/utility.js b/utility.js index 08b62fe00..7ec948f6d 100644 --- a/utility.js +++ b/utility.js @@ -4,6 +4,7 @@ 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 mixin from './utility/mixin'; import noop from './utility/noop'; import property from './utility/property'; @@ -19,6 +20,7 @@ export default { 'identity': identity, 'iteratee': iteratee, 'matches': matches, + 'matchesProperty': matchesProperty, 'mixin': mixin, 'noop': noop, 'property': property, diff --git a/utility/attempt.js b/utility/attempt.js index 3c234155d..c1ff929c7 100644 --- a/utility/attempt.js +++ b/utility/attempt.js @@ -1,8 +1,9 @@ +import baseSlice from '../internal/baseSlice'; import isError from '../lang/isError'; /** - * Attempts to invoke `func`, returning either the result or the caught - * error object. + * Attempts to invoke `func`, returning either the result or the caught error + * object. Any additional arguments are provided to `func` when it is invoked. * * @static * @memberOf _ @@ -12,9 +13,9 @@ import isError from '../lang/isError'; * @example * * // avoid throwing errors for invalid selectors - * var elements = _.attempt(function() { + * var elements = _.attempt(function(selector) { * return document.querySelectorAll(selector); - * }); + * }, '>_>'); * * if (_.isError(elements)) { * elements = []; @@ -22,9 +23,9 @@ import isError from '../lang/isError'; */ function attempt(func) { try { - return func(); + return func.apply(undefined, baseSlice(arguments, 1)); } catch(e) { - return isError(e) ? e : Error(e); + return isError(e) ? e : new Error(e); } } diff --git a/utility/callback.js b/utility/callback.js index 8838b0d38..0c35240a6 100644 --- a/utility/callback.js +++ b/utility/callback.js @@ -4,10 +4,11 @@ import isObjectLike from '../internal/isObjectLike'; import matches from './matches'; /** - * Creates a function bound to an optional `thisArg`. 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`. + * 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 _ diff --git a/utility/matches.js b/utility/matches.js index afcefadf4..3f4437314 100644 --- a/utility/matches.js +++ b/utility/matches.js @@ -6,6 +6,11 @@ import baseMatches from '../internal/baseMatches'; * 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 @@ -14,17 +19,12 @@ import baseMatches from '../internal/baseMatches'; * @example * * var users = [ - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 36 } + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } * ]; * - * var matchesAge = _.matches({ 'age': 36 }); - * - * _.filter(users, matchesAge); - * // => [{ 'user': 'barney', 'age': 36 }] - * - * _.find(users, matchesAge); - * // => { 'user': 'barney', 'age': 36 } + * _.filter(users, _.matches({ 'age': 40, 'active': false })); + * // => [{ 'user': 'fred', 'age': 40, 'active': false }] */ function matches(source) { return baseMatches(baseClone(source, true)); diff --git a/utility/matchesProperty.js b/utility/matchesProperty.js new file mode 100644 index 000000000..c241b4ca7 --- /dev/null +++ b/utility/matchesProperty.js @@ -0,0 +1,33 @@ +import baseClone from '../internal/baseClone'; +import baseMatchesProperty from '../internal/baseMatchesProperty'; + +/** + * Creates a function which compares the property value of `key` on a given + * object to `value`. + * + * **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. + * + * @static + * @memberOf _ + * @category Utility + * @param {string} key The key of the property to get. + * @param {*} value The value to compare. + * @returns {Function} Returns the new function. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' }, + * { 'user': 'pebbles' } + * ]; + * + * _.find(users, _.matchesProperty('user', 'fred')); + * // => { 'user': 'fred', 'age': 40 } + */ +function matchesProperty(key, value) { + return baseMatchesProperty(key + '', baseClone(value, true)); +} + +export default matchesProperty; diff --git a/utility/mixin.js b/utility/mixin.js index 6ccfaa777..59609efb3 100644 --- a/utility/mixin.js +++ b/utility/mixin.js @@ -32,6 +32,9 @@ var push = arrayProto.push; * }); * } * + * // use `_.runInContext` to avoid potential conflicts (esp. in Node.js) + * var _ = require('lodash').runInContext(); + * * _.mixin({ 'vowels': vowels }); * _.vowels('fred'); * // => ['e']