3 * Lo-Dash 1.0.2 (Custom Build) <http://lodash.com/>
4 * Build: `lodash underscore -o ./dist/lodash.underscore.js`
5 * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
6 * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
7 * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
8 * Available under MIT license <http://lodash.com/license>
10 ;(function(window, undefined) {
12 /** Detect free variable `exports` */
13 var freeExports = typeof exports == 'object' && exports;
15 /** Detect free variable `module` */
16 var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
18 /** Detect free variable `global` and use it as `window` */
19 var freeGlobal = typeof global == 'object' && global;
20 if (freeGlobal.global === freeGlobal) {
24 /** Used for array and object method references */
28 /** Used to generate unique IDs */
31 /** Used internally to indicate various things */
32 var indicatorObject = objectRef;
34 /** Used to restore the original `_` reference in `noConflict` */
35 var oldDash = window._;
37 /** Used to match HTML entities */
38 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
40 /** Used to match empty string literals in compiled template source */
41 var reEmptyStringLeading = /\b__p \+= '';/g,
42 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
43 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
45 /** Used to match regexp flags from their coerced string values */
48 /** Used to detect if a method is native */
49 var reNative = RegExp('^' +
50 (objectRef.valueOf + '')
51 .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
52 .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
56 * Used to match ES6 template delimiters
57 * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
59 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
61 /** Used to match "interpolate" template delimiters */
62 var reInterpolate = /<%=([\s\S]+?)%>/g;
64 /** Used to ensure capturing order of template delimiters */
65 var reNoMatch = /($^)/;
67 /** Used to match HTML characters */
68 var reUnescapedHtml = /[&<>"']/g;
70 /** Used to match unescaped characters in compiled string literals */
71 var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
73 /** Used to make template sourceURLs easier to identify */
74 var templateCounter = 0;
76 /** Native method shortcuts */
78 concat = arrayRef.concat,
80 hasOwnProperty = objectRef.hasOwnProperty,
82 toString = objectRef.toString;
84 /* Native method shortcuts for methods with the same name as other `lodash` methods */
85 var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
86 nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
87 nativeIsFinite = window.isFinite,
88 nativeIsNaN = window.isNaN,
89 nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
92 nativeRandom = Math.random;
94 /** `Object#toString` result shortcuts */
95 var argsClass = '[object Arguments]',
96 arrayClass = '[object Array]',
97 boolClass = '[object Boolean]',
98 dateClass = '[object Date]',
99 funcClass = '[object Function]',
100 numberClass = '[object Number]',
101 objectClass = '[object Object]',
102 regexpClass = '[object RegExp]',
103 stringClass = '[object String]';
105 /** Detect various environments */
106 var isIeOpera = !!window.attachEvent,
107 isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
109 /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */
110 var isBindFast = nativeBind && !isV8;
113 * Detect if `Array#shift` and `Array#splice` augment array-like objects
116 * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
117 * and `splice()` functions that fail to remove the last element, `value[0]`,
118 * of array-like objects even though the `length` property is set to `0`.
119 * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
120 * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
122 var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 },
123 arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]);
125 /** Detect if `arguments` objects are `Object` objects (all but Opera < 10.5) */
126 var argsAreObjects = arguments.constructor == Object;
128 /** Used to determine if values are of the language type Object */
138 /** Used to escape characters for inclusion in compiled string literals */
139 var stringEscapes = {
149 /*--------------------------------------------------------------------------*/
152 * Creates a `lodash` object, that wraps the given `value`, to enable method
155 * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
156 * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
159 * The chainable wrapper functions are:
160 * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`,
161 * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`,
162 * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`,
163 * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`,
164 * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
165 * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
166 * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
167 * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
169 * The non-chainable wrapper functions are:
170 * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`,
171 * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`,
172 * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`,
173 * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`,
174 * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`,
175 * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId`
177 * The wrapper functions `first` and `last` return wrapped values when `n` is
178 * passed, otherwise they return unwrapped values.
183 * @param {Mixed} value The value to wrap in a `lodash` instance.
184 * @returns {Object} Returns a `lodash` instance.
186 function lodash(value) {
187 // exit early if already wrapped, even if wrapped by a different `lodash` constructor
188 if (value && typeof value == 'object' && value.__wrapped__) {
191 // allow invoking `lodash` without the `new` operator
192 if (!(this instanceof lodash)) {
193 return new lodash(value);
195 this.__wrapped__ = value;
199 * By default, the template delimiters used by Lo-Dash are similar to those in
200 * embedded Ruby (ERB). Change the following template settings to use alternative
207 lodash.templateSettings = {
210 * Used to detect `data` property values to be HTML-escaped.
212 * @memberOf _.templateSettings
215 'escape': /<%-([\s\S]+?)%>/g,
218 * Used to detect code to be evaluated.
220 * @memberOf _.templateSettings
223 'evaluate': /<%([\s\S]+?)%>/g,
226 * Used to detect `data` property values to inject.
228 * @memberOf _.templateSettings
231 'interpolate': reInterpolate,
234 * Used to reference the data object in the template text.
236 * @memberOf _.templateSettings
242 /*--------------------------------------------------------------------------*/
245 * Used by `_.max` and `_.min` as the default `callback` when a given
246 * `collection` is a string value.
249 * @param {String} value The character to inspect.
250 * @returns {Number} Returns the code unit of given character.
252 function charAtCallback(value) {
253 return value.charCodeAt(0);
257 * Used by `sortBy` to compare transformed `collection` values, stable sorting
258 * them in ascending order.
261 * @param {Object} a The object to compare to `b`.
262 * @param {Object} b The object to compare to `a`.
263 * @returns {Number} Returns the sort order indicator of `1` or `-1`.
265 function compareAscending(a, b) {
272 // ensure a stable sort in V8 and other engines
273 // http://code.google.com/p/v8/issues/detail?id=90
275 if (a > b || typeof a == 'undefined') {
278 if (a < b || typeof b == 'undefined') {
282 return ai < bi ? -1 : 1;
286 * Creates a function that, when called, invokes `func` with the `this` binding
287 * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
291 * @param {Function|String} func The function to bind or the method name.
292 * @param {Mixed} [thisArg] The `this` binding of `func`.
293 * @param {Array} partialArgs An array of arguments to be partially applied.
294 * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right.
295 * @returns {Function} Returns the new bound function.
297 function createBound(func, thisArg, partialArgs, rightIndicator) {
298 var isFunc = isFunction(func),
299 isPartial = !partialArgs,
304 partialArgs = thisArg;
311 // `Function#bind` spec
312 // http://es5.github.com/#x15.3.4.5
313 var args = arguments,
314 thisBinding = isPartial ? this : thisArg;
319 if (partialArgs.length) {
321 ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
324 if (this instanceof bound) {
325 // ensure `new bound` is an instance of `bound` and `func`
326 noop.prototype = func.prototype;
327 thisBinding = new noop;
328 noop.prototype = null;
330 // mimic the constructor's `return` behavior
331 // http://es5.github.com/#x13.2.2
332 var result = func.apply(thisBinding, args);
333 return isObject(result) ? result : thisBinding;
335 return func.apply(thisBinding, args);
341 * Produces a callback bound to an optional `thisArg`. If `func` is a property
342 * name, the created callback will return the property value for a given element.
343 * If `func` is an object, the created callback will return `true` for elements
344 * that contain the equivalent object properties, otherwise it will return `false`.
347 * @param {Mixed} [func=identity] The value to convert to a callback.
348 * @param {Mixed} [thisArg] The `this` binding of the created callback.
349 * @param {Number} [argCount=3] The number of arguments the callback accepts.
350 * @returns {Function} Returns a callback function.
352 function createCallback(func, thisArg, argCount) {
356 var type = typeof func;
357 if (type != 'function') {
358 if (type != 'object') {
359 return function(object) {
363 var props = keys(func);
364 return function(object) {
365 var length = props.length,
368 if (!(result = object[props[length]] === func[props[length]])) {
375 if (typeof thisArg != 'undefined') {
376 if (argCount === 1) {
377 return function(value) {
378 return func.call(thisArg, value);
381 if (argCount === 2) {
382 return function(a, b) {
383 return func.call(thisArg, a, b);
386 if (argCount === 4) {
387 return function(accumulator, value, index, object) {
388 return func.call(thisArg, accumulator, value, index, object);
391 return function(value, index, object) {
392 return func.call(thisArg, value, index, object);
399 * A function compiled to iterate `arguments` objects, arrays, objects, and
400 * strings consistenly across environments, executing the `callback` for each
401 * element in the `collection`. The `callback` is bound to `thisArg` and invoked
402 * with three arguments; (value, index|key, collection). Callbacks may exit
403 * iteration early by explicitly returning `false`.
407 * @param {Array|Object|String} collection The collection to iterate over.
408 * @param {Function} [callback=identity] The function called per iteration.
409 * @param {Mixed} [thisArg] The `this` binding of `callback`.
410 * @returns {Array|Object|String} Returns `collection`.
412 var each = function (collection, callback, thisArg) {
413 var index, iterable = collection, result = iterable;
414 if (!iterable) return result;
415 callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg);
416 var length = iterable.length; index = -1;
417 if (typeof length == 'number') {
418 while (++index < length) {
419 if (callback(iterable[index], index, collection) === indicatorObject) return result
423 for (index in iterable) {
424 if (hasOwnProperty.call(iterable, index)) {
425 if (callback(iterable[index], index, collection) === indicatorObject) return result;
432 * Used by `template` to escape characters for inclusion in compiled
436 * @param {String} match The matched character to escape.
437 * @returns {String} Returns the escaped character.
439 function escapeStringChar(match) {
440 return '\\' + stringEscapes[match];
444 * Used by `escape` to convert characters to HTML entities.
447 * @param {String} match The matched character to escape.
448 * @returns {String} Returns the escaped character.
450 function escapeHtmlChar(match) {
451 return htmlEscapes[match];
455 * Checks if `value` is a DOM node in IE < 9.
458 * @param {Mixed} value The value to check.
459 * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
461 function isNode(value) {
462 // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
463 // methods that are `typeof` "string" and still can coerce nodes to strings
464 return typeof value.toString != 'function' && typeof (value + '') == 'string';
468 * A no-operation function.
473 // no operation performed
477 * Slices the `collection` from the `start` index up to, but not including,
480 * Note: This function is used, instead of `Array#slice`, to support node lists
481 * in IE < 9 and to ensure dense arrays are returned.
484 * @param {Array|Object|String} collection The collection to slice.
485 * @param {Number} start The start index.
486 * @param {Number} end The end index.
487 * @returns {Array} Returns the new array.
489 function slice(array, start, end) {
490 start || (start = 0);
491 if (typeof end == 'undefined') {
492 end = array ? array.length : 0;
495 length = end - start || 0,
496 result = Array(length < 0 ? 0 : length);
498 while (++index < length) {
499 result[index] = array[start + index];
505 * Used by `unescape` to convert HTML entities to characters.
508 * @param {String} match The matched character to unescape.
509 * @returns {String} Returns the unescaped character.
511 function unescapeHtmlChar(match) {
512 return htmlUnescapes[match];
515 /*--------------------------------------------------------------------------*/
518 * Checks if `value` is an `arguments` object.
523 * @param {Mixed} value The value to check.
524 * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
527 * (function() { return _.isArguments(arguments); })(1, 2, 3);
530 * _.isArguments([1, 2, 3]);
533 function isArguments(value) {
534 return toString.call(value) == argsClass;
536 // fallback for browsers that can't detect `arguments` objects by [[Class]]
537 if (!isArguments(arguments)) {
538 isArguments = function(value) {
539 return value ? hasOwnProperty.call(value, 'callee') : false;
544 * Iterates over `object`'s own and inherited enumerable properties, executing
545 * the `callback` for each property. The `callback` is bound to `thisArg` and
546 * invoked with three arguments; (value, key, object). Callbacks may exit iteration
547 * early by explicitly returning `false`.
553 * @param {Object} object The object to iterate over.
554 * @param {Function} [callback=identity] The function called per iteration.
555 * @param {Mixed} [thisArg] The `this` binding of `callback`.
556 * @returns {Object} Returns `object`.
559 * function Dog(name) {
563 * Dog.prototype.bark = function() {
564 * alert('Woof, woof!');
567 * _.forIn(new Dog('Dagny'), function(value, key) {
570 * // => alerts 'name' and 'bark' (order is not guaranteed)
572 var forIn = function (collection, callback) {
573 var index, iterable = collection, result = iterable;
574 if (!iterable) return result;
575 if (!objectTypes[typeof iterable]) return result;
576 callback || (callback = identity);
578 for (index in iterable) {
579 if (callback(iterable[index], index, collection) === indicatorObject) return result;
585 * Iterates over an object's own enumerable properties, executing the `callback`
586 * for each property. The `callback` is bound to `thisArg` and invoked with three
587 * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
594 * @param {Object} object The object to iterate over.
595 * @param {Function} [callback=identity] The function called per iteration.
596 * @param {Mixed} [thisArg] The `this` binding of `callback`.
597 * @returns {Object} Returns `object`.
600 * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
603 * // => alerts '0', '1', and 'length' (order is not guaranteed)
605 var forOwn = function (collection, callback) {
606 var index, iterable = collection, result = iterable;
607 if (!iterable) return result;
608 if (!objectTypes[typeof iterable]) return result;
609 callback || (callback = identity);
611 for (index in iterable) {
612 if (hasOwnProperty.call(iterable, index)) {
613 if (callback(iterable[index], index, collection) === indicatorObject) return result;
620 * Checks if `value` is an array.
625 * @param {Mixed} value The value to check.
626 * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
629 * (function() { return _.isArray(arguments); })();
632 * _.isArray([1, 2, 3]);
635 var isArray = nativeIsArray || function(value) {
636 // `instanceof` may cause a memory leak in IE 7 if `value` is a host object
637 // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
638 return (argsAreObjects && value instanceof Array) || toString.call(value) == arrayClass;
642 * Creates an array composed of the own enumerable property names of `object`.
647 * @param {Object} object The object to inspect.
648 * @returns {Array} Returns a new array of property names.
651 * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
652 * // => ['one', 'two', 'three'] (order is not guaranteed)
654 var keys = !nativeKeys ? shimKeys : function(object) {
655 if (!isObject(object)) {
658 return nativeKeys(object);
662 * A fallback implementation of `isPlainObject` that checks if a given `value`
663 * is an object created by the `Object` constructor, assuming objects created
664 * by the `Object` constructor have no inherited enumerable properties and that
665 * there are no `Object.prototype` extensions.
668 * @param {Mixed} value The value to check.
669 * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
671 function shimIsPlainObject(value) {
672 // avoid non-objects and false positives for `arguments` objects
674 if (!(value && typeof value == 'object') || isArguments(value)) {
677 // check that the constructor is `Object` (i.e. `Object instanceof Object`)
678 var ctor = value.constructor;
679 if ((!isFunction(ctor)) || ctor instanceof ctor) {
680 // In most environments an object's own properties are iterated before
681 // its inherited properties. If the last iterated property is an object's
682 // own property then there are no inherited enumerable properties.
683 forIn(value, function(value, key) {
686 return result === false || hasOwnProperty.call(value, result);
692 * A fallback implementation of `Object.keys` that produces an array of the
693 * given object's own enumerable property names.
696 * @param {Object} object The object to inspect.
697 * @returns {Array} Returns a new array of property names.
699 function shimKeys(object) {
701 forOwn(object, function(value, key) {
708 * Used to convert characters to HTML entities:
710 * Though the `>` character is escaped for symmetry, characters like `>` and `/`
711 * don't require escaping in HTML and have no special meaning unless they're part
712 * of a tag or an unquoted attribute value.
713 * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
723 /** Used to convert HTML entities to characters */
724 var htmlUnescapes = invert(htmlEscapes);
726 /*--------------------------------------------------------------------------*/
729 * Assigns own enumerable properties of source object(s) to the destination
730 * object. Subsequent sources will overwrite propery assignments of previous
731 * sources. If a `callback` function is passed, it will be executed to produce
732 * the assigned values. The `callback` is bound to `thisArg` and invoked with
733 * two arguments; (objectValue, sourceValue).
740 * @param {Object} object The destination object.
741 * @param {Object} [source1, source2, ...] The source objects.
742 * @param {Function} [callback] The function to customize assigning values.
743 * @param {Mixed} [thisArg] The `this` binding of `callback`.
744 * @returns {Object} Returns the destination object.
747 * _.assign({ 'name': 'moe' }, { 'age': 40 });
748 * // => { 'name': 'moe', 'age': 40 }
750 * var defaults = _.partialRight(_.assign, function(a, b) {
751 * return typeof a == 'undefined' ? b : a;
754 * var food = { 'name': 'apple' };
755 * defaults(food, { 'name': 'banana', 'type': 'fruit' });
756 * // => { 'name': 'apple', 'type': 'fruit' }
758 function assign(object) {
762 for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
763 var iterable = arguments[argsIndex];
765 for (var key in iterable) {
766 object[key] = iterable[key];
774 * Creates a clone of `value`. If `deep` is `true`, nested objects will also
775 * be cloned, otherwise they will be assigned by reference. If a `callback`
776 * function is passed, it will be executed to produce the cloned values. If
777 * `callback` returns `undefined`, cloning will be handled by the method instead.
778 * The `callback` is bound to `thisArg` and invoked with one argument; (value).
783 * @param {Mixed} value The value to clone.
784 * @param {Boolean} [deep=false] A flag to indicate a deep clone.
785 * @param {Function} [callback] The function to customize cloning values.
786 * @param {Mixed} [thisArg] The `this` binding of `callback`.
787 * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
788 * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts.
789 * @returns {Mixed} Returns the cloned `value`.
793 * { 'name': 'moe', 'age': 40 },
794 * { 'name': 'larry', 'age': 50 }
797 * var shallow = _.clone(stooges);
798 * shallow[0] === stooges[0];
801 * var deep = _.clone(stooges, true);
802 * deep[0] === stooges[0];
806 * 'clone': _.partialRight(_.clone, function(value) {
807 * return _.isElement(value) ? value.cloneNode(false) : undefined;
811 * var clone = _.clone(document.body);
812 * clone.childNodes.length;
815 function clone(value) {
816 return isObject(value)
817 ? (isArray(value) ? slice(value) : assign({}, value))
822 * Assigns own enumerable properties of source object(s) to the destination
823 * object for all destination properties that resolve to `undefined`. Once a
824 * property is set, additional defaults of the same property will be ignored.
830 * @param {Object} object The destination object.
831 * @param {Object} [source1, source2, ...] The source objects.
832 * @param- {Object} [guard] Internally used to allow working with `_.reduce`
833 * without using its callback's `key` and `object` arguments as sources.
834 * @returns {Object} Returns the destination object.
837 * var food = { 'name': 'apple' };
838 * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
839 * // => { 'name': 'apple', 'type': 'fruit' }
841 function defaults(object) {
845 for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
846 var iterable = arguments[argsIndex];
848 for (var key in iterable) {
849 if (object[key] == null) {
850 object[key] = iterable[key];
859 * Creates a sorted array of all enumerable properties, own and inherited,
860 * of `object` that have function values.
866 * @param {Object} object The object to inspect.
867 * @returns {Array} Returns a new array of property names that have function values.
871 * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
873 function functions(object) {
875 forIn(object, function(value, key) {
876 if (isFunction(value)) {
880 return result.sort();
884 * Checks if the specified object `property` exists and is a direct property,
885 * instead of an inherited property.
890 * @param {Object} object The object to check.
891 * @param {String} property The property to check for.
892 * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
895 * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
898 function has(object, property) {
899 return object ? hasOwnProperty.call(object, property) : false;
903 * Creates an object composed of the inverted keys and values of the given `object`.
908 * @param {Object} object The object to invert.
909 * @returns {Object} Returns the created inverted object.
912 * _.invert({ 'first': 'moe', 'second': 'larry' });
913 * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed)
915 function invert(object) {
917 props = keys(object),
918 length = props.length,
921 while (++index < length) {
922 var key = props[index];
923 result[object[key]] = key;
929 * Checks if `value` is a boolean value.
934 * @param {Mixed} value The value to check.
935 * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
941 function isBoolean(value) {
942 return value === true || value === false || toString.call(value) == boolClass;
946 * Checks if `value` is a date.
951 * @param {Mixed} value The value to check.
952 * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
955 * _.isDate(new Date);
958 function isDate(value) {
959 return value instanceof Date || toString.call(value) == dateClass;
963 * Checks if `value` is a DOM element.
968 * @param {Mixed} value The value to check.
969 * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
972 * _.isElement(document.body);
975 function isElement(value) {
976 return value ? value.nodeType === 1 : false;
980 * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
981 * length of `0` and objects with no own enumerable properties are considered
987 * @param {Array|Object|String} value The value to inspect.
988 * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
991 * _.isEmpty([1, 2, 3]);
1000 function isEmpty(value) {
1004 if (isArray(value) || isString(value)) {
1005 return !value.length;
1007 for (var key in value) {
1008 if (hasOwnProperty.call(value, key)) {
1016 * Performs a deep comparison between two values to determine if they are
1017 * equivalent to each other. If `callback` is passed, it will be executed to
1018 * compare values. If `callback` returns `undefined`, comparisons will be handled
1019 * by the method instead. The `callback` is bound to `thisArg` and invoked with
1020 * two arguments; (a, b).
1025 * @param {Mixed} a The value to compare.
1026 * @param {Mixed} b The other value to compare.
1027 * @param {Function} [callback] The function to customize comparing values.
1028 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1029 * @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
1030 * @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
1031 * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`.
1034 * var moe = { 'name': 'moe', 'age': 40 };
1035 * var copy = { 'name': 'moe', 'age': 40 };
1040 * _.isEqual(moe, copy);
1043 * var words = ['hello', 'goodbye'];
1044 * var otherWords = ['hi', 'goodbye'];
1046 * _.isEqual(words, otherWords, function(a, b) {
1047 * var reGreet = /^(?:hello|hi)$/i,
1048 * aGreet = _.isString(a) && reGreet.test(a),
1049 * bGreet = _.isString(b) && reGreet.test(b);
1051 * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
1055 function isEqual(a, b, stackA, stackB) {
1057 return a !== 0 || (1 / a == 1 / b);
1059 var type = typeof a,
1060 otherType = typeof b;
1063 (!a || (type != 'function' && type != 'object')) &&
1064 (!b || (otherType != 'function' && otherType != 'object'))) {
1067 if (a == null || b == null) {
1070 var className = toString.call(a),
1071 otherClass = toString.call(b);
1073 if (className != otherClass) {
1076 switch (className) {
1084 : (a == 0 ? (1 / a == 1 / b) : a == +b);
1090 var isArr = className == arrayClass;
1092 if (a.__wrapped__ || b.__wrapped__) {
1093 return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, stackA, stackB);
1095 if (className != objectClass) {
1098 var ctorA = a.constructor,
1099 ctorB = b.constructor;
1101 if (ctorA != ctorB && !(
1102 isFunction(ctorA) && ctorA instanceof ctorA &&
1103 isFunction(ctorB) && ctorB instanceof ctorB
1108 stackA || (stackA = []);
1109 stackB || (stackB = []);
1111 var length = stackA.length;
1113 if (stackA[length] == a) {
1114 return stackB[length] == b;
1125 result = size == a.length;
1129 if (!(result = isEqual(a[size], b[size], stackA, stackB))) {
1136 forIn(b, function(value, key, b) {
1137 if (hasOwnProperty.call(b, key)) {
1139 return !(result = hasOwnProperty.call(a, key) && isEqual(a[key], value, stackA, stackB)) && indicatorObject;
1144 forIn(a, function(value, key, a) {
1145 if (hasOwnProperty.call(a, key)) {
1146 return !(result = --size > -1) && indicatorObject;
1154 * Checks if `value` is, or can be coerced to, a finite number.
1156 * Note: This is not the same as native `isFinite`, which will return true for
1157 * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
1162 * @param {Mixed} value The value to check.
1163 * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
1178 * _.isFinite(Infinity);
1181 function isFinite(value) {
1182 return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
1186 * Checks if `value` is a function.
1191 * @param {Mixed} value The value to check.
1192 * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
1198 function isFunction(value) {
1199 return typeof value == 'function';
1201 // fallback for older versions of Chrome and Safari
1202 if (isFunction(/x/)) {
1203 isFunction = function(value) {
1204 return value instanceof Function || toString.call(value) == funcClass;
1209 * Checks if `value` is the language type of Object.
1210 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
1215 * @param {Mixed} value The value to check.
1216 * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
1222 * _.isObject([1, 2, 3]);
1228 function isObject(value) {
1229 // check if the value is the ECMAScript language type of Object
1230 // http://es5.github.com/#x8
1231 // and avoid a V8 bug
1232 // http://code.google.com/p/v8/issues/detail?id=2291
1233 return value ? objectTypes[typeof value] : false;
1237 * Checks if `value` is `NaN`.
1239 * Note: This is not the same as native `isNaN`, which will return `true` for
1240 * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
1245 * @param {Mixed} value The value to check.
1246 * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
1252 * _.isNaN(new Number(NaN));
1258 * _.isNaN(undefined);
1261 function isNaN(value) {
1262 // `NaN` as a primitive is the only value that is not equal to itself
1263 // (perform the [[Class]] check first to avoid errors with some host objects in IE)
1264 return isNumber(value) && value != +value
1268 * Checks if `value` is `null`.
1273 * @param {Mixed} value The value to check.
1274 * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
1280 * _.isNull(undefined);
1283 function isNull(value) {
1284 return value === null;
1288 * Checks if `value` is a number.
1293 * @param {Mixed} value The value to check.
1294 * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
1297 * _.isNumber(8.4 * 5);
1300 function isNumber(value) {
1301 return typeof value == 'number' || toString.call(value) == numberClass;
1305 * Checks if `value` is a regular expression.
1310 * @param {Mixed} value The value to check.
1311 * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
1314 * _.isRegExp(/moe/);
1317 function isRegExp(value) {
1318 return value instanceof RegExp || toString.call(value) == regexpClass;
1322 * Checks if `value` is a string.
1327 * @param {Mixed} value The value to check.
1328 * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
1331 * _.isString('moe');
1334 function isString(value) {
1335 return typeof value == 'string' || toString.call(value) == stringClass;
1339 * Checks if `value` is `undefined`.
1344 * @param {Mixed} value The value to check.
1345 * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
1348 * _.isUndefined(void 0);
1351 function isUndefined(value) {
1352 return typeof value == 'undefined';
1356 * Creates a shallow clone of `object` excluding the specified properties.
1357 * Property names may be specified as individual arguments or as arrays of
1358 * property names. If a `callback` function is passed, it will be executed
1359 * for each property in the `object`, omitting the properties `callback`
1360 * returns truthy for. The `callback` is bound to `thisArg` and invoked
1361 * with three arguments; (value, key, object).
1366 * @param {Object} object The source object.
1367 * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
1368 * or the function called per iteration.
1369 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1370 * @returns {Object} Returns an object without the omitted properties.
1373 * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
1374 * // => { 'name': 'moe' }
1376 * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
1377 * return typeof value == 'number';
1379 * // => { 'name': 'moe' }
1381 function omit(object) {
1382 var props = concat.apply(arrayRef, arguments),
1385 forIn(object, function(value, key) {
1386 if (indexOf(props, key, 1) < 0) {
1387 result[key] = value;
1394 * Creates a two dimensional array of the given object's key-value pairs,
1395 * i.e. `[[key1, value1], [key2, value2]]`.
1400 * @param {Object} object The object to inspect.
1401 * @returns {Array} Returns new array of key-value pairs.
1404 * _.pairs({ 'moe': 30, 'larry': 40 });
1405 * // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
1407 function pairs(object) {
1409 props = keys(object),
1410 length = props.length,
1411 result = Array(length);
1413 while (++index < length) {
1414 var key = props[index];
1415 result[index] = [key, object[key]];
1421 * Creates a shallow clone of `object` composed of the specified properties.
1422 * Property names may be specified as individual arguments or as arrays of property
1423 * names. If `callback` is passed, it will be executed for each property in the
1424 * `object`, picking the properties `callback` returns truthy for. The `callback`
1425 * is bound to `thisArg` and invoked with three arguments; (value, key, object).
1430 * @param {Object} object The source object.
1431 * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
1432 * per iteration or properties to pick, either as individual arguments or arrays.
1433 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1434 * @returns {Object} Returns an object composed of the picked properties.
1437 * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
1438 * // => { 'name': 'moe' }
1440 * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
1441 * return key.charAt(0) != '_';
1443 * // => { 'name': 'moe' }
1445 function pick(object) {
1447 props = concat.apply(arrayRef, arguments),
1448 length = props.length,
1451 while (++index < length) {
1452 var prop = props[index];
1453 if (prop in object) {
1454 result[prop] = object[prop];
1461 * Creates an array composed of the own enumerable property values of `object`.
1466 * @param {Object} object The object to inspect.
1467 * @returns {Array} Returns a new array of property values.
1470 * _.values({ 'one': 1, 'two': 2, 'three': 3 });
1473 function values(object) {
1475 props = keys(object),
1476 length = props.length,
1477 result = Array(length);
1479 while (++index < length) {
1480 result[index] = object[props[index]];
1485 /*--------------------------------------------------------------------------*/
1488 * Checks if a given `target` element is present in a `collection` using strict
1489 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
1490 * as the offset from the end of the collection.
1495 * @category Collections
1496 * @param {Array|Object|String} collection The collection to iterate over.
1497 * @param {Mixed} target The value to check for.
1498 * @param {Number} [fromIndex=0] The index to search from.
1499 * @returns {Boolean} Returns `true` if the `target` element is found, else `false`.
1502 * _.contains([1, 2, 3], 1);
1505 * _.contains([1, 2, 3], 1, 2);
1508 * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
1511 * _.contains('curly', 'ur');
1514 function contains(collection, target) {
1515 var length = collection ? collection.length : 0,
1517 if (typeof length == 'number') {
1518 result = indexOf(collection, target) > -1;
1520 each(collection, function(value) {
1521 return (result = value === target) && indicatorObject;
1528 * Creates an object composed of keys returned from running each element of the
1529 * `collection` through the given `callback`. The corresponding value of each key
1530 * is the number of times the key was returned by the `callback`. The `callback`
1531 * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
1533 * If a property name is passed for `callback`, the created "_.pluck" style
1534 * callback will return the property value of the given element.
1536 * If an object is passed for `callback`, the created "_.where" style callback
1537 * will return `true` for elements that have the propeties of the given object,
1542 * @category Collections
1543 * @param {Array|Object|String} collection The collection to iterate over.
1544 * @param {Function|Object|String} [callback=identity] The function called per
1545 * iteration. If a property name or object is passed, it will be used to create
1546 * a "_.pluck" or "_.where" style callback, respectively.
1547 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1548 * @returns {Object} Returns the composed aggregate object.
1551 * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
1552 * // => { '4': 1, '6': 2 }
1554 * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
1555 * // => { '4': 1, '6': 2 }
1557 * _.countBy(['one', 'two', 'three'], 'length');
1558 * // => { '3': 2, '5': 1 }
1560 function countBy(collection, callback, thisArg) {
1562 callback = createCallback(callback, thisArg);
1564 forEach(collection, function(value, key, collection) {
1565 key = callback(value, key, collection) + '';
1566 (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
1572 * Checks if the `callback` returns a truthy value for **all** elements of a
1573 * `collection`. The `callback` is bound to `thisArg` and invoked with three
1574 * arguments; (value, index|key, collection).
1576 * If a property name is passed for `callback`, the created "_.pluck" style
1577 * callback will return the property value of the given element.
1579 * If an object is passed for `callback`, the created "_.where" style callback
1580 * will return `true` for elements that have the propeties of the given object,
1586 * @category Collections
1587 * @param {Array|Object|String} collection The collection to iterate over.
1588 * @param {Function|Object|String} [callback=identity] The function called per
1589 * iteration. If a property name or object is passed, it will be used to create
1590 * a "_.pluck" or "_.where" style callback, respectively.
1591 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1592 * @returns {Boolean} Returns `true` if all elements pass the callback check,
1596 * _.every([true, 1, null, 'yes'], Boolean);
1600 * { 'name': 'moe', 'age': 40 },
1601 * { 'name': 'larry', 'age': 50 }
1604 * // using "_.pluck" callback shorthand
1605 * _.every(stooges, 'age');
1608 * // using "_.where" callback shorthand
1609 * _.every(stooges, { 'age': 50 });
1612 function every(collection, callback, thisArg) {
1614 callback = createCallback(callback, thisArg);
1616 if (isArray(collection)) {
1618 length = collection.length;
1620 while (++index < length) {
1621 if (!(result = !!callback(collection[index], index, collection))) {
1626 each(collection, function(value, index, collection) {
1627 return !(result = !!callback(value, index, collection)) && indicatorObject;
1634 * Examines each element in a `collection`, returning an array of all elements
1635 * the `callback` returns truthy for. The `callback` is bound to `thisArg` and
1636 * invoked with three arguments; (value, index|key, collection).
1638 * If a property name is passed for `callback`, the created "_.pluck" style
1639 * callback will return the property value of the given element.
1641 * If an object is passed for `callback`, the created "_.where" style callback
1642 * will return `true` for elements that have the propeties of the given object,
1648 * @category Collections
1649 * @param {Array|Object|String} collection The collection to iterate over.
1650 * @param {Function|Object|String} [callback=identity] The function called per
1651 * iteration. If a property name or object is passed, it will be used to create
1652 * a "_.pluck" or "_.where" style callback, respectively.
1653 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1654 * @returns {Array} Returns a new array of elements that passed the callback check.
1657 * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
1661 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
1662 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
1665 * // using "_.pluck" callback shorthand
1666 * _.filter(food, 'organic');
1667 * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
1669 * // using "_.where" callback shorthand
1670 * _.filter(food, { 'type': 'fruit' });
1671 * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
1673 function filter(collection, callback, thisArg) {
1675 callback = createCallback(callback, thisArg);
1677 if (isArray(collection)) {
1679 length = collection.length;
1681 while (++index < length) {
1682 var value = collection[index];
1683 if (callback(value, index, collection)) {
1688 each(collection, function(value, index, collection) {
1689 if (callback(value, index, collection)) {
1698 * Examines each element in a `collection`, returning the first that the `callback`
1699 * returns truthy for. The `callback` is bound to `thisArg` and invoked with three
1700 * arguments; (value, index|key, collection).
1702 * If a property name is passed for `callback`, the created "_.pluck" style
1703 * callback will return the property value of the given element.
1705 * If an object is passed for `callback`, the created "_.where" style callback
1706 * will return `true` for elements that have the propeties of the given object,
1712 * @category Collections
1713 * @param {Array|Object|String} collection The collection to iterate over.
1714 * @param {Function|Object|String} [callback=identity] The function called per
1715 * iteration. If a property name or object is passed, it will be used to create
1716 * a "_.pluck" or "_.where" style callback, respectively.
1717 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1718 * @returns {Mixed} Returns the element that passed the callback check,
1722 * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
1726 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
1727 * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
1728 * { 'name': 'beet', 'organic': false, 'type': 'vegetable' },
1729 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
1732 * // using "_.where" callback shorthand
1733 * var veggie = _.find(food, { 'type': 'vegetable' });
1734 * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
1736 * // using "_.pluck" callback shorthand
1737 * var healthy = _.find(food, 'organic');
1738 * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
1740 function find(collection, callback, thisArg) {
1742 callback = createCallback(callback, thisArg);
1744 forEach(collection, function(value, index, collection) {
1745 if (callback(value, index, collection)) {
1747 return indicatorObject;
1753 function findWhere(object, properties) {
1754 return where(object, properties, true);
1758 * Iterates over a `collection`, executing the `callback` for each element in
1759 * the `collection`. The `callback` is bound to `thisArg` and invoked with three
1760 * arguments; (value, index|key, collection). Callbacks may exit iteration early
1761 * by explicitly returning `false`.
1766 * @category Collections
1767 * @param {Array|Object|String} collection The collection to iterate over.
1768 * @param {Function} [callback=identity] The function called per iteration.
1769 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1770 * @returns {Array|Object|String} Returns `collection`.
1773 * _([1, 2, 3]).forEach(alert).join(',');
1774 * // => alerts each number and returns '1,2,3'
1776 * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);
1777 * // => alerts each number value (order is not guaranteed)
1779 function forEach(collection, callback, thisArg) {
1780 if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
1782 length = collection.length;
1784 while (++index < length) {
1785 if (callback(collection[index], index, collection) === indicatorObject) {
1790 each(collection, callback, thisArg);
1795 * Creates an object composed of keys returned from running each element of the
1796 * `collection` through the `callback`. The corresponding value of each key is
1797 * an array of elements passed to `callback` that returned the key. The `callback`
1798 * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
1800 * If a property name is passed for `callback`, the created "_.pluck" style
1801 * callback will return the property value of the given element.
1803 * If an object is passed for `callback`, the created "_.where" style callback
1804 * will return `true` for elements that have the propeties of the given object,
1809 * @category Collections
1810 * @param {Array|Object|String} collection The collection to iterate over.
1811 * @param {Function|Object|String} [callback=identity] The function called per
1812 * iteration. If a property name or object is passed, it will be used to create
1813 * a "_.pluck" or "_.where" style callback, respectively.
1814 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1815 * @returns {Object} Returns the composed aggregate object.
1818 * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
1819 * // => { '4': [4.2], '6': [6.1, 6.4] }
1821 * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
1822 * // => { '4': [4.2], '6': [6.1, 6.4] }
1824 * // using "_.pluck" callback shorthand
1825 * _.groupBy(['one', 'two', 'three'], 'length');
1826 * // => { '3': ['one', 'two'], '5': ['three'] }
1828 function groupBy(collection, callback, thisArg) {
1830 callback = createCallback(callback, thisArg);
1832 forEach(collection, function(value, key, collection) {
1833 key = callback(value, key, collection) + '';
1834 (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
1840 * Invokes the method named by `methodName` on each element in the `collection`,
1841 * returning an array of the results of each invoked method. Additional arguments
1842 * will be passed to each invoked method. If `methodName` is a function, it will
1843 * be invoked for, and `this` bound to, each element in the `collection`.
1847 * @category Collections
1848 * @param {Array|Object|String} collection The collection to iterate over.
1849 * @param {Function|String} methodName The name of the method to invoke or
1850 * the function invoked per iteration.
1851 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
1852 * @returns {Array} Returns a new array of the results of each invoked method.
1855 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
1856 * // => [[1, 5, 7], [1, 2, 3]]
1858 * _.invoke([123, 456], String.prototype.split, '');
1859 * // => [['1', '2', '3'], ['4', '5', '6']]
1861 function invoke(collection, methodName) {
1862 var args = slice(arguments, 2),
1864 isFunc = typeof methodName == 'function',
1865 length = collection ? collection.length : 0,
1866 result = Array(typeof length == 'number' ? length : 0);
1868 forEach(collection, function(value) {
1869 result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
1875 * Creates an array of values by running each element in the `collection`
1876 * through the `callback`. The `callback` is bound to `thisArg` and invoked with
1877 * three arguments; (value, index|key, collection).
1879 * If a property name is passed for `callback`, the created "_.pluck" style
1880 * callback will return the property value of the given element.
1882 * If an object is passed for `callback`, the created "_.where" style callback
1883 * will return `true` for elements that have the propeties of the given object,
1889 * @category Collections
1890 * @param {Array|Object|String} collection The collection to iterate over.
1891 * @param {Function|Object|String} [callback=identity] The function called per
1892 * iteration. If a property name or object is passed, it will be used to create
1893 * a "_.pluck" or "_.where" style callback, respectively.
1894 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1895 * @returns {Array} Returns a new array of the results of each `callback` execution.
1898 * _.map([1, 2, 3], function(num) { return num * 3; });
1901 * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
1902 * // => [3, 6, 9] (order is not guaranteed)
1905 * { 'name': 'moe', 'age': 40 },
1906 * { 'name': 'larry', 'age': 50 }
1909 * // using "_.pluck" callback shorthand
1910 * _.map(stooges, 'name');
1911 * // => ['moe', 'larry']
1913 function map(collection, callback, thisArg) {
1915 length = collection ? collection.length : 0,
1916 result = Array(typeof length == 'number' ? length : 0);
1918 callback = createCallback(callback, thisArg);
1919 if (isArray(collection)) {
1920 while (++index < length) {
1921 result[index] = callback(collection[index], index, collection);
1924 each(collection, function(value, key, collection) {
1925 result[++index] = callback(value, key, collection);
1932 * Retrieves the maximum value of an `array`. If `callback` is passed,
1933 * it will be executed for each value in the `array` to generate the
1934 * criterion by which the value is ranked. The `callback` is bound to
1935 * `thisArg` and invoked with three arguments; (value, index, collection).
1937 * If a property name is passed for `callback`, the created "_.pluck" style
1938 * callback will return the property value of the given element.
1940 * If an object is passed for `callback`, the created "_.where" style callback
1941 * will return `true` for elements that have the propeties of the given object,
1946 * @category Collections
1947 * @param {Array|Object|String} collection The collection to iterate over.
1948 * @param {Function|Object|String} [callback=identity] The function called per
1949 * iteration. If a property name or object is passed, it will be used to create
1950 * a "_.pluck" or "_.where" style callback, respectively.
1951 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1952 * @returns {Mixed} Returns the maximum value.
1955 * _.max([4, 2, 8, 6]);
1959 * { 'name': 'moe', 'age': 40 },
1960 * { 'name': 'larry', 'age': 50 }
1963 * _.max(stooges, function(stooge) { return stooge.age; });
1964 * // => { 'name': 'larry', 'age': 50 };
1966 * // using "_.pluck" callback shorthand
1967 * _.max(stooges, 'age');
1968 * // => { 'name': 'larry', 'age': 50 };
1970 function max(collection, callback, thisArg) {
1971 var computed = -Infinity,
1974 if (!callback && isArray(collection)) {
1976 length = collection.length;
1978 while (++index < length) {
1979 var value = collection[index];
1980 if (value > result) {
1985 callback = createCallback(callback, thisArg);
1987 each(collection, function(value, index, collection) {
1988 var current = callback(value, index, collection);
1989 if (current > computed) {
1999 * Retrieves the minimum value of an `array`. If `callback` is passed,
2000 * it will be executed for each value in the `array` to generate the
2001 * criterion by which the value is ranked. The `callback` is bound to `thisArg`
2002 * and invoked with three arguments; (value, index, collection).
2004 * If a property name is passed for `callback`, the created "_.pluck" style
2005 * callback will return the property value of the given element.
2007 * If an object is passed for `callback`, the created "_.where" style callback
2008 * will return `true` for elements that have the propeties of the given object,
2013 * @category Collections
2014 * @param {Array|Object|String} collection The collection to iterate over.
2015 * @param {Function|Object|String} [callback=identity] The function called per
2016 * iteration. If a property name or object is passed, it will be used to create
2017 * a "_.pluck" or "_.where" style callback, respectively.
2018 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2019 * @returns {Mixed} Returns the minimum value.
2022 * _.min([4, 2, 8, 6]);
2026 * { 'name': 'moe', 'age': 40 },
2027 * { 'name': 'larry', 'age': 50 }
2030 * _.min(stooges, function(stooge) { return stooge.age; });
2031 * // => { 'name': 'moe', 'age': 40 };
2033 * // using "_.pluck" callback shorthand
2034 * _.min(stooges, 'age');
2035 * // => { 'name': 'moe', 'age': 40 };
2037 function min(collection, callback, thisArg) {
2038 var computed = Infinity,
2041 if (!callback && isArray(collection)) {
2043 length = collection.length;
2045 while (++index < length) {
2046 var value = collection[index];
2047 if (value < result) {
2052 callback = createCallback(callback, thisArg);
2054 each(collection, function(value, index, collection) {
2055 var current = callback(value, index, collection);
2056 if (current < computed) {
2066 * Retrieves the value of a specified property from all elements in the `collection`.
2071 * @category Collections
2072 * @param {Array|Object|String} collection The collection to iterate over.
2073 * @param {String} property The property to pluck.
2074 * @returns {Array} Returns a new array of property values.
2078 * { 'name': 'moe', 'age': 40 },
2079 * { 'name': 'larry', 'age': 50 }
2082 * _.pluck(stooges, 'name');
2083 * // => ['moe', 'larry']
2088 * Reduces a `collection` to a value that is the accumulated result of running
2089 * each element in the `collection` through the `callback`, where each successive
2090 * `callback` execution consumes the return value of the previous execution.
2091 * If `accumulator` is not passed, the first element of the `collection` will be
2092 * used as the initial `accumulator` value. The `callback` is bound to `thisArg`
2093 * and invoked with four arguments; (accumulator, value, index|key, collection).
2097 * @alias foldl, inject
2098 * @category Collections
2099 * @param {Array|Object|String} collection The collection to iterate over.
2100 * @param {Function} [callback=identity] The function called per iteration.
2101 * @param {Mixed} [accumulator] Initial value of the accumulator.
2102 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2103 * @returns {Mixed} Returns the accumulated value.
2106 * var sum = _.reduce([1, 2, 3], function(sum, num) {
2111 * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2112 * result[key] = num * 3;
2115 * // => { 'a': 3, 'b': 6, 'c': 9 }
2117 function reduce(collection, callback, accumulator, thisArg) {
2118 var noaccum = arguments.length < 3;
2119 callback = createCallback(callback, thisArg, 4);
2121 if (isArray(collection)) {
2123 length = collection.length;
2126 accumulator = collection[++index];
2128 while (++index < length) {
2129 accumulator = callback(accumulator, collection[index], index, collection);
2132 each(collection, function(value, index, collection) {
2133 accumulator = noaccum
2134 ? (noaccum = false, value)
2135 : callback(accumulator, value, index, collection)
2142 * This method is similar to `_.reduce`, except that it iterates over a
2143 * `collection` from right to left.
2148 * @category Collections
2149 * @param {Array|Object|String} collection The collection to iterate over.
2150 * @param {Function} [callback=identity] The function called per iteration.
2151 * @param {Mixed} [accumulator] Initial value of the accumulator.
2152 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2153 * @returns {Mixed} Returns the accumulated value.
2156 * var list = [[0, 1], [2, 3], [4, 5]];
2157 * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
2158 * // => [4, 5, 2, 3, 0, 1]
2160 function reduceRight(collection, callback, accumulator, thisArg) {
2161 var iterable = collection,
2162 length = collection ? collection.length : 0,
2163 noaccum = arguments.length < 3;
2165 if (typeof length != 'number') {
2166 var props = keys(collection);
2167 length = props.length;
2169 callback = createCallback(callback, thisArg, 4);
2170 forEach(collection, function(value, index, collection) {
2171 index = props ? props[--length] : --length;
2172 accumulator = noaccum
2173 ? (noaccum = false, iterable[index])
2174 : callback(accumulator, iterable[index], index, collection);
2180 * The opposite of `_.filter`, this method returns the elements of a
2181 * `collection` that `callback` does **not** return truthy for.
2183 * If a property name is passed for `callback`, the created "_.pluck" style
2184 * callback will return the property value of the given element.
2186 * If an object is passed for `callback`, the created "_.where" style callback
2187 * will return `true` for elements that have the propeties of the given object,
2192 * @category Collections
2193 * @param {Array|Object|String} collection The collection to iterate over.
2194 * @param {Function|Object|String} [callback=identity] The function called per
2195 * iteration. If a property name or object is passed, it will be used to create
2196 * a "_.pluck" or "_.where" style callback, respectively.
2197 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2198 * @returns {Array} Returns a new array of elements that did **not** pass the
2202 * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2206 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2207 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2210 * // using "_.pluck" callback shorthand
2211 * _.reject(food, 'organic');
2212 * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
2214 * // using "_.where" callback shorthand
2215 * _.reject(food, { 'type': 'fruit' });
2216 * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
2218 function reject(collection, callback, thisArg) {
2219 callback = createCallback(callback, thisArg);
2220 return filter(collection, function(value, index, collection) {
2221 return !callback(value, index, collection);
2226 * Creates an array of shuffled `array` values, using a version of the
2227 * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
2231 * @category Collections
2232 * @param {Array|Object|String} collection The collection to shuffle.
2233 * @returns {Array} Returns a new shuffled collection.
2236 * _.shuffle([1, 2, 3, 4, 5, 6]);
2237 * // => [4, 1, 6, 3, 5, 2]
2239 function shuffle(collection) {
2241 length = collection ? collection.length : 0,
2242 result = Array(typeof length == 'number' ? length : 0);
2244 forEach(collection, function(value) {
2245 var rand = floor(nativeRandom() * (++index + 1));
2246 result[index] = result[rand];
2247 result[rand] = value;
2253 * Gets the size of the `collection` by returning `collection.length` for arrays
2254 * and array-like objects or the number of own enumerable properties for objects.
2258 * @category Collections
2259 * @param {Array|Object|String} collection The collection to inspect.
2260 * @returns {Number} Returns `collection.length` or number of own enumerable properties.
2266 * _.size({ 'one': 1, 'two': 2, 'three': 3 });
2272 function size(collection) {
2273 var length = collection ? collection.length : 0;
2274 return typeof length == 'number' ? length : keys(collection).length;
2278 * Checks if the `callback` returns a truthy value for **any** element of a
2279 * `collection`. The function returns as soon as it finds passing value, and
2280 * does not iterate over the entire `collection`. The `callback` is bound to
2281 * `thisArg` and invoked with three arguments; (value, index|key, collection).
2283 * If a property name is passed for `callback`, the created "_.pluck" style
2284 * callback will return the property value of the given element.
2286 * If an object is passed for `callback`, the created "_.where" style callback
2287 * will return `true` for elements that have the propeties of the given object,
2293 * @category Collections
2294 * @param {Array|Object|String} collection The collection to iterate over.
2295 * @param {Function|Object|String} [callback=identity] The function called per
2296 * iteration. If a property name or object is passed, it will be used to create
2297 * a "_.pluck" or "_.where" style callback, respectively.
2298 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2299 * @returns {Boolean} Returns `true` if any element passes the callback check,
2303 * _.some([null, 0, 'yes', false], Boolean);
2307 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2308 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2311 * // using "_.pluck" callback shorthand
2312 * _.some(food, 'organic');
2315 * // using "_.where" callback shorthand
2316 * _.some(food, { 'type': 'meat' });
2319 function some(collection, callback, thisArg) {
2321 callback = createCallback(callback, thisArg);
2323 if (isArray(collection)) {
2325 length = collection.length;
2327 while (++index < length) {
2328 if ((result = callback(collection[index], index, collection))) {
2333 each(collection, function(value, index, collection) {
2334 return (result = callback(value, index, collection)) && indicatorObject;
2341 * Creates an array of elements, sorted in ascending order by the results of
2342 * running each element in the `collection` through the `callback`. This method
2343 * performs a stable sort, that is, it will preserve the original sort order of
2344 * equal elements. The `callback` is bound to `thisArg` and invoked with three
2345 * arguments; (value, index|key, collection).
2347 * If a property name is passed for `callback`, the created "_.pluck" style
2348 * callback will return the property value of the given element.
2350 * If an object is passed for `callback`, the created "_.where" style callback
2351 * will return `true` for elements that have the propeties of the given object,
2356 * @category Collections
2357 * @param {Array|Object|String} collection The collection to iterate over.
2358 * @param {Function|Object|String} [callback=identity] The function called per
2359 * iteration. If a property name or object is passed, it will be used to create
2360 * a "_.pluck" or "_.where" style callback, respectively.
2361 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2362 * @returns {Array} Returns a new array of sorted elements.
2365 * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
2368 * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
2371 * // using "_.pluck" callback shorthand
2372 * _.sortBy(['banana', 'strawberry', 'apple'], 'length');
2373 * // => ['apple', 'banana', 'strawberry']
2375 function sortBy(collection, callback, thisArg) {
2377 length = collection ? collection.length : 0,
2378 result = Array(typeof length == 'number' ? length : 0);
2380 callback = createCallback(callback, thisArg);
2381 forEach(collection, function(value, key, collection) {
2383 'criteria': callback(value, key, collection),
2389 length = result.length;
2390 result.sort(compareAscending);
2392 result[length] = result[length].value;
2398 * Converts the `collection` to an array.
2402 * @category Collections
2403 * @param {Array|Object|String} collection The collection to convert.
2404 * @returns {Array} Returns the new converted array.
2407 * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
2410 function toArray(collection) {
2411 if (collection && typeof collection.length == 'number') {
2412 return slice(collection);
2414 return values(collection);
2418 * Examines each element in a `collection`, returning an array of all elements
2419 * that have the given `properties`. When checking `properties`, this method
2420 * performs a deep comparison between values to determine if they are equivalent
2426 * @category Collections
2427 * @param {Array|Object|String} collection The collection to iterate over.
2428 * @param {Object} properties The object of property values to filter by.
2429 * @returns {Array} Returns a new array of elements that have the given `properties`.
2433 * { 'name': 'moe', 'age': 40 },
2434 * { 'name': 'larry', 'age': 50 }
2437 * _.where(stooges, { 'age': 40 });
2438 * // => [{ 'name': 'moe', 'age': 40 }]
2440 function where(collection, properties, first) {
2441 return (first && isEmpty(properties))
2443 : (first ? find : filter)(collection, properties);
2446 /*--------------------------------------------------------------------------*/
2449 * Creates an array with all falsey values of `array` removed. The values
2450 * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
2455 * @param {Array} array The array to compact.
2456 * @returns {Array} Returns a new filtered array.
2459 * _.compact([0, 1, false, 2, '', 3]);
2462 function compact(array) {
2464 length = array ? array.length : 0,
2467 while (++index < length) {
2468 var value = array[index];
2477 * Creates an array of `array` elements not present in the other arrays
2478 * using strict equality for comparisons, i.e. `===`.
2483 * @param {Array} array The array to process.
2484 * @param {Array} [array1, array2, ...] Arrays to check.
2485 * @returns {Array} Returns a new array of `array` elements not present in the
2489 * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
2492 function difference(array) {
2494 length = array.length,
2495 flattened = concat.apply(arrayRef, arguments),
2498 while (++index < length) {
2499 var value = array[index]
2500 if (indexOf(flattened, value, length) < 0) {
2508 * Gets the first element of the `array`. If a number `n` is passed, the first
2509 * `n` elements of the `array` are returned. If a `callback` function is passed,
2510 * the first elements the `callback` returns truthy for are returned. The `callback`
2511 * is bound to `thisArg` and invoked with three arguments; (value, index, array).
2513 * If a property name is passed for `callback`, the created "_.pluck" style
2514 * callback will return the property value of the given element.
2516 * If an object is passed for `callback`, the created "_.where" style callback
2517 * will return `true` for elements that have the propeties of the given object,
2524 * @param {Array} array The array to query.
2525 * @param {Function|Object|Number|String} [callback|n] The function called
2526 * per element or the number of elements to return. If a property name or
2527 * object is passed, it will be used to create a "_.pluck" or "_.where"
2528 * style callback, respectively.
2529 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2530 * @returns {Mixed} Returns the first element(s) of `array`.
2533 * _.first([1, 2, 3]);
2536 * _.first([1, 2, 3], 2);
2539 * _.first([1, 2, 3], function(num) {
2545 * { 'name': 'banana', 'organic': true },
2546 * { 'name': 'beet', 'organic': false },
2549 * // using "_.pluck" callback shorthand
2550 * _.first(food, 'organic');
2551 * // => [{ 'name': 'banana', 'organic': true }]
2554 * { 'name': 'apple', 'type': 'fruit' },
2555 * { 'name': 'banana', 'type': 'fruit' },
2556 * { 'name': 'beet', 'type': 'vegetable' }
2559 * // using "_.where" callback shorthand
2560 * _.first(food, { 'type': 'fruit' });
2561 * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
2563 function first(array, callback, thisArg) {
2566 length = array.length;
2568 if (typeof callback != 'number' && callback != null) {
2570 callback = createCallback(callback, thisArg);
2571 while (++index < length && callback(array[index], index, array)) {
2576 if (n == null || thisArg) {
2580 return slice(array, 0, nativeMin(nativeMax(0, n), length));
2585 * Flattens a nested array (the nesting can be to any depth). If `shallow` is
2586 * truthy, `array` will only be flattened a single level.
2591 * @param {Array} array The array to compact.
2592 * @param {Boolean} shallow A flag to indicate only flattening a single level.
2593 * @returns {Array} Returns a new flattened array.
2596 * _.flatten([1, [2], [3, [[4]]]]);
2597 * // => [1, 2, 3, 4];
2599 * _.flatten([1, [2], [3, [[4]]]], true);
2600 * // => [1, 2, 3, [[4]]];
2602 function flatten(array, shallow) {
2604 length = array ? array.length : 0,
2607 while (++index < length) {
2608 var value = array[index];
2610 // recursively flatten arrays (susceptible to call stack limits)
2611 if (isArray(value)) {
2612 push.apply(result, shallow ? value : flatten(value));
2621 * Gets the index at which the first occurrence of `value` is found using
2622 * strict equality for comparisons, i.e. `===`. If the `array` is already
2623 * sorted, passing `true` for `fromIndex` will run a faster binary search.
2628 * @param {Array} array The array to search.
2629 * @param {Mixed} value The value to search for.
2630 * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to
2631 * perform a binary search on a sorted `array`.
2632 * @returns {Number} Returns the index of the matched value or `-1`.
2635 * _.indexOf([1, 2, 3, 1, 2, 3], 2);
2638 * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
2641 * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
2644 function indexOf(array, value, fromIndex) {
2646 length = array ? array.length : 0;
2648 if (typeof fromIndex == 'number') {
2649 index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
2650 } else if (fromIndex) {
2651 index = sortedIndex(array, value);
2652 return array[index] === value ? index : -1;
2654 while (++index < length) {
2655 if (array[index] === value) {
2663 * Gets all but the last element of `array`. If a number `n` is passed, the
2664 * last `n` elements are excluded from the result. If a `callback` function
2665 * is passed, the last elements the `callback` returns truthy for are excluded
2666 * from the result. The `callback` is bound to `thisArg` and invoked with three
2667 * arguments; (value, index, array).
2669 * If a property name is passed for `callback`, the created "_.pluck" style
2670 * callback will return the property value of the given element.
2672 * If an object is passed for `callback`, the created "_.where" style callback
2673 * will return `true` for elements that have the propeties of the given object,
2679 * @param {Array} array The array to query.
2680 * @param {Function|Object|Number|String} [callback|n=1] The function called
2681 * per element or the number of elements to exclude. If a property name or
2682 * object is passed, it will be used to create a "_.pluck" or "_.where"
2683 * style callback, respectively.
2684 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2685 * @returns {Array} Returns a slice of `array`.
2688 * _.initial([1, 2, 3]);
2691 * _.initial([1, 2, 3], 2);
2694 * _.initial([1, 2, 3], function(num) {
2700 * { 'name': 'beet', 'organic': false },
2701 * { 'name': 'carrot', 'organic': true }
2704 * // using "_.pluck" callback shorthand
2705 * _.initial(food, 'organic');
2706 * // => [{ 'name': 'beet', 'organic': false }]
2709 * { 'name': 'banana', 'type': 'fruit' },
2710 * { 'name': 'beet', 'type': 'vegetable' },
2711 * { 'name': 'carrot', 'type': 'vegetable' }
2714 * // using "_.where" callback shorthand
2715 * _.initial(food, { 'type': 'vegetable' });
2716 * // => [{ 'name': 'banana', 'type': 'fruit' }]
2718 function initial(array, callback, thisArg) {
2723 length = array.length;
2725 if (typeof callback != 'number' && callback != null) {
2727 callback = createCallback(callback, thisArg);
2728 while (index-- && callback(array[index], index, array)) {
2732 n = (callback == null || thisArg) ? 1 : callback || n;
2734 return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
2738 * Computes the intersection of all the passed-in arrays using strict equality
2739 * for comparisons, i.e. `===`.
2744 * @param {Array} [array1, array2, ...] Arrays to process.
2745 * @returns {Array} Returns a new array of unique elements that are present
2746 * in **all** of the arrays.
2749 * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
2752 function intersection(array) {
2753 var args = arguments,
2754 argsLength = args.length,
2756 length = array ? array.length : 0,
2760 while (++index < length) {
2761 var value = array[index];
2762 if (indexOf(result, value) < 0) {
2763 var argsIndex = argsLength;
2764 while (--argsIndex) {
2765 if (indexOf(args[argsIndex], value) < 0) {
2776 * Gets the last element of the `array`. If a number `n` is passed, the last
2777 * `n` elements of the `array` are returned. If a `callback` function is passed,
2778 * the last elements the `callback` returns truthy for are returned. The `callback`
2779 * is bound to `thisArg` and invoked with three arguments; (value, index, array).
2782 * If a property name is passed for `callback`, the created "_.pluck" style
2783 * callback will return the property value of the given element.
2785 * If an object is passed for `callback`, the created "_.where" style callback
2786 * will return `true` for elements that have the propeties of the given object,
2792 * @param {Array} array The array to query.
2793 * @param {Function|Object|Number|String} [callback|n] The function called
2794 * per element or the number of elements to return. If a property name or
2795 * object is passed, it will be used to create a "_.pluck" or "_.where"
2796 * style callback, respectively.
2797 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2798 * @returns {Mixed} Returns the last element(s) of `array`.
2801 * _.last([1, 2, 3]);
2804 * _.last([1, 2, 3], 2);
2807 * _.last([1, 2, 3], function(num) {
2813 * { 'name': 'beet', 'organic': false },
2814 * { 'name': 'carrot', 'organic': true }
2817 * // using "_.pluck" callback shorthand
2818 * _.last(food, 'organic');
2819 * // => [{ 'name': 'carrot', 'organic': true }]
2822 * { 'name': 'banana', 'type': 'fruit' },
2823 * { 'name': 'beet', 'type': 'vegetable' },
2824 * { 'name': 'carrot', 'type': 'vegetable' }
2827 * // using "_.where" callback shorthand
2828 * _.last(food, { 'type': 'vegetable' });
2829 * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
2831 function last(array, callback, thisArg) {
2834 length = array.length;
2836 if (typeof callback != 'number' && callback != null) {
2838 callback = createCallback(callback, thisArg);
2839 while (index-- && callback(array[index], index, array)) {
2844 if (n == null || thisArg) {
2845 return array[length - 1];
2848 return slice(array, nativeMax(0, length - n));
2853 * Gets the index at which the last occurrence of `value` is found using strict
2854 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
2855 * as the offset from the end of the collection.
2860 * @param {Array} array The array to search.
2861 * @param {Mixed} value The value to search for.
2862 * @param {Number} [fromIndex=array.length-1] The index to search from.
2863 * @returns {Number} Returns the index of the matched value or `-1`.
2866 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
2869 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
2872 function lastIndexOf(array, value, fromIndex) {
2873 var index = array ? array.length : 0;
2874 if (typeof fromIndex == 'number') {
2875 index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
2878 if (array[index] === value) {
2886 * Creates an object composed from arrays of `keys` and `values`. Pass either
2887 * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or
2888 * two arrays, one of `keys` and one of corresponding `values`.
2893 * @param {Array} keys The array of keys.
2894 * @param {Array} [values=[]] The array of values.
2895 * @returns {Object} Returns an object composed of the given keys and
2896 * corresponding values.
2899 * _.object(['moe', 'larry'], [30, 40]);
2900 * // => { 'moe': 30, 'larry': 40 }
2902 function object(keys, values) {
2904 length = keys ? keys.length : 0,
2907 while (++index < length) {
2908 var key = keys[index];
2910 result[key] = values[index];
2912 result[key[0]] = key[1];
2919 * Creates an array of numbers (positive and/or negative) progressing from
2920 * `start` up to but not including `end`.
2925 * @param {Number} [start=0] The start of the range.
2926 * @param {Number} end The end of the range.
2927 * @param {Number} [step=1] The value to increment or descrement by.
2928 * @returns {Array} Returns a new range array.
2932 * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2935 * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2937 * _.range(0, 30, 5);
2938 * // => [0, 5, 10, 15, 20, 25]
2940 * _.range(0, -10, -1);
2941 * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
2946 function range(start, end, step) {
2947 start = +start || 0;
2954 // use `Array(length)` so V8 will avoid the slower "dictionary" mode
2955 // http://youtu.be/XAqIpGU8ZZk#t=17m25s
2957 length = nativeMax(0, ceil((end - start) / step)),
2958 result = Array(length);
2960 while (++index < length) {
2961 result[index] = start;
2968 * The opposite of `_.initial`, this method gets all but the first value of `array`.
2969 * If a number `n` is passed, the first `n` values are excluded from the result.
2970 * If a `callback` function is passed, the first elements the `callback` returns
2971 * truthy for are excluded from the result. The `callback` is bound to `thisArg`
2972 * and invoked with three arguments; (value, index, array).
2974 * If a property name is passed for `callback`, the created "_.pluck" style
2975 * callback will return the property value of the given element.
2977 * If an object is passed for `callback`, the created "_.where" style callback
2978 * will return `true` for elements that have the propeties of the given object,
2985 * @param {Array} array The array to query.
2986 * @param {Function|Object|Number|String} [callback|n=1] The function called
2987 * per element or the number of elements to exclude. If a property name or
2988 * object is passed, it will be used to create a "_.pluck" or "_.where"
2989 * style callback, respectively.
2990 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2991 * @returns {Array} Returns a slice of `array`.
2994 * _.rest([1, 2, 3]);
2997 * _.rest([1, 2, 3], 2);
3000 * _.rest([1, 2, 3], function(num) {
3006 * { 'name': 'banana', 'organic': true },
3007 * { 'name': 'beet', 'organic': false },
3010 * // using "_.pluck" callback shorthand
3011 * _.rest(food, 'organic');
3012 * // => [{ 'name': 'beet', 'organic': false }]
3015 * { 'name': 'apple', 'type': 'fruit' },
3016 * { 'name': 'banana', 'type': 'fruit' },
3017 * { 'name': 'beet', 'type': 'vegetable' }
3020 * // using "_.where" callback shorthand
3021 * _.rest(food, { 'type': 'fruit' });
3022 * // => [{ 'name': 'beet', 'type': 'vegetable' }]
3024 function rest(array, callback, thisArg) {
3025 if (typeof callback != 'number' && callback != null) {
3028 length = array ? array.length : 0;
3030 callback = createCallback(callback, thisArg);
3031 while (++index < length && callback(array[index], index, array)) {
3035 n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
3037 return slice(array, n);
3041 * Uses a binary search to determine the smallest index at which the `value`
3042 * should be inserted into `array` in order to maintain the sort order of the
3043 * sorted `array`. If `callback` is passed, it will be executed for `value` and
3044 * each element in `array` to compute their sort ranking. The `callback` is
3045 * bound to `thisArg` and invoked with one argument; (value).
3047 * If a property name is passed for `callback`, the created "_.pluck" style
3048 * callback will return the property value of the given element.
3050 * If an object is passed for `callback`, the created "_.where" style callback
3051 * will return `true` for elements that have the propeties of the given object,
3057 * @param {Array} array The array to iterate over.
3058 * @param {Mixed} value The value to evaluate.
3059 * @param {Function|Object|String} [callback=identity] The function called per
3060 * iteration. If a property name or object is passed, it will be used to create
3061 * a "_.pluck" or "_.where" style callback, respectively.
3062 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3063 * @returns {Number} Returns the index at which the value should be inserted
3067 * _.sortedIndex([20, 30, 50], 40);
3070 * // using "_.pluck" callback shorthand
3071 * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
3075 * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
3078 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3079 * return dict.wordToNumber[word];
3083 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3084 * return this.wordToNumber[word];
3088 function sortedIndex(array, value, callback, thisArg) {
3090 high = array ? array.length : low;
3092 // explicitly reference `identity` for better inlining in Firefox
3093 callback = callback ? createCallback(callback, thisArg, 1) : identity;
3094 value = callback(value);
3096 while (low < high) {
3097 var mid = (low + high) >>> 1;
3098 callback(array[mid]) < value
3106 * Computes the union of the passed-in arrays using strict equality for
3107 * comparisons, i.e. `===`.
3112 * @param {Array} [array1, array2, ...] Arrays to process.
3113 * @returns {Array} Returns a new array of unique values, in order, that are
3114 * present in one or more of the arrays.
3117 * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
3118 * // => [1, 2, 3, 101, 10]
3121 return uniq(concat.apply(arrayRef, arguments));
3125 * Creates a duplicate-value-free version of the `array` using strict equality
3126 * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
3127 * for `isSorted` will run a faster algorithm. If `callback` is passed, each
3128 * element of `array` is passed through a callback` before uniqueness is computed.
3129 * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
3131 * If a property name is passed for `callback`, the created "_.pluck" style
3132 * callback will return the property value of the given element.
3134 * If an object is passed for `callback`, the created "_.where" style callback
3135 * will return `true` for elements that have the propeties of the given object,
3142 * @param {Array} array The array to process.
3143 * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
3144 * @param {Function|Object|String} [callback=identity] The function called per
3145 * iteration. If a property name or object is passed, it will be used to create
3146 * a "_.pluck" or "_.where" style callback, respectively.
3147 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3148 * @returns {Array} Returns a duplicate-value-free array.
3151 * _.uniq([1, 2, 1, 3, 1]);
3154 * _.uniq([1, 1, 2, 2, 3], true);
3157 * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); });
3160 * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math);
3163 * // using "_.pluck" callback shorthand
3164 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
3165 * // => [{ 'x': 1 }, { 'x': 2 }]
3167 function uniq(array, isSorted, callback, thisArg) {
3169 length = array ? array.length : 0,
3173 if (typeof isSorted == 'function') {
3175 callback = isSorted;
3180 callback = createCallback(callback, thisArg);
3182 while (++index < length) {
3183 var value = array[index],
3184 computed = callback ? callback(value, index, array) : value;
3187 ? !index || seen[seen.length - 1] !== computed
3188 : indexOf(seen, computed) < 0
3191 seen.push(computed);
3200 * Creates an array with all occurrences of the passed values removed using
3201 * strict equality for comparisons, i.e. `===`.
3206 * @param {Array} array The array to filter.
3207 * @param {Mixed} [value1, value2, ...] Values to remove.
3208 * @returns {Array} Returns a new filtered array.
3211 * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
3214 function without(array) {
3216 length = array.length,
3219 while (++index < length) {
3220 var value = array[index]
3221 if (indexOf(arguments, value, 1) < 0) {
3229 * Groups the elements of each array at their corresponding indexes. Useful for
3230 * separate data sources that are coordinated through matching array indexes.
3231 * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix
3232 * in a similar fashion.
3237 * @param {Array} [array1, array2, ...] Arrays to process.
3238 * @returns {Array} Returns a new array of grouped elements.
3241 * _.zip(['moe', 'larry'], [30, 40], [true, false]);
3242 * // => [['moe', 30, true], ['larry', 40, false]]
3244 function zip(array) {
3246 length = array ? max(pluck(arguments, 'length')) : 0,
3247 result = Array(length);
3249 while (++index < length) {
3250 result[index] = pluck(arguments, index);
3255 /*--------------------------------------------------------------------------*/
3258 * Creates a function that is restricted to executing `func` only after it is
3259 * called `n` times. The `func` is executed with the `this` binding of the
3264 * @category Functions
3265 * @param {Number} n The number of times the function must be called before
3267 * @param {Function} func The function to restrict.
3268 * @returns {Function} Returns the new restricted function.
3271 * var renderNotes = _.after(notes.length, render);
3272 * _.forEach(notes, function(note) {
3273 * note.asyncSave({ 'success': renderNotes });
3275 * // `renderNotes` is run once, after all notes have saved
3277 function after(n, func) {
3283 return func.apply(this, arguments);
3289 * Creates a function that, when called, invokes `func` with the `this`
3290 * binding of `thisArg` and prepends any additional `bind` arguments to those
3291 * passed to the bound function.
3295 * @category Functions
3296 * @param {Function} func The function to bind.
3297 * @param {Mixed} [thisArg] The `this` binding of `func`.
3298 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
3299 * @returns {Function} Returns the new bound function.
3302 * var func = function(greeting) {
3303 * return greeting + ' ' + this.name;
3306 * func = _.bind(func, { 'name': 'moe' }, 'hi');
3310 function bind(func, thisArg) {
3311 // use `Function#bind` if it exists and is fast
3312 // (in V8 `Function#bind` is slower except when partially applied)
3313 return isBindFast || (nativeBind && arguments.length > 2)
3314 ? nativeBind.call.apply(nativeBind, arguments)
3315 : createBound(func, thisArg, slice(arguments, 2));
3319 * Binds methods on `object` to `object`, overwriting the existing method.
3320 * Method names may be specified as individual arguments or as arrays of method
3321 * names. If no method names are provided, all the function properties of `object`
3326 * @category Functions
3327 * @param {Object} object The object to bind and assign the bound methods to.
3328 * @param {String} [methodName1, methodName2, ...] Method names on the object to bind.
3329 * @returns {Object} Returns `object`.
3334 * 'onClick': function() { alert('clicked ' + this.label); }
3338 * jQuery('#docs').on('click', view.onClick);
3339 * // => alerts 'clicked docs', when the button is clicked
3341 function bindAll(object) {
3342 var funcs = concat.apply(arrayRef, arguments),
3343 index = funcs.length > 1 ? 0 : (funcs = functions(object), -1),
3344 length = funcs.length;
3346 while (++index < length) {
3347 var key = funcs[index];
3348 object[key] = bind(object[key], object);
3354 * Creates a function that is the composition of the passed functions,
3355 * where each function consumes the return value of the function that follows.
3356 * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
3357 * Each function is executed with the `this` binding of the composed function.
3361 * @category Functions
3362 * @param {Function} [func1, func2, ...] Functions to compose.
3363 * @returns {Function} Returns the new composed function.
3366 * var greet = function(name) { return 'hi ' + name; };
3367 * var exclaim = function(statement) { return statement + '!'; };
3368 * var welcome = _.compose(exclaim, greet);
3372 function compose() {
3373 var funcs = arguments;
3375 var args = arguments,
3376 length = funcs.length;
3379 args = [funcs[length].apply(this, args)];
3386 * Creates a function that will delay the execution of `func` until after
3387 * `wait` milliseconds have elapsed since the last time it was invoked. Pass
3388 * `true` for `immediate` to cause debounce to invoke `func` on the leading,
3389 * instead of the trailing, edge of the `wait` timeout. Subsequent calls to
3390 * the debounced function will return the result of the last `func` call.
3394 * @category Functions
3395 * @param {Function} func The function to debounce.
3396 * @param {Number} wait The number of milliseconds to delay.
3397 * @param {Boolean} immediate A flag to indicate execution is on the leading
3398 * edge of the timeout.
3399 * @returns {Function} Returns the new debounced function.
3402 * var lazyLayout = _.debounce(calculateLayout, 300);
3403 * jQuery(window).on('resize', lazyLayout);
3405 function debounce(func, wait, immediate) {
3411 function delayed() {
3414 result = func.apply(thisArg, args);
3418 var isImmediate = immediate && !timeoutId;
3422 clearTimeout(timeoutId);
3423 timeoutId = setTimeout(delayed, wait);
3426 result = func.apply(thisArg, args);
3433 * Executes the `func` function after `wait` milliseconds. Additional arguments
3434 * will be passed to `func` when it is invoked.
3438 * @category Functions
3439 * @param {Function} func The function to delay.
3440 * @param {Number} wait The number of milliseconds to delay execution.
3441 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
3442 * @returns {Number} Returns the `setTimeout` timeout id.
3445 * var log = _.bind(console.log, console);
3446 * _.delay(log, 1000, 'logged later');
3447 * // => 'logged later' (Appears after one second.)
3449 function delay(func, wait) {
3450 var args = slice(arguments, 2);
3451 return setTimeout(function() { func.apply(undefined, args); }, wait);
3455 * Defers executing the `func` function until the current call stack has cleared.
3456 * Additional arguments will be passed to `func` when it is invoked.
3460 * @category Functions
3461 * @param {Function} func The function to defer.
3462 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
3463 * @returns {Number} Returns the `setTimeout` timeout id.
3466 * _.defer(function() { alert('deferred'); });
3467 * // returns from the function before `alert` is called
3469 function defer(func) {
3470 var args = slice(arguments, 1);
3471 return setTimeout(function() { func.apply(undefined, args); }, 1);
3473 // use `setImmediate` if it's available in Node.js
3474 if (isV8 && freeModule && typeof setImmediate == 'function') {
3475 defer = bind(setImmediate, window);
3479 * Creates a function that memoizes the result of `func`. If `resolver` is
3480 * passed, it will be used to determine the cache key for storing the result
3481 * based on the arguments passed to the memoized function. By default, the first
3482 * argument passed to the memoized function is used as the cache key. The `func`
3483 * is executed with the `this` binding of the memoized function.
3487 * @category Functions
3488 * @param {Function} func The function to have its output memoized.
3489 * @param {Function} [resolver] A function used to resolve the cache key.
3490 * @returns {Function} Returns the new memoizing function.
3493 * var fibonacci = _.memoize(function(n) {
3494 * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
3497 function memoize(func, resolver) {
3500 var key = (resolver ? resolver.apply(this, arguments) : arguments[0]) + '';
3501 return hasOwnProperty.call(cache, key)
3503 : (cache[key] = func.apply(this, arguments));
3508 * Creates a function that is restricted to execute `func` once. Repeat calls to
3509 * the function will return the value of the first call. The `func` is executed
3510 * with the `this` binding of the created function.
3514 * @category Functions
3515 * @param {Function} func The function to restrict.
3516 * @returns {Function} Returns the new restricted function.
3519 * var initialize = _.once(createApplication);
3522 * // `initialize` executes `createApplication` once
3524 function once(func) {
3533 result = func.apply(this, arguments);
3535 // clear the `func` variable so the function may be garbage collected
3542 * Creates a function that, when called, invokes `func` with any additional
3543 * `partial` arguments prepended to those passed to the new function. This
3544 * method is similar to `_.bind`, except it does **not** alter the `this` binding.
3548 * @category Functions
3549 * @param {Function} func The function to partially apply arguments to.
3550 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
3551 * @returns {Function} Returns the new partially applied function.
3554 * var greet = function(greeting, name) { return greeting + ' ' + name; };
3555 * var hi = _.partial(greet, 'hi');
3559 function partial(func) {
3560 return createBound(func, slice(arguments, 1));
3564 * Creates a function that, when executed, will only call the `func`
3565 * function at most once per every `wait` milliseconds. If the throttled
3566 * function is invoked more than once during the `wait` timeout, `func` will
3567 * also be called on the trailing edge of the timeout. Subsequent calls to the
3568 * throttled function will return the result of the last `func` call.
3572 * @category Functions
3573 * @param {Function} func The function to throttle.
3574 * @param {Number} wait The number of milliseconds to throttle executions to.
3575 * @returns {Function} Returns the new throttled function.
3578 * var throttled = _.throttle(updatePosition, 100);
3579 * jQuery(window).on('scroll', throttled);
3581 function throttle(func, wait) {
3588 function trailingCall() {
3589 lastCalled = new Date;
3591 result = func.apply(thisArg, args);
3595 remaining = wait - (now - lastCalled);
3600 if (remaining <= 0) {
3601 clearTimeout(timeoutId);
3604 result = func.apply(thisArg, args);
3606 else if (!timeoutId) {
3607 timeoutId = setTimeout(trailingCall, remaining);
3614 * Creates a function that passes `value` to the `wrapper` function as its
3615 * first argument. Additional arguments passed to the function are appended
3616 * to those passed to the `wrapper` function. The `wrapper` is executed with
3617 * the `this` binding of the created function.
3621 * @category Functions
3622 * @param {Mixed} value The value to wrap.
3623 * @param {Function} wrapper The wrapper function.
3624 * @returns {Function} Returns the new function.
3627 * var hello = function(name) { return 'hello ' + name; };
3628 * hello = _.wrap(hello, function(func) {
3629 * return 'before, ' + func('moe') + ', after';
3632 * // => 'before, hello moe, after'
3634 function wrap(value, wrapper) {
3637 push.apply(args, arguments);
3638 return wrapper.apply(this, args);
3642 /*--------------------------------------------------------------------------*/
3645 * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
3646 * corresponding HTML entities.
3650 * @category Utilities
3651 * @param {String} string The string to escape.
3652 * @returns {String} Returns the escaped string.
3655 * _.escape('Moe, Larry & Curly');
3656 * // => 'Moe, Larry & Curly'
3658 function escape(string) {
3659 return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar);
3663 * This function returns the first argument passed to it.
3667 * @category Utilities
3668 * @param {Mixed} value Any value.
3669 * @returns {Mixed} Returns `value`.
3672 * var moe = { 'name': 'moe' };
3673 * moe === _.identity(moe);
3676 function identity(value) {
3681 * Adds functions properties of `object` to the `lodash` function and chainable
3686 * @category Utilities
3687 * @param {Object} object The object of function properties to add to `lodash`.
3691 * 'capitalize': function(string) {
3692 * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
3696 * _.capitalize('moe');
3699 * _('moe').capitalize();
3702 function mixin(object) {
3703 forEach(functions(object), function(methodName) {
3704 var func = lodash[methodName] = object[methodName];
3706 lodash.prototype[methodName] = function() {
3707 var args = [this.__wrapped__];
3708 push.apply(args, arguments);
3710 var result = func.apply(lodash, args);
3711 if (this.__chain__) {
3712 result = new lodash(result);
3713 result.__chain__ = true;
3721 * Reverts the '_' variable to its previous value and returns a reference to
3722 * the `lodash` function.
3726 * @category Utilities
3727 * @returns {Function} Returns the `lodash` function.
3730 * var lodash = _.noConflict();
3732 function noConflict() {
3738 * Produces a random number between `min` and `max` (inclusive). If only one
3739 * argument is passed, a number between `0` and the given number will be returned.
3743 * @category Utilities
3744 * @param {Number} [min=0] The minimum possible value.
3745 * @param {Number} [max=1] The maximum possible value.
3746 * @returns {Number} Returns a random number.
3750 * // => a number between 0 and 5
3753 * // => also a number between 0 and 5
3755 function random(min, max) {
3756 if (min == null && max == null) {
3764 return min + floor(nativeRandom() * ((+max || 0) - min + 1));
3768 * Resolves the value of `property` on `object`. If `property` is a function,
3769 * it will be invoked and its result returned, else the property value is
3770 * returned. If `object` is falsey, then `null` is returned.
3774 * @category Utilities
3775 * @param {Object} object The object to inspect.
3776 * @param {String} property The property to get the value of.
3777 * @returns {Mixed} Returns the resolved value.
3781 * 'cheese': 'crumpets',
3782 * 'stuff': function() {
3783 * return 'nonsense';
3787 * _.result(object, 'cheese');
3790 * _.result(object, 'stuff');
3793 function result(object, property) {
3794 var value = object ? object[property] : null;
3795 return isFunction(value) ? object[property]() : value;
3799 * A micro-templating method that handles arbitrary delimiters, preserves
3800 * whitespace, and correctly escapes quotes within interpolated code.
3802 * Note: In the development build, `_.template` utilizes sourceURLs for easier
3803 * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
3805 * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp`
3806 * build and using precompiled templates, or loading Lo-Dash in a sandbox.
3808 * For more information on precompiling templates see:
3809 * http://lodash.com/#custom-builds
3811 * For more information on Chrome extension sandboxes see:
3812 * http://developer.chrome.com/stable/extensions/sandboxingEval.html
3816 * @category Utilities
3817 * @param {String} text The template text.
3818 * @param {Obect} data The data object used to populate the text.
3819 * @param {Object} options The options object.
3820 * escape - The "escape" delimiter regexp.
3821 * evaluate - The "evaluate" delimiter regexp.
3822 * interpolate - The "interpolate" delimiter regexp.
3823 * sourceURL - The sourceURL of the template's compiled source.
3824 * variable - The data object variable name.
3826 * @returns {Function|String} Returns a compiled function when no `data` object
3827 * is given, else it returns the interpolated text.
3830 * // using a compiled template
3831 * var compiled = _.template('hello <%= name %>');
3832 * compiled({ 'name': 'moe' });
3835 * var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
3836 * _.template(list, { 'people': ['moe', 'larry'] });
3837 * // => '<li>moe</li><li>larry</li>'
3839 * // using the "escape" delimiter to escape HTML in data property values
3840 * _.template('<b><%- value %></b>', { 'value': '<script>' });
3841 * // => '<b><script></b>'
3843 * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
3844 * _.template('hello ${ name }', { 'name': 'curly' });
3845 * // => 'hello curly'
3847 * // using the internal `print` function in "evaluate" delimiters
3848 * _.template('<% print("hello " + epithet); %>!', { 'epithet': 'stooge' });
3849 * // => 'hello stooge!'
3851 * // using custom template delimiters
3852 * _.templateSettings = {
3853 * 'interpolate': /{{([\s\S]+?)}}/g
3856 * _.template('hello {{ name }}!', { 'name': 'mustache' });
3857 * // => 'hello mustache!'
3859 * // using the `sourceURL` option to specify a custom sourceURL for the template
3860 * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
3862 * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
3864 * // using the `variable` option to ensure a with-statement isn't used in the compiled template
3865 * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
3867 * // => function(data) {
3868 * var __t, __p = '', __e = _.escape;
3869 * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
3873 * // using the `source` property to inline compiled templates for meaningful
3874 * // line numbers in error messages and a stack trace
3875 * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
3877 * "main": ' + _.template(mainText).source + '\
3881 function template(text, data, options) {
3882 text || (text = '');
3883 options = defaults({}, options, lodash.templateSettings);
3886 source = "__p += '",
3887 variable = options.variable;
3889 var reDelimiters = RegExp(
3890 (options.escape || reNoMatch).source + '|' +
3891 (options.interpolate || reNoMatch).source + '|' +
3892 (options.evaluate || reNoMatch).source + '|$'
3895 text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {
3896 source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
3898 source += "' +\n_.escape(" + escapeValue + ") +\n'";
3900 if (evaluateValue) {
3901 source += "';\n" + evaluateValue + ";\n__p += '";
3903 if (interpolateValue) {
3904 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
3906 index = offset + match.length;
3913 source = 'with (' + variable + ' || {}) {\n' + source + '\n}\n';
3915 source = 'function(' + variable + ') {\n' +
3916 "var __t, __p = '', __j = Array.prototype.join;\n" +
3917 "function print() { __p += __j.call(arguments, '') }\n" +
3922 var result = Function('_', 'return ' + source)(lodash);
3928 return result(data);
3930 result.source = source;
3935 * Executes the `callback` function `n` times, returning an array of the results
3936 * of each `callback` execution. The `callback` is bound to `thisArg` and invoked
3937 * with one argument; (index).
3941 * @category Utilities
3942 * @param {Number} n The number of times to execute the callback.
3943 * @param {Function} callback The function called per iteration.
3944 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3945 * @returns {Array} Returns a new array of the results of each `callback` execution.
3948 * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
3951 * _.times(3, function(n) { mage.castSpell(n); });
3952 * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
3954 * _.times(3, function(n) { this.cast(n); }, mage);
3955 * // => also calls `mage.castSpell(n)` three times
3957 function times(n, callback, thisArg) {
3962 while (++index < n) {
3963 result[index] = callback.call(thisArg, index);
3969 * The opposite of `_.escape`, this method converts the HTML entities
3970 * `&`, `<`, `>`, `"`, and `'` in `string` to their
3971 * corresponding characters.
3975 * @category Utilities
3976 * @param {String} string The string to unescape.
3977 * @returns {String} Returns the unescaped string.
3980 * _.unescape('Moe, Larry & Curly');
3981 * // => 'Moe, Larry & Curly'
3983 function unescape(string) {
3984 return string == null ? '' : (string + '').replace(reEscapedHtml, unescapeHtmlChar);
3988 * Generates a unique ID. If `prefix` is passed, the ID will be appended to it.
3992 * @category Utilities
3993 * @param {String} [prefix] The value to prefix the ID with.
3994 * @returns {String} Returns the unique ID.
3997 * _.uniqueId('contact_');
3998 * // => 'contact_104'
4003 function uniqueId(prefix) {
4004 var id = ++idCounter + '';
4005 return prefix ? prefix + id : id;
4008 /*--------------------------------------------------------------------------*/
4011 * Creates a `lodash` object that wraps the given `value`.
4015 * @category Chaining
4016 * @param {Mixed} value The value to wrap.
4017 * @returns {Object} Returns the wrapper object.
4021 * { 'name': 'moe', 'age': 40 },
4022 * { 'name': 'larry', 'age': 50 },
4023 * { 'name': 'curly', 'age': 60 }
4026 * var youngest = _.chain(stooges)
4027 * .sortBy(function(stooge) { return stooge.age; })
4028 * .map(function(stooge) { return stooge.name + ' is ' + stooge.age; })
4032 function chain(value) {
4033 value = new lodash(value);
4034 value.__chain__ = true;
4039 * Invokes `interceptor` with the `value` as the first argument, and then
4040 * returns `value`. The purpose of this method is to "tap into" a method chain,
4041 * in order to perform operations on intermediate results within the chain.
4045 * @category Chaining
4046 * @param {Mixed} value The value to pass to `interceptor`.
4047 * @param {Function} interceptor The function to invoke.
4048 * @returns {Mixed} Returns `value`.
4052 * .filter(function(num) { return num % 2 == 0; })
4054 * .map(function(num) { return num * num; })
4056 * // => // [2, 4] (alerted)
4059 function tap(value, interceptor) {
4065 * Enables method chaining on the wrapper object.
4069 * @category Chaining
4070 * @returns {Mixed} Returns the wrapper object.
4073 * var sum = _([1, 2, 3])
4075 * .reduce(function(sum, num) { return sum + num; })
4079 function wrapperChain() {
4080 this.__chain__ = true;
4085 * Produces the `toString` result of the wrapped value.
4089 * @category Chaining
4090 * @returns {String} Returns the string result.
4093 * _([1, 2, 3]).toString();
4096 function wrapperToString() {
4097 return this.__wrapped__ + '';
4101 * Extracts the wrapped value.
4106 * @category Chaining
4107 * @returns {Mixed} Returns the wrapped value.
4110 * _([1, 2, 3]).valueOf();
4113 function wrapperValueOf() {
4114 return this.__wrapped__;
4117 /*--------------------------------------------------------------------------*/
4119 // add functions that return wrapped values when chaining
4120 lodash.after = after;
4122 lodash.bindAll = bindAll;
4123 lodash.compact = compact;
4124 lodash.compose = compose;
4125 lodash.countBy = countBy;
4126 lodash.debounce = debounce;
4127 lodash.defaults = defaults;
4128 lodash.defer = defer;
4129 lodash.delay = delay;
4130 lodash.difference = difference;
4131 lodash.filter = filter;
4132 lodash.flatten = flatten;
4133 lodash.forEach = forEach;
4134 lodash.functions = functions;
4135 lodash.groupBy = groupBy;
4136 lodash.initial = initial;
4137 lodash.intersection = intersection;
4138 lodash.invert = invert;
4139 lodash.invoke = invoke;
4143 lodash.memoize = memoize;
4145 lodash.object = object;
4148 lodash.pairs = pairs;
4149 lodash.partial = partial;
4151 lodash.pluck = pluck;
4152 lodash.range = range;
4153 lodash.reject = reject;
4155 lodash.shuffle = shuffle;
4156 lodash.sortBy = sortBy;
4158 lodash.throttle = throttle;
4159 lodash.times = times;
4160 lodash.toArray = toArray;
4161 lodash.union = union;
4163 lodash.values = values;
4164 lodash.where = where;
4165 lodash.without = without;
4170 lodash.collect = map;
4172 lodash.each = forEach;
4173 lodash.extend = assign;
4174 lodash.methods = functions;
4175 lodash.select = filter;
4177 lodash.unique = uniq;
4179 /*--------------------------------------------------------------------------*/
4181 // add functions that return unwrapped values when chaining
4182 lodash.clone = clone;
4183 lodash.contains = contains;
4184 lodash.escape = escape;
4185 lodash.every = every;
4187 lodash.findWhere = findWhere;
4189 lodash.identity = identity;
4190 lodash.indexOf = indexOf;
4191 lodash.isArguments = isArguments;
4192 lodash.isArray = isArray;
4193 lodash.isBoolean = isBoolean;
4194 lodash.isDate = isDate;
4195 lodash.isElement = isElement;
4196 lodash.isEmpty = isEmpty;
4197 lodash.isEqual = isEqual;
4198 lodash.isFinite = isFinite;
4199 lodash.isFunction = isFunction;
4200 lodash.isNaN = isNaN;
4201 lodash.isNull = isNull;
4202 lodash.isNumber = isNumber;
4203 lodash.isObject = isObject;
4204 lodash.isRegExp = isRegExp;
4205 lodash.isString = isString;
4206 lodash.isUndefined = isUndefined;
4207 lodash.lastIndexOf = lastIndexOf;
4208 lodash.mixin = mixin;
4209 lodash.noConflict = noConflict;
4210 lodash.random = random;
4211 lodash.reduce = reduce;
4212 lodash.reduceRight = reduceRight;
4213 lodash.result = result;
4216 lodash.sortedIndex = sortedIndex;
4217 lodash.template = template;
4218 lodash.unescape = unescape;
4219 lodash.uniqueId = uniqueId;
4224 lodash.detect = find;
4225 lodash.foldl = reduce;
4226 lodash.foldr = reduceRight;
4227 lodash.include = contains;
4228 lodash.inject = reduce;
4230 /*--------------------------------------------------------------------------*/
4232 // add functions capable of returning wrapped and unwrapped values when chaining
4233 lodash.first = first;
4237 lodash.take = first;
4238 lodash.head = first;
4240 /*--------------------------------------------------------------------------*/
4242 lodash.chain = chain;
4245 * The semantic version number.
4251 lodash.VERSION = '1.0.2';
4253 // add functions to `lodash.prototype`
4256 // add "Chaining" functions to the wrapper
4257 lodash.prototype.chain = wrapperChain;
4258 lodash.prototype.value = wrapperValueOf;
4260 // add `Array` mutator functions to the wrapper
4261 each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
4262 var func = arrayRef[methodName];
4263 lodash.prototype[methodName] = function() {
4264 var value = this.__wrapped__;
4265 func.apply(value, arguments);
4267 // avoid array-like object bugs with `Array#shift` and `Array#splice`
4268 // in Firefox < 10 and IE < 9
4269 if (hasObjectSpliceBug && value.length === 0) {
4276 // add `Array` accessor functions to the wrapper
4277 each(['concat', 'join', 'slice'], function(methodName) {
4278 var func = arrayRef[methodName];
4279 lodash.prototype[methodName] = function() {
4280 var value = this.__wrapped__,
4281 result = func.apply(value, arguments);
4283 if (this.__chain__) {
4284 result = new lodash(result);
4285 result.__chain__ = true;
4291 /*--------------------------------------------------------------------------*/
4294 // in Node.js or RingoJS v0.8.0+
4296 (freeModule.exports = lodash)._ = lodash;
4298 // in Narwhal or RingoJS v0.7.0-
4300 freeExports._ = lodash;
4304 // in a browser or Rhino