From 05cb7419a6d70d157fa4c8b73bb294fa96939f7f Mon Sep 17 00:00:00 2001 From: jdalton Date: Sun, 8 Feb 2015 22:05:22 -0800 Subject: [PATCH] Bump to v3.2.0. --- README.md | 18 +- array.js | 1 + array/chunk.js | 2 +- array/drop.js | 1 - array/dropRight.js | 1 - array/dropRightWhile.js | 33 +- array/dropWhile.js | 29 +- array/fill.js | 31 + array/findIndex.js | 35 +- array/findLastIndex.js | 29 +- array/remove.js | 11 +- array/sortedIndex.js | 13 +- array/sortedLastIndex.js | 3 +- array/take.js | 1 - array/takeRight.js | 1 - array/takeRightWhile.js | 31 +- array/takeWhile.js | 29 +- array/uniq.js | 12 +- chain.js | 3 + chain/chain.js | 2 +- chain/commit.js | 1 + chain/lodash.js | 64 +- chain/plant.js | 1 + chain/run.js | 1 + chain/wrapperChain.js | 2 +- chain/wrapperCommit.js | 32 + chain/wrapperPlant.js | 45 ++ chain/wrapperReverse.js | 4 +- chain/wrapperValue.js | 2 +- collection/countBy.js | 11 +- collection/every.js | 29 +- collection/filter.js | 27 +- collection/find.js | 29 +- collection/findLast.js | 3 +- collection/findWhere.js | 13 +- collection/groupBy.js | 13 +- collection/indexBy.js | 11 +- collection/map.js | 23 +- collection/max.js | 12 +- collection/min.js | 12 +- collection/partition.js | 25 +- collection/pluck.js | 2 +- collection/reduce.js | 6 + collection/reject.js | 23 +- collection/some.js | 29 +- collection/sortBy.js | 12 +- collection/sortByAll.js | 2 +- collection/where.js | 14 +- function.js | 1 + function/after.js | 6 +- function/before.js | 6 +- function/debounce.js | 5 +- function/flow.js | 2 +- function/flowRight.js | 2 +- function/memoize.js | 5 +- function/negate.js | 4 +- function/once.js | 1 - function/spread.js | 43 ++ function/throttle.js | 3 +- index.js | 1114 +++++++++++++++++++++---------- internal/LazyWrapper.js | 16 +- internal/LodashWrapper.js | 2 +- internal/baseAssign.js | 2 +- internal/baseCallback.js | 11 +- internal/baseDelay.js | 5 +- internal/baseFill.js | 31 + internal/baseIsMatch.js | 2 +- internal/baseMatches.js | 5 +- internal/baseMatchesProperty.js | 24 + internal/baseReduce.js | 2 +- internal/createAggregator.js | 3 +- internal/createWrapper.js | 7 +- internal/lazyClone.js | 22 +- internal/lazyReverse.js | 8 +- internal/lazyValue.js | 14 +- internal/wrapperClone.js | 18 + lang/isEqual.js | 3 +- lang/isMatch.js | 2 +- object/findKey.js | 21 +- object/findLastKey.js | 21 +- object/keysIn.js | 2 +- object/mapValues.js | 13 +- object/transform.js | 3 +- package.json | 2 +- string/trimLeft.js | 2 +- string/trimRight.js | 2 +- utility.js | 1 + utility/attempt.js | 15 +- utility/callback.js | 9 +- utility/matches.js | 18 +- utility/matchesProperty.js | 33 + utility/mixin.js | 3 + 92 files changed, 1528 insertions(+), 720 deletions(-) create mode 100644 array/fill.js create mode 100644 chain/commit.js create mode 100644 chain/plant.js create mode 100644 chain/run.js create mode 100644 chain/wrapperCommit.js create mode 100644 chain/wrapperPlant.js create mode 100644 function/spread.js create mode 100644 internal/baseFill.js create mode 100644 internal/baseMatchesProperty.js create mode 100644 internal/wrapperClone.js create mode 100644 utility/matchesProperty.js diff --git a/README.md b/README.md index ae22f683b..7c2b1729f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash v3.1.0 +# lodash v3.2.0 The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) modules. @@ -28,7 +28,7 @@ var array = require('lodash/array'); var chunk = require('lodash/array/chunk'); ``` -See the [package source](https://github.com/lodash/lodash/tree/3.1.0-npm) for more details. +See the [package source](https://github.com/lodash/lodash/tree/3.2.0-npm) for more details. **Note:**
Don’t assign values to the [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL.
@@ -39,8 +39,8 @@ Install [n_](https://www.npmjs.com/package/n_) for a REPL that includes lodash b lodash is also available in a variety of other builds & module formats. * npm packages for [modern](https://www.npmjs.com/package/lodash), [compatibility](https://www.npmjs.com/package/lodash-compat), & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) builds - * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.1.0-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.1.0-amd) builds - * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.1.0-es) build + * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.2.0-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.2.0-amd) builds + * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.2.0-es) build ## Further Reading @@ -68,8 +68,9 @@ lodash is also available in a variety of other builds & module formats. * [_.create](https://lodash.com/docs#create) for easier object inheritance * [_.curry](https://lodash.com/docs#curry) & [_.curryRight](https://lodash.com/docs#curryRight) for creating [curried](http://hughfdjackson.com/javascript/why-curry-helps/) functions * [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) are cancelable & accept options for more control + * [_.fill](https://lodash.com/docs#fill) to fill arrays with values * [_.findIndex](https://lodash.com/docs#findIndex) & [_.findKey](https://lodash.com/docs#findKey) for finding indexes & keys - * [_.flow](https://lodash.com/docs#flow) to complement [_.flowRight](https://lodash.com/docs#flowRight) (a.k.a `_.backflow` & `_.compose`) + * [_.flow](https://lodash.com/docs#flow) to complement [_.flowRight](https://lodash.com/docs#flowRight) (a.k.a `_.compose`) * [_.forEach](https://lodash.com/docs#forEach) supports exiting early * [_.forIn](https://lodash.com/docs#forIn) for iterating all enumerable properties * [_.forOwn](https://lodash.com/docs#forOwn) for iterating own properties @@ -81,6 +82,7 @@ lodash is also available in a variety of other builds & module formats. * [_.keysIn](https://lodash.com/docs#keysIn) & [_.valuesIn](https://lodash.com/docs#valuesIn) for getting keys & values of all enumerable properties * [_.mapValues](https://lodash.com/docs#mapValues) for [mapping](https://lodash.com/docs#map) values to an object * [_.matches](https://lodash.com/docs#matches) supports deep object comparisons + * [_.matchesProperty](https://lodash.com/docs#matchesProperty) to complement [_.matches](https://lodash.com/docs#matches) & [_.property](https://lodash.com/docs#property) * [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend) * [_.parseInt](https://lodash.com/docs#parseInt) for consistent cross-environment behavior * [_.propertyOf](https://lodash.com/docs#propertyOf) to complement [_.property](https://lodash.com/docs#property) @@ -89,10 +91,10 @@ lodash is also available in a variety of other builds & module formats. * [_.runInContext](https://lodash.com/docs#runInContext) for collisionless mixins & easier mocking * [_.slice](https://lodash.com/docs#slice) for creating subsets of array-like values * [_.sortByAll](https://lodash.com/docs#sortBy) for sorting by multiple properties + * [_.spread](https://lodash.com/docs#spread) for creating a function to spread an array of arguments to another * [_.support](https://lodash.com/docs#support) for flagging environment features * [_.template](https://lodash.com/docs#template) supports [*“imports”*](https://lodash.com/docs#templateSettings-imports) options & [ES template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components) * [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects - * [_.thru](https://lodash.com/docs#thru) to pass values thru method chains * [_.xor](https://lodash.com/docs#xor) to complement [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union) * [_.bind](https://lodash.com/docs#bind), [_.curry](https://lodash.com/docs#curry), [_.partial](https://lodash.com/docs#partial), & [more](https://lodash.com/docs "_.bindKey, _.curryRight, _.partialRight") support customizable argument placeholders @@ -106,9 +108,11 @@ lodash is also available in a variety of other builds & module formats. [more](https://lodash.com/docs "_.findLastKey, _.flowRight, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods * [_.includes](https://lodash.com/docs#includes), [_.toArray](https://lodash.com/docs#toArray), & [more](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.findLast, _.forEach, _.forEachRight, _.groupBy, _.indexBy, _.invoke, _.map, _.max, _.min, _.partition, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy") accept strings + * [_#commit](https://lodash.com/docs#prototype-commit) & [_#plant](https://lodash.com/docs#prototype-plant) for working with chain sequences + * [_#thru](https://lodash.com/docs#thru) to pass values thru a chain sequence ## Support -Tested in Chrome 39-40, Firefox 34-35, IE 6-11, Opera 26-27, Safari 5-8, io.js 1.0.4, Node.js 0.8.28 & 0.10.35, PhantomJS 1.9.8, RingoJS 0.11, & Rhino 1.7RC5. +Tested in Chrome 39-40, Firefox 34-35, IE 6-11, Opera 26-27, Safari 5-8, io.js 1.2.0, Node.js 0.8.28, 0.10.36, & 0.12.0, PhantomJS 1.9.8, RingoJS 0.11, & Rhino 1.7RC5. Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing. diff --git a/array.js b/array.js index 2623029c2..6ef12c75e 100644 --- a/array.js +++ b/array.js @@ -6,6 +6,7 @@ module.exports = { 'dropRight': require('./array/dropRight'), 'dropRightWhile': require('./array/dropRightWhile'), 'dropWhile': require('./array/dropWhile'), + 'fill': require('./array/fill'), 'findIndex': require('./array/findIndex'), 'findLastIndex': require('./array/findLastIndex'), 'first': require('./array/first'), diff --git a/array/chunk.js b/array/chunk.js index 3399ebab5..4de9b3961 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 07e9c7fe3..039a0b5fd 100644 --- a/array/drop.js +++ b/array/drop.js @@ -6,7 +6,6 @@ var baseSlice = require('../internal/baseSlice'), * * @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 8ed3e3d83..14b5eb6f0 100644 --- a/array/dropRight.js +++ b/array/dropRight.js @@ -6,7 +6,6 @@ var baseSlice = require('../internal/baseSlice'), * * @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 dff764862..7e0b455aa 100644 --- a/array/dropRightWhile.js +++ b/array/dropRightWhile.js @@ -6,20 +6,23 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * // => [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 bffdf4029..5123bc8cf 100644 --- a/array/dropWhile.js +++ b/array/dropWhile.js @@ -6,20 +6,23 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * // => [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..44811d309 --- /dev/null +++ b/array/fill.js @@ -0,0 +1,31 @@ +var baseFill = require('../internal/baseFill'), + isIterateeCall = require('../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); +} + +module.exports = fill; diff --git a/array/findIndex.js b/array/findIndex.js index 2695f3b77..f44b5d153 100644 --- a/array/findIndex.js +++ b/array/findIndex.js @@ -4,10 +4,14 @@ var baseCallback = require('../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 @@ var baseCallback = require('../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 4e66a5a42..0d5ac4576 100644 --- a/array/findLastIndex.js +++ b/array/findLastIndex.js @@ -4,10 +4,14 @@ var baseCallback = require('../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 @@ var baseCallback = require('../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 500e21cd0..ab545da2c 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 aed4b8db4..9a0abe9e5 100644 --- a/array/sortedIndex.js +++ b/array/sortedIndex.js @@ -9,10 +9,14 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * @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 @@ var baseCallback = require('../internal/baseCallback'), * }, 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 806713a61..21d643ff4 100644 --- a/array/sortedLastIndex.js +++ b/array/sortedLastIndex.js @@ -13,8 +13,7 @@ var baseCallback = require('../internal/baseCallback'), * @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 3482beef9..875917a74 100644 --- a/array/take.js +++ b/array/take.js @@ -6,7 +6,6 @@ var baseSlice = require('../internal/baseSlice'), * * @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 5c6a42879..6e89c8748 100644 --- a/array/takeRight.js +++ b/array/takeRight.js @@ -6,7 +6,6 @@ var baseSlice = require('../internal/baseSlice'), * * @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 e3c30c741..65e6010a8 100644 --- a/array/takeRightWhile.js +++ b/array/takeRightWhile.js @@ -6,20 +6,23 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * // => [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 aaf2b6291..ede84b031 100644 --- a/array/takeWhile.js +++ b/array/takeWhile.js @@ -6,20 +6,23 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * // => [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 3ea2d3b41..6d1462bc0 100644 --- a/array/uniq.js +++ b/array/uniq.js @@ -11,10 +11,14 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * @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 @@ var baseCallback = require('../internal/baseCallback'), * _.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 1c3c6e162..7992b733e 100644 --- a/chain.js +++ b/chain.js @@ -1,7 +1,10 @@ module.exports = { 'chain': require('./chain/chain'), + 'commit': require('./chain/commit'), 'lodash': require('./chain/lodash'), + 'plant': require('./chain/plant'), 'reverse': require('./chain/reverse'), + 'run': require('./chain/run'), 'tap': require('./chain/tap'), 'thru': require('./chain/thru'), 'toJSON': require('./chain/toJSON'), diff --git a/chain/chain.js b/chain/chain.js index dc777a0fd..36cc3d37f 100644 --- a/chain/chain.js +++ b/chain/chain.js @@ -8,7 +8,7 @@ var lodash = require('./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..c732d1bf9 --- /dev/null +++ b/chain/commit.js @@ -0,0 +1 @@ +module.exports = require('./wrapperCommit'); diff --git a/chain/lodash.js b/chain/lodash.js index 62e07f580..ad9087656 100644 --- a/chain/lodash.js +++ b/chain/lodash.js @@ -1,7 +1,8 @@ -var LodashWrapper = require('../internal/LodashWrapper'), - arrayCopy = require('../internal/arrayCopy'), +var LazyWrapper = require('../internal/LazyWrapper'), + LodashWrapper = require('../internal/LodashWrapper'), isArray = require('../lang/isArray'), - isObjectLike = require('../internal/isObjectLike'); + isObjectLike = require('../internal/isObjectLike'), + wrapperClone = require('../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; - module.exports = lodash; diff --git a/chain/plant.js b/chain/plant.js new file mode 100644 index 000000000..04099f238 --- /dev/null +++ b/chain/plant.js @@ -0,0 +1 @@ +module.exports = require('./wrapperPlant'); diff --git a/chain/run.js b/chain/run.js new file mode 100644 index 000000000..5e751a2c3 --- /dev/null +++ b/chain/run.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/chain/wrapperChain.js b/chain/wrapperChain.js index 68bb74935..38234819b 100644 --- a/chain/wrapperChain.js +++ b/chain/wrapperChain.js @@ -6,7 +6,7 @@ var chain = require('./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..c46a787e9 --- /dev/null +++ b/chain/wrapperCommit.js @@ -0,0 +1,32 @@ +var LodashWrapper = require('../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__); +} + +module.exports = wrapperCommit; diff --git a/chain/wrapperPlant.js b/chain/wrapperPlant.js new file mode 100644 index 000000000..5b94c488a --- /dev/null +++ b/chain/wrapperPlant.js @@ -0,0 +1,45 @@ +var LodashWrapper = require('../internal/LodashWrapper'), + wrapperClone = require('../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; +} + +module.exports = wrapperPlant; diff --git a/chain/wrapperReverse.js b/chain/wrapperReverse.js index bf8f811bd..4518b3ed2 100644 --- a/chain/wrapperReverse.js +++ b/chain/wrapperReverse.js @@ -11,7 +11,7 @@ var LazyWrapper = require('../internal/LazyWrapper'), * @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 c20d277b5..2734e41c4 100644 --- a/chain/wrapperValue.js +++ b/chain/wrapperValue.js @@ -5,7 +5,7 @@ var baseWrapperValue = require('../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 6f52b939c..f0d743365 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 5641f9c17..276afb3ed 100644 --- a/collection/every.js +++ b/collection/every.js @@ -8,10 +8,14 @@ var arrayEvery = require('../internal/arrayEvery'), * 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 @@ var arrayEvery = require('../internal/arrayEvery'), * @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 5ede1de8b..320b903a6 100644 --- a/collection/filter.js +++ b/collection/filter.js @@ -8,10 +8,14 @@ var arrayFilter = require('../internal/arrayFilter'), * `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 @@ var arrayFilter = require('../internal/arrayFilter'), * @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 @@ var arrayFilter = require('../internal/arrayFilter'), * // => [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 70045bcba..497a3fb95 100644 --- a/collection/find.js +++ b/collection/find.js @@ -9,10 +9,14 @@ var baseCallback = require('../internal/baseCallback'), * `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 @@ var baseCallback = require('../internal/baseCallback'), * @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 281133c7d..d7d0545b0 100644 --- a/collection/findLast.js +++ b/collection/findLast.js @@ -11,8 +11,7 @@ var baseCallback = require('../internal/baseCallback'), * @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 a51ba5ae7..2d620655e 100644 --- a/collection/findWhere.js +++ b/collection/findWhere.js @@ -6,6 +6,11 @@ var baseMatches = require('../internal/baseMatches'), * 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 @@ var baseMatches = require('../internal/baseMatches'), * @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 2fb6ff777..2231c10e6 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 8717245d1..a9cbcda77 100644 --- a/collection/indexBy.js +++ b/collection/indexBy.js @@ -7,10 +7,14 @@ var createAggregator = require('../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 @@ var createAggregator = require('../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 f0b2da183..48e9f7a71 100644 --- a/collection/map.js +++ b/collection/map.js @@ -8,21 +8,34 @@ var arrayMap = require('../internal/arrayMap'), * `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 @@ var arrayMap = require('../internal/arrayMap'), * { '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 5e7983e5d..60a29a4c1 100644 --- a/collection/max.js +++ b/collection/max.js @@ -8,10 +8,14 @@ var arrayMax = require('../internal/arrayMax'), * 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 @@ var arrayMax = require('../internal/arrayMax'), * @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 @@ var arrayMax = require('../internal/arrayMax'), * _.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 940b4b16d..f96cb612a 100644 --- a/collection/min.js +++ b/collection/min.js @@ -8,10 +8,14 @@ var arrayMin = require('../internal/arrayMin'), * 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 @@ var arrayMin = require('../internal/arrayMin'), * @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 @@ var arrayMin = require('../internal/arrayMin'), * _.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 508ff7132..fd4e3677f 100644 --- a/collection/partition.js +++ b/collection/partition.js @@ -6,10 +6,14 @@ var createAggregator = require('../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 @@ var createAggregator = require('../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 @@ var createAggregator = require('../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 bb64092f1..af85d5a9a 100644 --- a/collection/pluck.js +++ b/collection/pluck.js @@ -25,7 +25,7 @@ var baseProperty = require('../internal/baseProperty'), * // => [36, 40] (iteration order is not guaranteed) */ function pluck(collection, key) { - return map(collection, baseProperty(key + '')); + return map(collection, baseProperty(key)); } module.exports = pluck; diff --git a/collection/reduce.js b/collection/reduce.js index 66304c8c3..0ddf678e6 100644 --- a/collection/reduce.js +++ b/collection/reduce.js @@ -12,6 +12,12 @@ var arrayReduce = require('../internal/arrayReduce'), * 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 a129ddcba..e2e894e9c 100644 --- a/collection/reject.js +++ b/collection/reject.js @@ -7,10 +7,14 @@ var arrayFilter = require('../internal/arrayFilter'), * 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 @@ var arrayFilter = require('../internal/arrayFilter'), * @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 @@ var arrayFilter = require('../internal/arrayFilter'), * { '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 84a615423..56458b8b3 100644 --- a/collection/some.js +++ b/collection/some.js @@ -9,10 +9,14 @@ var arraySome = require('../internal/arraySome'), * 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 @@ var arraySome = require('../internal/arraySome'), * @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 @@ var arraySome = require('../internal/arraySome'), * // => 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 b2f1d0907..321e52b57 100644 --- a/collection/sortBy.js +++ b/collection/sortBy.js @@ -12,10 +12,14 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * @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 @@ var baseCallback = require('../internal/baseCallback'), * { '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 01c504bf1..19fe32eb2 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 a00fc220f..f603bf8ce 100644 --- a/collection/where.js +++ b/collection/where.js @@ -6,6 +6,11 @@ var baseMatches = require('../internal/baseMatches'), * 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 @@ var baseMatches = require('../internal/baseMatches'), * @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 c78afa333..33ccefc3a 100644 --- a/function.js +++ b/function.js @@ -20,6 +20,7 @@ module.exports = { 'partial': require('./function/partial'), 'partialRight': require('./function/partialRight'), 'rearg': require('./function/rearg'), + 'spread': require('./function/spread'), 'throttle': require('./function/throttle'), 'wrap': require('./function/wrap') }; diff --git a/function/after.js b/function/after.js index a0a221e21..e6a5de407 100644 --- a/function/after.js +++ b/function/after.js @@ -1,5 +1,3 @@ -var isFunction = require('../lang/isFunction'); - /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; @@ -30,8 +28,8 @@ var nativeIsFinite = global.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 c305e9988..0ae3f972f 100644 --- a/function/before.js +++ b/function/before.js @@ -1,5 +1,3 @@ -var isFunction = require('../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 62c2ba01e..28cfcff09 100644 --- a/function/debounce.js +++ b/function/debounce.js @@ -1,5 +1,4 @@ -var isFunction = require('../lang/isFunction'), - isObject = require('../lang/isObject'), +var isObject = require('../lang/isObject'), now = require('../date/now'); /** Used as the `TypeError` message for "Functions" methods. */ @@ -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 1358a8d6e..5d2fd7f00 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 f85fd75e1..adeafaf2e 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 2cbebd0f8..10741afd0 100644 --- a/function/memoize.js +++ b/function/memoize.js @@ -1,5 +1,4 @@ -var MapCache = require('../internal/MapCache'), - isFunction = require('../lang/isFunction'); +var MapCache = require('../internal/MapCache'); /** 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 40b94b156..82479390a 100644 --- a/function/negate.js +++ b/function/negate.js @@ -1,5 +1,3 @@ -var isFunction = require('../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 608ac234f..90c0ae9ab 100644 --- a/function/once.js +++ b/function/once.js @@ -7,7 +7,6 @@ var before = require('./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..a14d72a64 --- /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); + }; +} + +module.exports = spread; diff --git a/function/throttle.js b/function/throttle.js index a877ac108..57ce634f4 100644 --- a/function/throttle.js +++ b/function/throttle.js @@ -1,5 +1,4 @@ var debounce = require('./debounce'), - isFunction = require('../lang/isFunction'), isObject = require('../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/index.js b/index.js index 020c5575b..8f556b7b1 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ /** * @license - * lodash 3.1.0 (Custom Build) + * lodash 3.2.0 (Custom Build) * Build: `lodash modern -d -o ./index.js` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.7.0 @@ -13,7 +13,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '3.1.0'; + var VERSION = '3.2.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -728,7 +728,6 @@ setTimeout = context.setTimeout, splice = arrayProto.splice, Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array, - unshift = arrayProto.unshift, WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap; /** Used to clone array buffers. */ @@ -780,7 +779,7 @@ /*------------------------------------------------------------------------*/ /** - * 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 @@ -799,29 +798,31 @@ * `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`, @@ -836,14 +837,14 @@ * `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]); @@ -862,12 +863,12 @@ * // => 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); @@ -882,9 +883,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; } /** @@ -1017,14 +1018,14 @@ * @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; } /** @@ -1036,18 +1037,18 @@ * @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; } @@ -1060,13 +1061,13 @@ * @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; } @@ -1080,20 +1081,20 @@ * @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 = []; @@ -1538,7 +1539,7 @@ return baseCopy(source, object, props); } var index = -1, - length = props.length + length = props.length; while (++index < length) { var key = props[index], @@ -1645,10 +1646,12 @@ 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); } /** @@ -1749,7 +1752,7 @@ * @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); @@ -1869,6 +1872,36 @@ return result; } + /** + * 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; + } + /** * The base implementation of `_.filter` without support for callback * shorthands or `this` binding. @@ -2201,7 +2234,7 @@ * 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. @@ -2263,8 +2296,7 @@ } /** - * 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. @@ -2280,7 +2312,7 @@ 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); }; } } @@ -2297,6 +2329,26 @@ }; } + /** + * 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); + }; + } + /** * The base implementation of `_.merge` without support for argument juggling, * multiple sources, and `this` binding `customizer` functions. @@ -2459,7 +2511,7 @@ eachFunc(collection, function(value, index, collection) { accumulator = initFromCollection ? (initFromCollection = false, value) - : iteratee(accumulator, value, index, collection) + : iteratee(accumulator, value, index, collection); }); return accumulator; } @@ -2835,8 +2887,7 @@ /** * Creates a function that aggregates a collection, creating an accumulator * object composed from the results of running each element in the collection - * through an iteratee. 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. @@ -3173,7 +3224,7 @@ */ 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; @@ -3203,9 +3254,9 @@ 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); @@ -3893,6 +3944,19 @@ return isObject(value) ? value : Object(value); } + /** + * 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__)); + } + /*------------------------------------------------------------------------*/ /** @@ -3904,7 +3968,7 @@ * @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 @@ -3999,7 +4063,6 @@ * * @static * @memberOf _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. @@ -4035,7 +4098,6 @@ * * @static * @memberOf _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. @@ -4072,20 +4134,23 @@ * 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 @@ -4094,18 +4159,22 @@ * // => [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; @@ -4122,20 +4191,23 @@ * 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 @@ -4144,18 +4216,22 @@ * // => [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; @@ -4168,14 +4244,45 @@ return baseSlice(array, index); } + /** + * 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); + } + /** * 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`. * @@ -4184,28 +4291,31 @@ * @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, @@ -4224,10 +4334,14 @@ * 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`. * @@ -4236,26 +4350,29 @@ * @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 */ @@ -4607,10 +4724,14 @@ * 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`. * @@ -4621,8 +4742,7 @@ * @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 @@ -4704,10 +4824,14 @@ * 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`. * @@ -4717,8 +4841,7 @@ * @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`. @@ -4738,7 +4861,7 @@ * }, dict); * // => 1 * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); * // => 1 */ @@ -4760,8 +4883,7 @@ * @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`. @@ -4782,7 +4904,6 @@ * * @static * @memberOf _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. @@ -4818,7 +4939,6 @@ * * @static * @memberOf _ - * @type Function * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. @@ -4855,20 +4975,23 @@ * 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 @@ -4877,18 +5000,22 @@ * // => [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; @@ -4905,20 +5032,23 @@ * 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 @@ -4927,18 +5057,22 @@ * // => [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; @@ -4982,10 +5116,14 @@ * 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`. * @@ -5001,8 +5139,6 @@ * @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 @@ -5018,7 +5154,7 @@ * _.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 }] */ @@ -5199,7 +5335,7 @@ * @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 = [ @@ -5275,7 +5411,7 @@ * @name chain * @memberOf _ * @category Chain - * @returns {*} Returns the `lodash` object. + * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var users = [ @@ -5298,6 +5434,76 @@ return chain(this); } + /** + * 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__); + } + + /** + * 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; + } + /** * Reverses the wrapped array so the first element becomes the last, the * second element becomes the second to last, and so on. @@ -5307,7 +5513,7 @@ * @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]; @@ -5324,7 +5530,7 @@ 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(); @@ -5352,7 +5558,7 @@ * * @name value * @memberOf _ - * @alias toJSON, valueOf + * @alias run, toJSON, valueOf * @category Chain * @returns {*} Returns the resolved unwrapped value. * @example @@ -5452,10 +5658,14 @@ * 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`. * @@ -5464,8 +5674,7 @@ * @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 @@ -5488,10 +5697,14 @@ * 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`. * @@ -5501,27 +5714,30 @@ * @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) { @@ -5537,10 +5753,14 @@ * `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`. * @@ -5550,8 +5770,7 @@ * @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 @@ -5560,16 +5779,20 @@ * // => [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) { @@ -5583,10 +5806,14 @@ * `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`. * @@ -5596,28 +5823,31 @@ * @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)) { @@ -5637,8 +5867,7 @@ * @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 @@ -5656,6 +5885,11 @@ * 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 @@ -5665,14 +5899,14 @@ * @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) { @@ -5741,10 +5975,14 @@ * 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`. * @@ -5753,8 +5991,7 @@ * @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 @@ -5765,7 +6002,7 @@ * _.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'] } */ @@ -5784,10 +6021,14 @@ * 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`. * @@ -5796,8 +6037,7 @@ * @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 @@ -5851,21 +6091,34 @@ * `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 @@ -5881,7 +6134,7 @@ * { 'user': 'fred' } * ]; * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.map(users, 'user'); * // => ['barney', 'fred'] */ @@ -5898,10 +6151,14 @@ * 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`. * @@ -5910,8 +6167,6 @@ * @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 @@ -5930,7 +6185,7 @@ * _.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 }; */ @@ -5943,10 +6198,14 @@ * 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`. * @@ -5955,8 +6214,6 @@ * @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 @@ -5975,7 +6232,7 @@ * _.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 }; */ @@ -5987,10 +6244,14 @@ * 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`. * @@ -5999,8 +6260,7 @@ * @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 @@ -6017,12 +6277,18 @@ * { '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) { @@ -6053,7 +6319,7 @@ * // => [36, 40] (iteration order is not guaranteed) */ function pluck(collection, key) { - return map(collection, baseProperty(key + '')); + return map(collection, baseProperty(key)); } /** @@ -6064,6 +6330,12 @@ * 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 @@ -6117,10 +6389,14 @@ * 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`. * @@ -6129,8 +6405,7 @@ * @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 @@ -6143,13 +6418,17 @@ * { '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; @@ -6251,10 +6530,14 @@ * 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`. * @@ -6264,8 +6547,7 @@ * @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`. @@ -6275,17 +6557,21 @@ * // => 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; @@ -6302,10 +6588,14 @@ * 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`. * @@ -6315,7 +6605,7 @@ * @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 @@ -6332,7 +6622,7 @@ * { 'user': 'barney' } * ]; * - * // using the "_.property" callback shorthand + * // using the `_.property` callback shorthand * _.pluck(_.sortBy(users, 'user'), 'user'); * // => ['barney', 'fred', 'pebbles'] */ @@ -6384,7 +6674,7 @@ 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); @@ -6401,6 +6691,11 @@ * 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 @@ -6410,18 +6705,15 @@ * @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)); @@ -6471,8 +6763,8 @@ * // => 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; @@ -6530,8 +6822,8 @@ */ 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; @@ -6853,7 +7145,7 @@ maxWait = false, trailing = true; - if (!isFunction(func)) { + if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = wait < 0 ? 0 : wait; @@ -7023,7 +7315,7 @@ length = funcs.length; if (!length) { - return function() {}; + return function() { return arguments[0]; }; } if (!arrayEvery(funcs, isFunction)) { throw new TypeError(FUNC_ERROR_TEXT); @@ -7068,7 +7360,7 @@ fromIndex = funcs.length - 1; if (fromIndex < 0) { - return function() {}; + return function() { return arguments[0]; }; } if (!arrayEvery(funcs, isFunction)) { throw new TypeError(FUNC_ERROR_TEXT); @@ -7138,7 +7430,7 @@ * // => { '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() { @@ -7176,7 +7468,7 @@ * // => [1, 3, 5] */ function negate(predicate) { - if (!isFunction(predicate)) { + if (typeof predicate != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } return function() { @@ -7191,7 +7483,6 @@ * * @static * @memberOf _ - * @type Function * @category Function * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. @@ -7314,6 +7605,45 @@ return createWrapper(func, REARG_FLAG, null, null, null, indexes); } + /** + * 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); + }; + } + /** * Creates a function that only invokes `func` at most once per every `wait` * milliseconds. The created function comes with a `cancel` method to cancel @@ -7356,7 +7686,7 @@ var leading = true, trailing = true; - if (!isFunction(func)) { + if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } if (options === false) { @@ -7662,7 +7992,8 @@ * 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. * @@ -7832,7 +8163,7 @@ * @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`. @@ -8258,10 +8589,14 @@ * 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`. * @@ -8270,8 +8605,7 @@ * @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 @@ -8285,11 +8619,15 @@ * _.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' */ @@ -8302,10 +8640,14 @@ * 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`. * @@ -8314,8 +8656,7 @@ * @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 @@ -8329,11 +8670,15 @@ * _.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' */ @@ -8620,7 +8965,7 @@ 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; @@ -8642,10 +8987,14 @@ * 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`. * @@ -8654,8 +9003,7 @@ * @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 @@ -8668,7 +9016,7 @@ * '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) */ @@ -8913,7 +9261,7 @@ if (isArr) { accumulator = isArray(object) ? new Ctor : []; } else { - accumulator = baseCreate(typeof Ctor == 'function' && Ctor.prototype); + accumulator = baseCreate(isFunction(Ctor) && Ctor.prototype); } } else { accumulator = {}; @@ -9743,7 +10091,7 @@ 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 + ''))); } @@ -9773,7 +10121,7 @@ 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); } @@ -9916,8 +10264,8 @@ /*------------------------------------------------------------------------*/ /** - * 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 _ @@ -9927,9 +10275,9 @@ * @example * * // avoid throwing errors for invalid selectors - * var elements = _.attempt(function() { + * var elements = _.attempt(function(selector) { * return document.querySelectorAll(selector); - * }); + * }, '>_>'); * * if (_.isError(elements)) { * elements = []; @@ -9937,17 +10285,18 @@ */ 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); } } /** - * 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 _ @@ -10031,6 +10380,11 @@ * 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 @@ -10039,22 +10393,46 @@ * @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)); } + /** + * 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)); + } + /** * Adds all own enumerable function properties of a source object to the * destination object. If `object` is a function then methods are added to @@ -10077,6 +10455,9 @@ * }); * } * + * // use `_.runInContext` to avoid potential conflicts (esp. in Node.js) + * var _ = require('lodash').runInContext(); + * * _.mixin({ 'vowels': vowels }); * _.vowels('fred'); * // => ['e'] @@ -10351,7 +10732,11 @@ /*------------------------------------------------------------------------*/ // Ensure `new LodashWrapper` is an instance of `lodash`. - LodashWrapper.prototype = lodash.prototype; + LodashWrapper.prototype = baseCreate(lodash.prototype); + + // Ensure `new LazyWraper` is an instance of `LodashWrapper` + LazyWrapper.prototype = baseCreate(LodashWrapper.prototype); + LazyWrapper.prototype.constructor = LazyWrapper; // Add functions to the `Map` cache. MapCache.prototype['delete'] = mapDelete; @@ -10392,6 +10777,7 @@ lodash.dropRight = dropRight; lodash.dropRightWhile = dropRightWhile; lodash.dropWhile = dropWhile; + lodash.fill = fill; lodash.filter = filter; lodash.flatten = flatten; lodash.flattenDeep = flattenDeep; @@ -10415,6 +10801,7 @@ lodash.map = map; lodash.mapValues = mapValues; lodash.matches = matches; + lodash.matchesProperty = matchesProperty; lodash.memoize = memoize; lodash.merge = merge; lodash.mixin = mixin; @@ -10440,6 +10827,7 @@ lodash.slice = slice; lodash.sortBy = sortBy; lodash.sortByAll = sortByAll; + lodash.spread = spread; lodash.take = take; lodash.takeRight = takeRight; lodash.takeRightWhile = takeRightWhile; @@ -10613,14 +11001,15 @@ // 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': getCallback(iteratee, thisArg, 3), 'type': index }); return result; }; @@ -10628,19 +11017,19 @@ // 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; }; @@ -10656,7 +11045,7 @@ // 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]; @@ -10678,27 +11067,26 @@ 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 = getCallback(iteratee, thisArg, 3); + LazyWrapper.prototype.dropWhile = function(predicate, thisArg) { + var done; + predicate = getCallback(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 = getCallback(iteratee, thisArg, 3); + LazyWrapper.prototype.reject = function(predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); return this.filter(function(value, index, array) { - return !iteratee(value, index, array); + return !predicate(value, index, array); }); }; @@ -10713,6 +11101,10 @@ 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], @@ -10740,8 +11132,8 @@ 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); @@ -10774,9 +11166,11 @@ // Add chaining functions to the lodash wrapper. lodash.prototype.chain = wrapperChain; + lodash.prototype.commit = wrapperCommit; + lodash.prototype.plant = wrapperPlant; lodash.prototype.reverse = wrapperReverse; lodash.prototype.toString = wrapperToString; - lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; + lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; // Add function aliases to the lodash wrapper. lodash.prototype.collect = lodash.prototype.map; diff --git a/internal/LazyWrapper.js b/internal/LazyWrapper.js index f25d12728..b0374b4bb 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; } module.exports = LazyWrapper; diff --git a/internal/LodashWrapper.js b/internal/LodashWrapper.js index 74bfe341e..faedb1aea 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; } module.exports = LodashWrapper; diff --git a/internal/baseAssign.js b/internal/baseAssign.js index 6c9ec8d6b..3626c2e30 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 8543fc9a3..684d67dcd 100644 --- a/internal/baseCallback.js +++ b/internal/baseCallback.js @@ -1,4 +1,5 @@ var baseMatches = require('./baseMatches'), + baseMatchesProperty = require('./baseMatchesProperty'), baseProperty = require('./baseProperty'), bindCallback = require('./bindCallback'), identity = require('../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); } module.exports = baseCallback; diff --git a/internal/baseDelay.js b/internal/baseDelay.js index 083f19239..12fc5ffb5 100644 --- a/internal/baseDelay.js +++ b/internal/baseDelay.js @@ -1,5 +1,4 @@ -var baseSlice = require('./baseSlice'), - isFunction = require('../lang/isFunction'); +var baseSlice = require('./baseSlice'); /** 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..3b90582ff --- /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; +} + +module.exports = baseFill; diff --git a/internal/baseIsMatch.js b/internal/baseIsMatch.js index 995d67e3d..8409e1fba 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 b36c995a7..cc9b62f58 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..49e31e6ee --- /dev/null +++ b/internal/baseMatchesProperty.js @@ -0,0 +1,24 @@ +var baseIsEqual = require('./baseIsEqual'), + isStrictComparable = require('./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); + }; +} + +module.exports = baseMatchesProperty; diff --git a/internal/baseReduce.js b/internal/baseReduce.js index c38c7da42..73229277e 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 ceb1c51b9..d277cc997 100644 --- a/internal/createAggregator.js +++ b/internal/createAggregator.js @@ -5,8 +5,7 @@ var baseCallback = require('./baseCallback'), /** * 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 3da8991c4..f0dc3fd79 100644 --- a/internal/createWrapper.js +++ b/internal/createWrapper.js @@ -3,7 +3,6 @@ var baseSetData = require('./baseSetData'), createHybridWrapper = require('./createHybridWrapper'), createPartialWrapper = require('./createPartialWrapper'), getData = require('./getData'), - isFunction = require('../lang/isFunction'), mergeData = require('./mergeData'), setData = require('./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 b6528a394..cccfa7136 100644 --- a/internal/lazyClone.js +++ b/internal/lazyClone.js @@ -10,18 +10,18 @@ var LazyWrapper = require('./LazyWrapper'), * @returns {Object} Returns the cloned `LazyWrapper` object. */ function lazyClone() { - var actions = this.actions, - iteratees = this.iteratees, - views = this.views, - result = new LazyWrapper(this.wrapped); + 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 95481d2d9..c658402f9 100644 --- a/internal/lazyReverse.js +++ b/internal/lazyReverse.js @@ -9,13 +9,13 @@ var LazyWrapper = require('./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 fb1a15b4e..5bbbdeeff 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..e5e10dac6 --- /dev/null +++ b/internal/wrapperClone.js @@ -0,0 +1,18 @@ +var LazyWrapper = require('./LazyWrapper'), + LodashWrapper = require('./LodashWrapper'), + arrayCopy = require('./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__)); +} + +module.exports = wrapperClone; diff --git a/lang/isEqual.js b/lang/isEqual.js index f98513038..b8c0f3c7e 100644 --- a/lang/isEqual.js +++ b/lang/isEqual.js @@ -10,7 +10,8 @@ var baseIsEqual = require('../internal/baseIsEqual'), * 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 fc0dbfa87..bc3eefae0 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/object/findKey.js b/object/findKey.js index 14cbc285f..4aea35a7a 100644 --- a/object/findKey.js +++ b/object/findKey.js @@ -6,10 +6,14 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * @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 @@ var baseCallback = require('../internal/baseCallback'), * _.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 c4383f67e..37063afd5 100644 --- a/object/findLastKey.js +++ b/object/findLastKey.js @@ -6,10 +6,14 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * @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 @@ var baseCallback = require('../internal/baseCallback'), * _.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 f4fa6d2a7..5a88e12ca 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 502eeec1a..b7e1e5c93 100644 --- a/object/mapValues.js +++ b/object/mapValues.js @@ -7,10 +7,14 @@ var baseCallback = require('../internal/baseCallback'), * 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 @@ var baseCallback = require('../internal/baseCallback'), * @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 @@ var baseCallback = require('../internal/baseCallback'), * '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 03a567472..c31b8f05f 100644 --- a/object/transform.js +++ b/object/transform.js @@ -3,6 +3,7 @@ var arrayEach = require('../internal/arrayEach'), baseCreate = require('../internal/baseCreate'), baseForOwn = require('../internal/baseForOwn'), isArray = require('../lang/isArray'), + isFunction = require('../lang/isFunction'), isObject = require('../lang/isObject'), isTypedArray = require('../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 2bb8a945a..e009e2b36 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash", - "version": "3.1.0", + "version": "3.2.0", "description": "The modern build of lodash modular utilities.", "homepage": "https://lodash.com/", "icon": "https://lodash.com/icon.svg", diff --git a/string/trimLeft.js b/string/trimLeft.js index 9ce7651ea..29299677a 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 cc93346ab..0f9be71fb 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 a2c035228..062c92ebd 100644 --- a/utility.js +++ b/utility.js @@ -5,6 +5,7 @@ module.exports = { 'identity': require('./utility/identity'), 'iteratee': require('./utility/iteratee'), 'matches': require('./utility/matches'), + 'matchesProperty': require('./utility/matchesProperty'), 'mixin': require('./utility/mixin'), 'noop': require('./utility/noop'), 'property': require('./utility/property'), diff --git a/utility/attempt.js b/utility/attempt.js index 1ba6737d1..997a930bb 100644 --- a/utility/attempt.js +++ b/utility/attempt.js @@ -1,8 +1,9 @@ -var isError = require('../lang/isError'); +var baseSlice = require('../internal/baseSlice'), + isError = require('../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 @@ var isError = require('../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 @@ var isError = require('../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 e7b804708..756ccbea0 100644 --- a/utility/callback.js +++ b/utility/callback.js @@ -4,10 +4,11 @@ var baseCallback = require('../internal/baseCallback'), matches = require('./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 78cbbd4f0..6b14143db 100644 --- a/utility/matches.js +++ b/utility/matches.js @@ -6,6 +6,11 @@ var baseClone = require('../internal/baseClone'), * 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 @@ var baseClone = require('../internal/baseClone'), * @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..6e5675593 --- /dev/null +++ b/utility/matchesProperty.js @@ -0,0 +1,33 @@ +var baseClone = require('../internal/baseClone'), + baseMatchesProperty = require('../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)); +} + +module.exports = matchesProperty; diff --git a/utility/mixin.js b/utility/mixin.js index d7d56daea..09b578970 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']