diff --git a/dist/lodash.compat.js b/dist/lodash.compat.js
index 0b76e46f7..abd4f3908 100644
--- a/dist/lodash.compat.js
+++ b/dist/lodash.compat.js
@@ -1407,6 +1407,19 @@
});
}
+ /**
+ * The base implementation of `_.random` without argument juggling or support
+ * for ruturning floating-point numbers.
+ *
+ * @private
+ * @param {number} min The minimum possible value.
+ * @param {number} max The maximum possible value.
+ * @returns {number} Returns a random number.
+ */
+ function baseRandom(min, max) {
+ return min + floor(nativeRandom() * (max - min + 1));
+ }
+
/**
* The base implementation of `_.uniq` without support for callback shorthands
* or `thisArg` binding.
@@ -1943,16 +1956,16 @@
* @returns {Object} Returns the destination object.
* @example
*
- * _.assign({ 'name': 'moe' }, { 'age': 40 });
- * // => { 'name': 'moe', 'age': 40 }
+ * _.assign({ 'name': 'fred' }, { 'age': 40 });
+ * // => { 'name': 'fred', 'age': 40 }
*
* var defaults = _.partialRight(_.assign, function(a, b) {
* return typeof a == 'undefined' ? b : a;
* });
*
- * var food = { 'name': 'apple' };
- * defaults(food, { 'name': 'banana', 'type': 'fruit' });
- * // => { 'name': 'apple', 'type': 'fruit' }
+ * var person = { 'name': 'barney' };
+ * defaults(person, { 'name': 'fred', 'employer': 'slate' });
+ * // => { 'name': 'barney', 'employer': 'slate' }
*/
var assign = createIterator(defaultsIteratorOptions, {
'top':
@@ -1984,17 +1997,17 @@
* @returns {*} Returns the cloned value.
* @example
*
- * var stooges = [
- * { 'name': 'moe', 'age': 40 },
- * { 'name': 'larry', 'age': 50 }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36 },
+ * { 'name': 'fred', 'age': 40 }
* ];
*
- * var shallow = _.clone(stooges);
- * shallow[0] === stooges[0];
+ * var shallow = _.clone(characters);
+ * shallow[0] === characters[0];
* // => true
*
- * var deep = _.clone(stooges, true);
- * deep[0] === stooges[0];
+ * var deep = _.clone(characters, true);
+ * deep[0] === characters[0];
* // => false
*
* _.mixin({
@@ -2038,13 +2051,13 @@
* @returns {*} Returns the deep cloned value.
* @example
*
- * var stooges = [
- * { 'name': 'moe', 'age': 40 },
- * { 'name': 'larry', 'age': 50 }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36 },
+ * { 'name': 'fred', 'age': 40 }
* ];
*
- * var deep = _.cloneDeep(stooges);
- * deep[0] === stooges[0];
+ * var deep = _.cloneDeep(characters);
+ * deep[0] === characters[0];
* // => false
*
* var view = {
@@ -2079,9 +2092,9 @@
* @returns {Object} Returns the destination object.
* @example
*
- * var food = { 'name': 'apple' };
- * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
- * // => { 'name': 'apple', 'type': 'fruit' }
+ * var person = { 'name': 'barney' };
+ * _.defaults(person, { 'name': 'fred', 'employer': 'slate' });
+ * // => { 'name': 'barney', 'employer': 'slate' }
*/
var defaults = createIterator(defaultsIteratorOptions);
@@ -2089,6 +2102,13 @@
* This method is like `_.findIndex` except that it returns the key of the
* first element that passes the callback check, instead of the element itself.
*
+ * If a property name is provided for `callback` the created "_.pluck" style
+ * callback will return the property value of the given element.
+ *
+ * If an object is provided for `callback` the created "_.where" style callback
+ * will return `true` for elements that have the properties of the given object,
+ * else `false`.
+ *
* @static
* @memberOf _
* @category Objects
@@ -2100,10 +2120,24 @@
* @returns {string|undefined} Returns the key of the found element, else `undefined`.
* @example
*
- * _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
- * return num % 2 == 0;
+ * var characters = {
+ * 'barney': { 'age': 36, 'blocked': false },
+ * 'fred': { 'age': 40, 'blocked': true },
+ * 'pebbles': { 'age': 1, 'blocked': false }
+ * };
+ *
+ * _.findKey(characters, function(chr) {
+ * return chr.age < 40;
* });
- * // => 'b' (property order is not guaranteed across environments)
+ * // => 'barney' (property order is not guaranteed across environments)
+ *
+ * // using "_.where" callback shorthand
+ * _.findKey(characters, { 'age': 1 });
+ * // => 'pebbles'
+ *
+ * // using "_.pluck" callback shorthand
+ * _.findKey(characters, 'blocked');
+ * // => 'fred'
*/
function findKey(object, callback, thisArg) {
var result;
@@ -2121,6 +2155,13 @@
* 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 `callback` the created "_.pluck" style
+ * callback will return the property value of the given element.
+ *
+ * If an object is provided for `callback` the created "_.where" style callback
+ * will return `true` for elements that have the properties of the given object,
+ * else `false`.
+ *
* @static
* @memberOf _
* @category Objects
@@ -2132,10 +2173,24 @@
* @returns {string|undefined} Returns the key of the found element, else `undefined`.
* @example
*
- * _.findLastKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
- * return num % 2 == 1;
+ * var characters = {
+ * 'barney': { 'age': 36, 'blocked': true },
+ * 'fred': { 'age': 40, 'blocked': false },
+ * 'pebbles': { 'age': 1, 'blocked': true }
+ * };
+ *
+ * _.findLastKey(characters, function(chr) {
+ * return chr.age < 40;
* });
- * // => returns `c`, assuming `_.findKey` returns `a`
+ * // => returns `pebbles`, assuming `_.findKey` returns `barney`
+ *
+ * // using "_.where" callback shorthand
+ * _.findLastKey(characters, { 'age': 40 });
+ * // => 'fred'
+ *
+ * // using "_.pluck" callback shorthand
+ * _.findLastKey(characters, 'blocked');
+ * // => 'pebbles'
*/
function findLastKey(object, callback, thisArg) {
var result;
@@ -2334,8 +2389,8 @@
* @returns {Object} Returns the created inverted object.
* @example
*
- * _.invert({ 'first': 'moe', 'second': 'larry' });
- * // => { 'moe': 'first', 'larry': 'second' }
+ * _.invert({ 'first': 'fred', 'second': 'barney' });
+ * // => { 'fred': 'first', 'barney': 'second' }
*/
function invert(object) {
var index = -1,
@@ -2458,13 +2513,13 @@
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
- * var moe = { 'name': 'moe', 'age': 40 };
- * var copy = { 'name': 'moe', 'age': 40 };
+ * var fred = { 'name': 'fred', 'age': 40 };
+ * var copy = { 'name': 'fred', 'age': 40 };
*
- * moe == copy;
+ * fred == copy;
* // => false
*
- * _.isEqual(moe, copy);
+ * _.isEqual(fred, copy);
* // => true
*
* var words = ['hello', 'goodbye'];
@@ -2646,18 +2701,18 @@
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
- * function Stooge(name, age) {
+ * function Person(name, age) {
* this.name = name;
* this.age = age;
* }
*
- * _.isPlainObject(new Stooge('moe', 40));
+ * _.isPlainObject(new Person('fred', 40));
* // => false
*
* _.isPlainObject([1, 2, 3]);
* // => false
*
- * _.isPlainObject({ 'name': 'moe', 'age': 40 });
+ * _.isPlainObject({ 'name': 'fred', 'age': 40 });
* // => true
*/
var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
@@ -2682,7 +2737,7 @@
* @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
* @example
*
- * _.isRegExp(/moe/);
+ * _.isRegExp(/fred/);
* // => true
*/
function isRegExp(value) {
@@ -2699,7 +2754,7 @@
* @returns {boolean} Returns `true` if the `value` is a string, else `false`.
* @example
*
- * _.isString('moe');
+ * _.isString('fred');
* // => true
*/
function isString(value) {
@@ -2743,21 +2798,21 @@
* @example
*
* var names = {
- * 'stooges': [
- * { 'name': 'moe' },
- * { 'name': 'larry' }
+ * 'characters': [
+ * { 'name': 'barney' },
+ * { 'name': 'fred' }
* ]
* };
*
* var ages = {
- * 'stooges': [
- * { 'age': 40 },
- * { 'age': 50 }
+ * 'characters': [
+ * { 'age': 36 },
+ * { 'age': 40 }
* ]
* };
*
* _.merge(names, ages);
- * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
+ * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
*
* var food = {
* 'fruits': ['apple'],
@@ -2822,13 +2877,13 @@
* @returns {Object} Returns an object without the omitted properties.
* @example
*
- * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
- * // => { 'name': 'moe' }
+ * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
+ * // => { 'name': 'fred' }
*
- * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
+ * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
* return typeof value == 'number';
* });
- * // => { 'name': 'moe' }
+ * // => { 'name': 'fred' }
*/
function omit(object, callback, thisArg) {
var indexOf = getIndexOf(),
@@ -2862,8 +2917,8 @@
* @returns {Array} Returns new array of key-value pairs.
* @example
*
- * _.pairs({ 'moe': 30, 'larry': 40 });
- * // => [['moe', 30], ['larry', 40]] (property order is not guaranteed across environments)
+ * _.pairs({ 'barney': 36, 'fred': 40 });
+ * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
*/
function pairs(object) {
var index = -1,
@@ -2897,13 +2952,13 @@
* @returns {Object} Returns an object composed of the picked properties.
* @example
*
- * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
- * // => { 'name': 'moe' }
+ * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
+ * // => { 'name': 'fred' }
*
- * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
+ * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
* return key.charAt(0) != '_';
* });
- * // => { 'name': 'moe' }
+ * // => { 'name': 'fred' }
*/
function pick(object, callback, thisArg) {
var result = {};
@@ -3025,8 +3080,8 @@
* _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
* // => ['a', 'c', 'e']
*
- * _.at(['moe', 'larry', 'curly'], 0, 2);
- * // => ['moe', 'curly']
+ * _.at(['fred', 'barney', 'pebbles'], 0, 2);
+ * // => ['fred', 'pebbles']
*/
function at(collection) {
var args = arguments,
@@ -3065,10 +3120,10 @@
* _.contains([1, 2, 3], 1, 2);
* // => false
*
- * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
+ * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
* // => true
*
- * _.contains('curly', 'ur');
+ * _.contains('pebbles', 'ur');
* // => true
*/
function contains(collection, target, fromIndex) {
@@ -3155,20 +3210,20 @@
* else `false`.
* @example
*
- * _.every([true, 1, null, 'yes'], Boolean);
+ * _.every([true, 1, null, 'yes']);
* // => false
*
- * var stooges = [
- * { 'name': 'moe', 'age': 40 },
- * { 'name': 'larry', 'age': 50 }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36 },
+ * { 'name': 'fred', 'age': 40 }
* ];
*
* // using "_.pluck" callback shorthand
- * _.every(stooges, 'age');
+ * _.every(characters, 'age');
* // => true
*
* // using "_.where" callback shorthand
- * _.every(stooges, { 'age': 50 });
+ * _.every(characters, { 'age': 36 });
* // => false
*/
function every(collection, callback, thisArg) {
@@ -3219,18 +3274,18 @@
* var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
* // => [2, 4, 6]
*
- * var food = [
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
- * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
+ * { 'name': 'fred', 'age': 40, 'blocked': true }
* ];
*
* // using "_.pluck" callback shorthand
- * _.filter(food, 'organic');
- * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
+ * _.filter(characters, 'blocked');
+ * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
*
* // using "_.where" callback shorthand
- * _.filter(food, { 'type': 'fruit' });
- * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
+ * _.filter(characters, { 'age': 36 });
+ * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
*/
function filter(collection, callback, thisArg) {
var result = [];
@@ -3280,24 +3335,24 @@
* @returns {*} Returns the found element, else `undefined`.
* @example
*
- * _.find([1, 2, 3, 4], function(num) {
- * return num % 2 == 0;
- * });
- * // => 2
- *
- * var food = [
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
- * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
- * { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
+ * { 'name': 'fred', 'age': 40, 'blocked': true },
+ * { 'name': 'pebbles', 'age': 1, 'blocked': false }
* ];
*
+ * _.find(characters, function(chr) {
+ * return chr.age < 40;
+ * });
+ * // => { 'name': 'barney', 'age': 36, 'blocked': false }
+ *
* // using "_.where" callback shorthand
- * _.find(food, { 'type': 'vegetable' });
- * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
+ * _.find(characters, { 'age': 1 });
+ * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
*
* // using "_.pluck" callback shorthand
- * _.find(food, 'organic');
- * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
+ * _.find(characters, 'blocked');
+ * // => { 'name': 'fred', 'age': 40, 'blocked': true }
*/
function find(collection, callback, thisArg) {
callback = lodash.createCallback(callback, thisArg, 3);
@@ -3512,7 +3567,7 @@
* _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
*
- * _.indexBy(stooges, function(key) { this.fromCharCode(key.code); }, String);
+ * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
*/
var indexBy = createAggregator(function(result, value, key) {
@@ -3584,14 +3639,14 @@
* _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
* // => [3, 6, 9] (property order is not guaranteed across environments)
*
- * var stooges = [
- * { 'name': 'moe', 'age': 40 },
- * { 'name': 'larry', 'age': 50 }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36 },
+ * { 'name': 'fred', 'age': 40 }
* ];
*
* // using "_.pluck" callback shorthand
- * _.map(stooges, 'name');
- * // => ['moe', 'larry']
+ * _.map(characters, 'name');
+ * // => ['barney', 'fred']
*/
function map(collection, callback, thisArg) {
var index = -1,
@@ -3639,17 +3694,17 @@
* _.max([4, 2, 8, 6]);
* // => 8
*
- * var stooges = [
- * { 'name': 'moe', 'age': 40 },
- * { 'name': 'larry', 'age': 50 }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36 },
+ * { 'name': 'fred', 'age': 40 }
* ];
*
- * _.max(stooges, function(stooge) { return stooge.age; });
- * // => { 'name': 'larry', 'age': 50 };
+ * _.max(characters, function(chr) { return chr.age; });
+ * // => { 'name': 'fred', 'age': 40 };
*
* // using "_.pluck" callback shorthand
- * _.max(stooges, 'age');
- * // => { 'name': 'larry', 'age': 50 };
+ * _.max(characters, 'age');
+ * // => { 'name': 'fred', 'age': 40 };
*/
function max(collection, callback, thisArg) {
var computed = -Infinity,
@@ -3709,17 +3764,17 @@
* _.min([4, 2, 8, 6]);
* // => 2
*
- * var stooges = [
- * { 'name': 'moe', 'age': 40 },
- * { 'name': 'larry', 'age': 50 }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36 },
+ * { 'name': 'fred', 'age': 40 }
* ];
*
- * _.min(stooges, function(stooge) { return stooge.age; });
- * // => { 'name': 'moe', 'age': 40 };
+ * _.min(characters, function(chr) { return chr.age; });
+ * // => { 'name': 'barney', 'age': 36 };
*
* // using "_.pluck" callback shorthand
- * _.min(stooges, 'age');
- * // => { 'name': 'moe', 'age': 40 };
+ * _.min(characters, 'age');
+ * // => { 'name': 'barney', 'age': 36 };
*/
function min(collection, callback, thisArg) {
var computed = Infinity,
@@ -3752,7 +3807,7 @@
}
/**
- * Retrieves the value of a specified property from all elements in the `collection`.
+ * Retrieves the value of a specified property from all elements in the collection.
*
* @static
* @memberOf _
@@ -3763,13 +3818,13 @@
* @returns {Array} Returns a new array of property values.
* @example
*
- * var stooges = [
- * { 'name': 'moe', 'age': 40 },
- * { 'name': 'larry', 'age': 50 }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36 },
+ * { 'name': 'fred', 'age': 40 }
* ];
*
- * _.pluck(stooges, 'name');
- * // => ['moe', 'larry']
+ * _.pluck(characters, 'name');
+ * // => ['barney', 'fred']
*/
var pluck = map;
@@ -3882,18 +3937,18 @@
* var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
* // => [1, 3, 5]
*
- * var food = [
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
- * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
+ * { 'name': 'fred', 'age': 40, 'blocked': true }
* ];
*
* // using "_.pluck" callback shorthand
- * _.reject(food, 'organic');
- * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
+ * _.reject(characters, 'blocked');
+ * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
*
* // using "_.where" callback shorthand
- * _.reject(food, { 'type': 'fruit' });
- * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
+ * _.reject(characters, { 'age': 36 });
+ * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
*/
function reject(collection, callback, thisArg) {
callback = lodash.createCallback(callback, thisArg, 3);
@@ -3922,14 +3977,13 @@
* // => [3, 1]
*/
function sample(collection, n, guard) {
- var length = collection ? collection.length : 0;
- if (typeof length != 'number') {
+ if (collection && typeof collection.length != 'number') {
collection = values(collection);
} else if (support.unindexedChars && isString(collection)) {
collection = collection.split('');
}
if (n == null || guard) {
- return collection ? collection[random(length - 1)] : undefined;
+ return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
}
var result = shuffle(collection);
result.length = nativeMin(nativeMax(0, n), result.length);
@@ -3956,7 +4010,7 @@
result = Array(typeof length == 'number' ? length : 0);
forEach(collection, function(value) {
- var rand = random(++index);
+ var rand = baseRandom(0, ++index);
result[index] = result[rand];
result[rand] = value;
});
@@ -3980,7 +4034,7 @@
* _.size({ 'one': 1, 'two': 2, 'three': 3 });
* // => 3
*
- * _.size('curly');
+ * _.size('pebbles');
* // => 5
*/
function size(collection) {
@@ -4017,17 +4071,17 @@
* _.some([null, 0, 'yes', false], Boolean);
* // => true
*
- * var food = [
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
- * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
+ * { 'name': 'fred', 'age': 40, 'blocked': true }
* ];
*
* // using "_.pluck" callback shorthand
- * _.some(food, 'organic');
+ * _.some(characters, 'blocked');
* // => true
*
* // using "_.where" callback shorthand
- * _.some(food, { 'type': 'meat' });
+ * _.some(characters, { 'age': 1 });
* // => false
*/
function some(collection, callback, thisArg) {
@@ -4145,16 +4199,16 @@
* @returns {Array} Returns a new array of elements that have the given properties.
* @example
*
- * var stooges = [
- * { 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
- * { 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
+ * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
* ];
*
- * _.where(stooges, { 'age': 40 });
- * // => [{ 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }]
+ * _.where(characters, { 'age': 36 });
+ * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
*
- * _.where(stooges, { 'quotes': ['Poifect!'] });
- * // => [{ 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }]
+ * _.where(characters, { 'pets': ['dino'] });
+ * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
*/
var where = filter;
@@ -4237,6 +4291,13 @@
* This method is like `_.find` except that it returns the index of the first
* element that passes the callback check, instead of the element itself.
*
+ * If a property name is provided for `callback` the created "_.pluck" style
+ * callback will return the property value of the given element.
+ *
+ * If an object is provided for `callback` the created "_.where" style callback
+ * will return `true` for elements that have the properties of the given object,
+ * else `false`.
+ *
* @static
* @memberOf _
* @category Arrays
@@ -4248,9 +4309,23 @@
* @returns {number} Returns the index of the found element, else `-1`.
* @example
*
- * _.findIndex(['apple', 'banana', 'beet'], function(food) {
- * return /^b/.test(food);
+ * var characters = [
+ * { 'name': 'barney', 'age': 36, 'blocked': false },
+ * { 'name': 'fred', 'age': 40, 'blocked': true },
+ * { 'name': 'pebbles', 'age': 1, 'blocked': false }
+ * ];
+ *
+ * _.findIndex(characters, function(chr) {
+ * return chr.age < 20;
* });
+ * // => 2
+ *
+ * // using "_.where" callback shorthand
+ * _.findIndex(characters, { 'age': 36 });
+ * // => 0
+ *
+ * // using "_.pluck" callback shorthand
+ * _.findIndex(characters, 'blocked');
* // => 1
*/
function findIndex(array, callback, thisArg) {
@@ -4270,6 +4345,13 @@
* This method is like `_.findIndex` except that it iterates over elements
* of a `collection` from right to left.
*
+ * If a property name is provided for `callback` the created "_.pluck" style
+ * callback will return the property value of the given element.
+ *
+ * If an object is provided for `callback` the created "_.where" style callback
+ * will return `true` for elements that have the properties of the given object,
+ * else `false`.
+ *
* @static
* @memberOf _
* @category Arrays
@@ -4281,9 +4363,23 @@
* @returns {number} Returns the index of the found element, else `-1`.
* @example
*
- * _.findLastIndex(['apple', 'banana', 'beet'], function(food) {
- * return /^b/.test(food);
+ * var characters = [
+ * { 'name': 'barney', 'age': 36, 'blocked': true },
+ * { 'name': 'fred', 'age': 40, 'blocked': false },
+ * { 'name': 'pebbles', 'age': 1, 'blocked': true }
+ * ];
+ *
+ * _.findLastIndex(characters, function(chr) {
+ * return chr.age > 30;
* });
+ * // => 1
+ *
+ * // using "_.where" callback shorthand
+ * _.findLastIndex(characters, { 'age': 36 });
+ * // => 0
+ *
+ * // using "_.pluck" callback shorthand
+ * _.findLastIndex(characters, 'blocked');
* // => 2
*/
function findLastIndex(array, callback, thisArg) {
@@ -4334,24 +4430,19 @@
* });
* // => [1, 2]
*
- * var food = [
- * { 'name': 'banana', 'organic': true },
- * { 'name': 'beet', 'organic': false },
+ * var characters = [
+ * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
+ * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
+ * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
* ];
*
* // using "_.pluck" callback shorthand
- * _.first(food, 'organic');
- * // => [{ 'name': 'banana', 'organic': true }]
- *
- * var food = [
- * { 'name': 'apple', 'type': 'fruit' },
- * { 'name': 'banana', 'type': 'fruit' },
- * { 'name': 'beet', 'type': 'vegetable' }
- * ];
+ * _.first(characters, 'blocked');
+ * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
*
* // using "_.where" callback shorthand
- * _.first(food, { 'type': 'fruit' });
- * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
+ * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
+ * // => ['barney', 'fred']
*/
function first(array, callback, thisArg) {
var n = 0,
@@ -4404,14 +4495,14 @@
* _.flatten([1, [2], [3, [[4]]]], true);
* // => [1, 2, 3, [[4]]];
*
- * var stooges = [
- * { 'name': 'curly', 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
- * { 'name': 'moe', 'quotes': ['Spread out!', 'You knucklehead!'] }
+ * var characters = [
+ * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
+ * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
* ];
*
* // using "_.pluck" callback shorthand
- * _.flatten(stooges, 'quotes');
- * // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!']
+ * _.flatten(characters, 'pets');
+ * // => ['hoppy', 'baby puss', 'dino']
*/
function flatten(array, isShallow, callback, thisArg) {
// juggle arguments
@@ -4497,24 +4588,19 @@
* });
* // => [1]
*
- * var food = [
- * { 'name': 'beet', 'organic': false },
- * { 'name': 'carrot', 'organic': true }
+ * var characters = [
+ * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
+ * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
+ * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
* ];
*
* // using "_.pluck" callback shorthand
- * _.initial(food, 'organic');
- * // => [{ 'name': 'beet', 'organic': false }]
- *
- * var food = [
- * { 'name': 'banana', 'type': 'fruit' },
- * { 'name': 'beet', 'type': 'vegetable' },
- * { 'name': 'carrot', 'type': 'vegetable' }
- * ];
+ * _.initial(characters, 'blocked');
+ * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
*
* // using "_.where" callback shorthand
- * _.initial(food, { 'type': 'vegetable' });
- * // => [{ 'name': 'banana', 'type': 'fruit' }]
+ * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
+ * // => ['barney', 'fred']
*/
function initial(array, callback, thisArg) {
var n = 0,
@@ -4627,24 +4713,19 @@
* });
* // => [2, 3]
*
- * var food = [
- * { 'name': 'beet', 'organic': false },
- * { 'name': 'carrot', 'organic': true }
+ * var characters = [
+ * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
+ * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
+ * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
* ];
*
* // using "_.pluck" callback shorthand
- * _.last(food, 'organic');
- * // => [{ 'name': 'carrot', 'organic': true }]
- *
- * var food = [
- * { 'name': 'banana', 'type': 'fruit' },
- * { 'name': 'beet', 'type': 'vegetable' },
- * { 'name': 'carrot', 'type': 'vegetable' }
- * ];
+ * _.pluck(_.last(characters, 'blocked'), 'name');
+ * // => ['fred', 'pebbles']
*
* // using "_.where" callback shorthand
- * _.last(food, { 'type': 'vegetable' });
- * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
+ * _.last(characters, { 'employer': 'na' });
+ * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
*/
function last(array, callback, thisArg) {
var n = 0,
@@ -4670,6 +4751,13 @@
* equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
* as the offset from the end of the collection.
*
+ * If a property name is provided for `callback` the created "_.pluck" style
+ * callback will return the property value of the given element.
+ *
+ * If an object is provided for `callback` the created "_.where" style callback
+ * will return `true` for elements that have the properties of the given object,
+ * else `false`.
+ *
* @static
* @memberOf _
* @category Arrays
@@ -4748,17 +4836,17 @@
* @returns {Array} Returns a new range array.
* @example
*
- * _.range(10);
- * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ * _.range(4);
+ * // => [0, 1, 2, 3]
*
- * _.range(1, 11);
- * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ * _.range(1, 5);
+ * // => [1, 2, 3, 4]
*
- * _.range(0, 30, 5);
- * // => [0, 5, 10, 15, 20, 25]
+ * _.range(0, 20, 5);
+ * // => [0, 5, 10, 15]
*
- * _.range(0, -10, -1);
- * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
+ * _.range(0, -4, -1);
+ * // => [0, -1, -2, -3]
*
* _.range(1, 4, 0);
* // => [1, 1, 1]
@@ -4874,24 +4962,19 @@
* });
* // => [3]
*
- * var food = [
- * { 'name': 'banana', 'organic': true },
- * { 'name': 'beet', 'organic': false },
+ * var characters = [
+ * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
+ * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
+ * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
* ];
*
* // using "_.pluck" callback shorthand
- * _.rest(food, 'organic');
- * // => [{ 'name': 'beet', 'organic': false }]
- *
- * var food = [
- * { 'name': 'apple', 'type': 'fruit' },
- * { 'name': 'banana', 'type': 'fruit' },
- * { 'name': 'beet', 'type': 'vegetable' }
- * ];
+ * _.pluck(_.rest(characters, 'blocked'), 'name');
+ * // => ['fred', 'pebbles']
*
* // using "_.where" callback shorthand
- * _.rest(food, { 'type': 'fruit' });
- * // => [{ 'name': 'beet', 'type': 'vegetable' }]
+ * _.rest(characters, { 'employer': 'slate' });
+ * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
*/
function rest(array, callback, thisArg) {
if (typeof callback != 'number' && callback != null) {
@@ -5081,8 +5164,8 @@
* @returns {Array} Returns a new array of grouped elements.
* @example
*
- * _.zip(['moe', 'larry'], [30, 40], [true, false]);
- * // => [['moe', 30, true], ['larry', 40, false]]
+ * _.zip(['fred', 'barney'], [30, 40], [true, false]);
+ * // => [['fred', 30, true], ['barney', 40, false]]
*/
function zip() {
var array = arguments.length > 1 ? arguments : arguments[0],
@@ -5111,8 +5194,8 @@
* corresponding values.
* @example
*
- * _.zipObject(['moe', 'larry'], [30, 40]);
- * // => { 'moe': 30, 'larry': 40 }
+ * _.zipObject(['fred', 'barney'], [30, 40]);
+ * // => { 'fred': 30, 'barney': 40 }
*/
function zipObject(keys, values) {
var index = -1,
@@ -5185,9 +5268,9 @@
* return greeting + ' ' + this.name;
* };
*
- * func = _.bind(func, { 'name': 'moe' }, 'hi');
+ * func = _.bind(func, { 'name': 'fred' }, 'hi');
* func();
- * // => 'hi moe'
+ * // => 'hi fred'
*/
function bind(func, thisArg) {
return arguments.length > 2
@@ -5248,7 +5331,7 @@
* @example
*
* var object = {
- * 'name': 'moe',
+ * 'name': 'fred',
* 'greet': function(greeting) {
* return greeting + ' ' + this.name;
* }
@@ -5256,14 +5339,14 @@
*
* var func = _.bindKey(object, 'greet', 'hi');
* func();
- * // => 'hi moe'
+ * // => 'hi fred'
*
* object.greet = function(greeting) {
* return greeting + ', ' + this.name + '!';
* };
*
* func();
- * // => 'hi, moe!'
+ * // => 'hi, fred!'
*/
function bindKey(object, key) {
return arguments.length > 2
@@ -5285,7 +5368,7 @@
* @example
*
* var realNameMap = {
- * 'curly': 'jerome'
+ * 'pebbles': 'jerome'
* };
*
* var format = function(name) {
@@ -5298,7 +5381,7 @@
* };
*
* var welcome = _.compose(greet, format);
- * welcome('curly');
+ * welcome('pebbles');
* // => 'Hiya Jerome!'
*/
function compose() {
@@ -5336,9 +5419,9 @@
* @returns {Function} Returns a callback function.
* @example
*
- * var stooges = [
- * { 'name': 'moe', 'age': 40 },
- * { 'name': 'larry', 'age': 50 }
+ * var characters = [
+ * { 'name': 'barney', 'age': 36 },
+ * { 'name': 'fred', 'age': 40 }
* ];
*
* // wrap to create custom callback shorthands
@@ -5349,8 +5432,8 @@
* };
* });
*
- * _.filter(stooges, 'age__gt45');
- * // => [{ 'name': 'larry', 'age': 50 }]
+ * _.filter(characters, 'age__gt38');
+ * // => [{ 'name': 'fred', 'age': 40 }]
*/
function createCallback(func, thisArg, argCount) {
var type = typeof func;
@@ -5625,17 +5708,17 @@
* });
*
* var data = {
- * 'moe': { 'name': 'moe', 'age': 40 },
- * 'curly': { 'name': 'curly', 'age': 60 }
+ * 'fred': { 'name': 'fred', 'age': 40 },
+ * 'pebbles': { 'name': 'pebbles', 'age': 60 }
* };
*
* // modifying the result cache
* var stooge = _.memoize(function(name) { return data[name]; }, _.identity);
- * stooge('curly');
- * // => { 'name': 'curly', 'age': 60 }
+ * stooge('pebbles');
+ * // => { 'name': 'pebbles', 'age': 60 }
*
- * stooge.cache.curly.name = 'jerome';
- * stooge('curly');
+ * stooge.cache.pebbles.name = 'jerome';
+ * stooge('pebbles');
* // => { 'name': 'jerome', 'age': 60 }
*/
function memoize(func, resolver) {
@@ -5706,8 +5789,8 @@
*
* var greet = function(greeting, name) { return greeting + ' ' + name; };
* var hi = _.partial(greet, 'hi');
- * hi('moe');
- * // => 'hi moe'
+ * hi('fred');
+ * // => 'hi fred'
*/
function partial(func) {
return createBound(func, 16, nativeSlice.call(arguments, 1));
@@ -5792,8 +5875,7 @@
debounceOptions.maxWait = wait;
debounceOptions.trailing = trailing;
- var result = debounce(func, wait, debounceOptions);
- return result;
+ return debounce(func, wait, debounceOptions);
}
/**
@@ -5812,10 +5894,10 @@
*
* var hello = function(name) { return 'hello ' + name; };
* hello = _.wrap(hello, function(func) {
- * return 'before, ' + func('moe') + ', after';
+ * return 'before, ' + func('fred') + ', after';
* });
* hello();
- * // => 'before, hello moe, after'
+ * // => 'before, hello fred, after'
*/
function wrap(value, wrapper) {
if (!isFunction(wrapper)) {
@@ -5841,8 +5923,8 @@
* @returns {string} Returns the escaped string.
* @example
*
- * _.escape('Moe, Larry & Curly');
- * // => 'Moe, Larry & Curly'
+ * _.escape('Fred, Wilma, & Pebbles');
+ * // => 'Fred, Wilma, & Pebbles'
*/
function escape(string) {
return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
@@ -5858,8 +5940,8 @@
* @returns {*} Returns `value`.
* @example
*
- * var moe = { 'name': 'moe' };
- * moe === _.identity(moe);
+ * var fred = { 'name': 'fred' };
+ * fred === _.identity(fred);
* // => true
*/
function identity(value) {
@@ -5883,11 +5965,11 @@
* }
* });
*
- * _.capitalize('moe');
- * // => 'Moe'
+ * _.capitalize('fred');
+ * // => 'Fred'
*
- * _('moe').capitalize();
- * // => 'Moe'
+ * _('fred').capitalize();
+ * // => 'Fred'
*/
function mixin(object, source) {
var ctor = object,
@@ -6010,10 +6092,11 @@
} else {
max = +max || 0;
}
- var rand = nativeRandom();
- return (floating || min % 1 || max % 1)
- ? nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max)
- : min + floor(rand * (max - min + 1));
+ if (floating || min % 1 || max % 1) {
+ var rand = nativeRandom();
+ return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
+ }
+ return baseRandom(min, max);
}
/**
@@ -6081,8 +6164,8 @@
*
* // using the "interpolate" delimiter to create a compiled template
* var compiled = _.template('hello <%= name %>');
- * compiled({ 'name': 'moe' });
- * // => 'hello moe'
+ * compiled({ 'name': 'fred' });
+ * // => 'hello fred'
*
* // using the "escape" delimiter to escape HTML in data property values
* _.template('<%- value %>', { 'value': '