3 * Lo-Dash 1.0.2 (Custom Build) <http://lodash.com/>
4 * Build: `lodash modern -o ./dist/lodash.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 by `cachedContains` as the default size when optimizations are enabled for large arrays */
35 var largeArraySize = 30;
37 /** Used to restore the original `_` reference in `noConflict` */
38 var oldDash = window._;
40 /** Used to match HTML entities */
41 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
43 /** Used to match empty string literals in compiled template source */
44 var reEmptyStringLeading = /\b__p \+= '';/g,
45 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
46 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
48 /** Used to match regexp flags from their coerced string values */
51 /** Used to detect if a method is native */
52 var reNative = RegExp('^' +
53 (objectRef.valueOf + '')
54 .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
55 .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
59 * Used to match ES6 template delimiters
60 * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
62 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
64 /** Used to match "interpolate" template delimiters */
65 var reInterpolate = /<%=([\s\S]+?)%>/g;
67 /** Used to ensure capturing order of template delimiters */
68 var reNoMatch = /($^)/;
70 /** Used to match HTML characters */
71 var reUnescapedHtml = /[&<>"']/g;
73 /** Used to match unescaped characters in compiled string literals */
74 var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
76 /** Used to make template sourceURLs easier to identify */
77 var templateCounter = 0;
79 /** Native method shortcuts */
81 concat = arrayRef.concat,
83 getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
84 hasOwnProperty = objectRef.hasOwnProperty,
86 toString = objectRef.toString;
88 /* Native method shortcuts for methods with the same name as other `lodash` methods */
89 var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
90 nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
91 nativeIsFinite = window.isFinite,
92 nativeIsNaN = window.isNaN,
93 nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
96 nativeRandom = Math.random;
98 /** `Object#toString` result shortcuts */
99 var argsClass = '[object Arguments]',
100 arrayClass = '[object Array]',
101 boolClass = '[object Boolean]',
102 dateClass = '[object Date]',
103 funcClass = '[object Function]',
104 numberClass = '[object Number]',
105 objectClass = '[object Object]',
106 regexpClass = '[object RegExp]',
107 stringClass = '[object String]';
109 /** Detect various environments */
110 var isIeOpera = !!window.attachEvent,
111 isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
113 /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */
114 var isBindFast = nativeBind && !isV8;
116 /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */
117 var isKeysFast = nativeKeys && (isIeOpera || isV8);
119 /** Used to identify object classifications that `_.clone` supports */
120 var cloneableClasses = {};
121 cloneableClasses[funcClass] = false;
122 cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
123 cloneableClasses[boolClass] = cloneableClasses[dateClass] =
124 cloneableClasses[numberClass] = cloneableClasses[objectClass] =
125 cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
127 /** Used to lookup a built-in constructor by [[Class]] */
128 var ctorByClass = {};
129 ctorByClass[arrayClass] = Array;
130 ctorByClass[boolClass] = Boolean;
131 ctorByClass[dateClass] = Date;
132 ctorByClass[objectClass] = Object;
133 ctorByClass[numberClass] = Number;
134 ctorByClass[regexpClass] = RegExp;
135 ctorByClass[stringClass] = String;
137 /** Used to determine if values are of the language type Object */
147 /** Used to escape characters for inclusion in compiled string literals */
148 var stringEscapes = {
158 /*--------------------------------------------------------------------------*/
161 * Creates a `lodash` object, that wraps the given `value`, to enable method
164 * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
165 * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
168 * The chainable wrapper functions are:
169 * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`,
170 * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`,
171 * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`,
172 * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`,
173 * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
174 * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
175 * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
176 * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
178 * The non-chainable wrapper functions are:
179 * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`,
180 * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`,
181 * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`,
182 * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`,
183 * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`,
184 * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId`
186 * The wrapper functions `first` and `last` return wrapped values when `n` is
187 * passed, otherwise they return unwrapped values.
192 * @param {Mixed} value The value to wrap in a `lodash` instance.
193 * @returns {Object} Returns a `lodash` instance.
195 function lodash(value) {
196 // exit early if already wrapped, even if wrapped by a different `lodash` constructor
197 if (value && typeof value == 'object' && value.__wrapped__) {
200 // allow invoking `lodash` without the `new` operator
201 if (!(this instanceof lodash)) {
202 return new lodash(value);
204 this.__wrapped__ = value;
208 * By default, the template delimiters used by Lo-Dash are similar to those in
209 * embedded Ruby (ERB). Change the following template settings to use alternative
216 lodash.templateSettings = {
219 * Used to detect `data` property values to be HTML-escaped.
221 * @memberOf _.templateSettings
224 'escape': /<%-([\s\S]+?)%>/g,
227 * Used to detect code to be evaluated.
229 * @memberOf _.templateSettings
232 'evaluate': /<%([\s\S]+?)%>/g,
235 * Used to detect `data` property values to inject.
237 * @memberOf _.templateSettings
240 'interpolate': reInterpolate,
243 * Used to reference the data object in the template text.
245 * @memberOf _.templateSettings
251 * Used to import variables into the compiled template.
253 * @memberOf _.templateSettings
259 * A reference to the `lodash` function.
261 * @memberOf _.templateSettings.imports
268 /*--------------------------------------------------------------------------*/
271 * The template used to create iterator functions.
274 * @param {Obect} data The data object used to populate the text.
275 * @returns {String} Returns the interpolated text.
277 var iteratorTemplate = function(obj) {
279 var __p = 'var index, iterable = ' +
281 ', result = iterable;\nif (!iterable) return result;\n' +
285 __p += 'var length = iterable.length; index = -1;\nif (' +
287 ') {\n while (++index < length) {\n ' +
292 if (obj.isKeysFast && obj.useHas) {
293 __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n ' +
297 __p += '\n for (index in iterable) {';
301 __p += 'hasOwnProperty.call(iterable, index)';
325 /** Reusable iterator options for `assign` and `defaults` */
326 var defaultsIteratorOptions = {
327 'args': 'object, source, guard',
329 'var args = arguments,\n' +
330 ' argsIndex = 0,\n' +
331 " argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
332 'while (++argsIndex < argsLength) {\n' +
333 ' iterable = args[argsIndex];\n' +
334 ' if (iterable && objectTypes[typeof iterable]) {',
335 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
339 /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
340 var eachIteratorOptions = {
341 'args': 'collection, callback, thisArg',
342 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)",
343 'arrays': "typeof length == 'number'",
344 'loop': 'if (callback(iterable[index], index, collection) === false) return result'
347 /** Reusable iterator options for `forIn` and `forOwn` */
348 var forOwnIteratorOptions = {
349 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
353 /*--------------------------------------------------------------------------*/
356 * Creates a function optimized to search large arrays for a given `value`,
357 * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
360 * @param {Array} array The array to search.
361 * @param {Mixed} value The value to search for.
362 * @param {Number} [fromIndex=0] The index to search from.
363 * @param {Number} [largeSize=30] The length at which an array is considered large.
364 * @returns {Boolean} Returns `true`, if `value` is found, else `false`.
366 function cachedContains(array, fromIndex, largeSize) {
367 fromIndex || (fromIndex = 0);
369 var length = array.length,
370 isLarge = (length - fromIndex) >= (largeSize || largeArraySize);
374 index = fromIndex - 1;
376 while (++index < length) {
377 // manually coerce `value` to a string because `hasOwnProperty`, in some
378 // older versions of Firefox, coerces objects incorrectly
379 var key = array[index] + '';
380 (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]);
383 return function(value) {
385 var key = value + '';
386 return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1;
388 return indexOf(array, value, fromIndex) > -1;
393 * Used by `_.max` and `_.min` as the default `callback` when a given
394 * `collection` is a string value.
397 * @param {String} value The character to inspect.
398 * @returns {Number} Returns the code unit of given character.
400 function charAtCallback(value) {
401 return value.charCodeAt(0);
405 * Used by `sortBy` to compare transformed `collection` values, stable sorting
406 * them in ascending order.
409 * @param {Object} a The object to compare to `b`.
410 * @param {Object} b The object to compare to `a`.
411 * @returns {Number} Returns the sort order indicator of `1` or `-1`.
413 function compareAscending(a, b) {
420 // ensure a stable sort in V8 and other engines
421 // http://code.google.com/p/v8/issues/detail?id=90
423 if (a > b || typeof a == 'undefined') {
426 if (a < b || typeof b == 'undefined') {
430 return ai < bi ? -1 : 1;
434 * Creates a function that, when called, invokes `func` with the `this` binding
435 * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
439 * @param {Function|String} func The function to bind or the method name.
440 * @param {Mixed} [thisArg] The `this` binding of `func`.
441 * @param {Array} partialArgs An array of arguments to be partially applied.
442 * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right.
443 * @returns {Function} Returns the new bound function.
445 function createBound(func, thisArg, partialArgs, rightIndicator) {
446 var isFunc = isFunction(func),
447 isPartial = !partialArgs,
452 partialArgs = thisArg;
459 // `Function#bind` spec
460 // http://es5.github.com/#x15.3.4.5
461 var args = arguments,
462 thisBinding = isPartial ? this : thisArg;
467 if (partialArgs.length) {
469 ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
472 if (this instanceof bound) {
473 // ensure `new bound` is an instance of `bound` and `func`
474 noop.prototype = func.prototype;
475 thisBinding = new noop;
476 noop.prototype = null;
478 // mimic the constructor's `return` behavior
479 // http://es5.github.com/#x13.2.2
480 var result = func.apply(thisBinding, args);
481 return isObject(result) ? result : thisBinding;
483 return func.apply(thisBinding, args);
489 * Produces a callback bound to an optional `thisArg`. If `func` is a property
490 * name, the created callback will return the property value for a given element.
491 * If `func` is an object, the created callback will return `true` for elements
492 * that contain the equivalent object properties, otherwise it will return `false`.
495 * @param {Mixed} [func=identity] The value to convert to a callback.
496 * @param {Mixed} [thisArg] The `this` binding of the created callback.
497 * @param {Number} [argCount=3] The number of arguments the callback accepts.
498 * @returns {Function} Returns a callback function.
500 function createCallback(func, thisArg, argCount) {
504 var type = typeof func;
505 if (type != 'function') {
506 if (type != 'object') {
507 return function(object) {
511 var props = keys(func);
512 return function(object) {
513 var length = props.length,
516 if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) {
523 if (typeof thisArg != 'undefined') {
524 if (argCount === 1) {
525 return function(value) {
526 return func.call(thisArg, value);
529 if (argCount === 2) {
530 return function(a, b) {
531 return func.call(thisArg, a, b);
534 if (argCount === 4) {
535 return function(accumulator, value, index, object) {
536 return func.call(thisArg, accumulator, value, index, object);
539 return function(value, index, object) {
540 return func.call(thisArg, value, index, object);
547 * Creates compiled iteration functions.
550 * @param {Object} [options1, options2, ...] The compile options object(s).
551 * arrays - A string of code to determine if the iterable is an array or array-like.
552 * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
553 * args - A string of comma separated arguments the iteration function will accept.
554 * top - A string of code to execute before the iteration branches.
555 * loop - A string of code to execute in the object loop.
556 * bottom - A string of code to execute after the iteration branches.
558 * @returns {Function} Returns the compiled function.
560 function createIterator() {
562 // support properties
563 'isKeysFast': isKeysFast,
566 'arrays': 'isArray(iterable)',
573 // merge options into a template data object
574 for (var object, index = 0; object = arguments[index]; index++) {
575 for (var key in object) {
576 data[key] = object[key];
579 var args = data.args;
580 data.firstArg = /^[^,]+/.exec(args)[0];
582 // create the function factory
583 var factory = Function(
584 'createCallback, hasOwnProperty, isArguments, isArray, isString, ' +
585 'objectTypes, nativeKeys',
586 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
588 // return the compiled function
590 createCallback, hasOwnProperty, isArguments, isArray, isString,
591 objectTypes, nativeKeys
596 * A function compiled to iterate `arguments` objects, arrays, objects, and
597 * strings consistenly across environments, executing the `callback` for each
598 * element in the `collection`. The `callback` is bound to `thisArg` and invoked
599 * with three arguments; (value, index|key, collection). Callbacks may exit
600 * iteration early by explicitly returning `false`.
604 * @param {Array|Object|String} collection The collection to iterate over.
605 * @param {Function} [callback=identity] The function called per iteration.
606 * @param {Mixed} [thisArg] The `this` binding of `callback`.
607 * @returns {Array|Object|String} Returns `collection`.
609 var each = createIterator(eachIteratorOptions);
612 * Used by `template` to escape characters for inclusion in compiled
616 * @param {String} match The matched character to escape.
617 * @returns {String} Returns the escaped character.
619 function escapeStringChar(match) {
620 return '\\' + stringEscapes[match];
624 * Used by `escape` to convert characters to HTML entities.
627 * @param {String} match The matched character to escape.
628 * @returns {String} Returns the escaped character.
630 function escapeHtmlChar(match) {
631 return htmlEscapes[match];
635 * Checks if `value` is a DOM node in IE < 9.
638 * @param {Mixed} value The value to check.
639 * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
641 function isNode(value) {
642 // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
643 // methods that are `typeof` "string" and still can coerce nodes to strings
644 return typeof value.toString != 'function' && typeof (value + '') == 'string';
648 * A no-operation function.
653 // no operation performed
657 * Slices the `collection` from the `start` index up to, but not including,
660 * Note: This function is used, instead of `Array#slice`, to support node lists
661 * in IE < 9 and to ensure dense arrays are returned.
664 * @param {Array|Object|String} collection The collection to slice.
665 * @param {Number} start The start index.
666 * @param {Number} end The end index.
667 * @returns {Array} Returns the new array.
669 function slice(array, start, end) {
670 start || (start = 0);
671 if (typeof end == 'undefined') {
672 end = array ? array.length : 0;
675 length = end - start || 0,
676 result = Array(length < 0 ? 0 : length);
678 while (++index < length) {
679 result[index] = array[start + index];
685 * Used by `unescape` to convert HTML entities to characters.
688 * @param {String} match The matched character to unescape.
689 * @returns {String} Returns the unescaped character.
691 function unescapeHtmlChar(match) {
692 return htmlUnescapes[match];
695 /*--------------------------------------------------------------------------*/
698 * Checks if `value` is an `arguments` object.
703 * @param {Mixed} value The value to check.
704 * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
707 * (function() { return _.isArguments(arguments); })(1, 2, 3);
710 * _.isArguments([1, 2, 3]);
713 function isArguments(value) {
714 return toString.call(value) == argsClass;
718 * Iterates over `object`'s own and inherited enumerable properties, executing
719 * the `callback` for each property. The `callback` is bound to `thisArg` and
720 * invoked with three arguments; (value, key, object). Callbacks may exit iteration
721 * early by explicitly returning `false`.
727 * @param {Object} object The object to iterate over.
728 * @param {Function} [callback=identity] The function called per iteration.
729 * @param {Mixed} [thisArg] The `this` binding of `callback`.
730 * @returns {Object} Returns `object`.
733 * function Dog(name) {
737 * Dog.prototype.bark = function() {
738 * alert('Woof, woof!');
741 * _.forIn(new Dog('Dagny'), function(value, key) {
744 * // => alerts 'name' and 'bark' (order is not guaranteed)
746 var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
751 * Iterates over an object's own enumerable properties, executing the `callback`
752 * for each property. The `callback` is bound to `thisArg` and invoked with three
753 * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
760 * @param {Object} object The object to iterate over.
761 * @param {Function} [callback=identity] The function called per iteration.
762 * @param {Mixed} [thisArg] The `this` binding of `callback`.
763 * @returns {Object} Returns `object`.
766 * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
769 * // => alerts '0', '1', and 'length' (order is not guaranteed)
771 var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
774 * Checks if `value` is an array.
779 * @param {Mixed} value The value to check.
780 * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
783 * (function() { return _.isArray(arguments); })();
786 * _.isArray([1, 2, 3]);
789 var isArray = nativeIsArray || function(value) {
790 // `instanceof` may cause a memory leak in IE 7 if `value` is a host object
791 // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
792 return value instanceof Array || toString.call(value) == arrayClass;
796 * Creates an array composed of the own enumerable property names of `object`.
801 * @param {Object} object The object to inspect.
802 * @returns {Array} Returns a new array of property names.
805 * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
806 * // => ['one', 'two', 'three'] (order is not guaranteed)
808 var keys = !nativeKeys ? shimKeys : function(object) {
809 if (!isObject(object)) {
812 return nativeKeys(object);
816 * A fallback implementation of `isPlainObject` that checks if a given `value`
817 * is an object created by the `Object` constructor, assuming objects created
818 * by the `Object` constructor have no inherited enumerable properties and that
819 * there are no `Object.prototype` extensions.
822 * @param {Mixed} value The value to check.
823 * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
825 function shimIsPlainObject(value) {
826 // avoid non-objects and false positives for `arguments` objects
828 if (!(value && typeof value == 'object') || isArguments(value)) {
831 // check that the constructor is `Object` (i.e. `Object instanceof Object`)
832 var ctor = value.constructor;
833 if ((!isFunction(ctor)) || ctor instanceof ctor) {
834 // In most environments an object's own properties are iterated before
835 // its inherited properties. If the last iterated property is an object's
836 // own property then there are no inherited enumerable properties.
837 forIn(value, function(value, key) {
840 return result === false || hasOwnProperty.call(value, result);
846 * A fallback implementation of `Object.keys` that produces an array of the
847 * given object's own enumerable property names.
850 * @param {Object} object The object to inspect.
851 * @returns {Array} Returns a new array of property names.
853 function shimKeys(object) {
855 forOwn(object, function(value, key) {
862 * Used to convert characters to HTML entities:
864 * Though the `>` character is escaped for symmetry, characters like `>` and `/`
865 * don't require escaping in HTML and have no special meaning unless they're part
866 * of a tag or an unquoted attribute value.
867 * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
877 /** Used to convert HTML entities to characters */
878 var htmlUnescapes = invert(htmlEscapes);
880 /*--------------------------------------------------------------------------*/
883 * Assigns own enumerable properties of source object(s) to the destination
884 * object. Subsequent sources will overwrite propery assignments of previous
885 * sources. If a `callback` function is passed, it will be executed to produce
886 * the assigned values. The `callback` is bound to `thisArg` and invoked with
887 * two arguments; (objectValue, sourceValue).
894 * @param {Object} object The destination object.
895 * @param {Object} [source1, source2, ...] The source objects.
896 * @param {Function} [callback] The function to customize assigning values.
897 * @param {Mixed} [thisArg] The `this` binding of `callback`.
898 * @returns {Object} Returns the destination object.
901 * _.assign({ 'name': 'moe' }, { 'age': 40 });
902 * // => { 'name': 'moe', 'age': 40 }
904 * var defaults = _.partialRight(_.assign, function(a, b) {
905 * return typeof a == 'undefined' ? b : a;
908 * var food = { 'name': 'apple' };
909 * defaults(food, { 'name': 'banana', 'type': 'fruit' });
910 * // => { 'name': 'apple', 'type': 'fruit' }
912 var assign = createIterator(defaultsIteratorOptions, {
914 defaultsIteratorOptions.top.replace(';',
916 "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
917 ' var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
918 "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
919 ' callback = args[--argsLength];\n' +
922 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
926 * Creates a clone of `value`. If `deep` is `true`, nested objects will also
927 * be cloned, otherwise they will be assigned by reference. If a `callback`
928 * function is passed, it will be executed to produce the cloned values. If
929 * `callback` returns `undefined`, cloning will be handled by the method instead.
930 * The `callback` is bound to `thisArg` and invoked with one argument; (value).
935 * @param {Mixed} value The value to clone.
936 * @param {Boolean} [deep=false] A flag to indicate a deep clone.
937 * @param {Function} [callback] The function to customize cloning values.
938 * @param {Mixed} [thisArg] The `this` binding of `callback`.
939 * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
940 * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts.
941 * @returns {Mixed} Returns the cloned `value`.
945 * { 'name': 'moe', 'age': 40 },
946 * { 'name': 'larry', 'age': 50 }
949 * var shallow = _.clone(stooges);
950 * shallow[0] === stooges[0];
953 * var deep = _.clone(stooges, true);
954 * deep[0] === stooges[0];
958 * 'clone': _.partialRight(_.clone, function(value) {
959 * return _.isElement(value) ? value.cloneNode(false) : undefined;
963 * var clone = _.clone(document.body);
964 * clone.childNodes.length;
967 function clone(value, deep, callback, thisArg, stackA, stackB) {
970 // allows working with "Collections" methods without using their `callback`
971 // argument, `index|key`, for this method's `callback`
972 if (typeof deep == 'function') {
977 if (typeof callback == 'function') {
978 callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 1);
979 result = callback(result);
981 var done = typeof result != 'undefined';
987 var isObj = isObject(result);
989 var className = toString.call(result);
990 if (!cloneableClasses[className]) {
993 var isArr = isArray(result);
996 if (!isObj || !deep) {
997 return isObj && !done
998 ? (isArr ? slice(result) : assign({}, result))
1001 var ctor = ctorByClass[className];
1002 switch (className) {
1005 return done ? result : new ctor(+result);
1009 return done ? result : new ctor(result);
1012 return done ? result : ctor(result.source, reFlags.exec(result));
1014 // check for circular references and return corresponding clone
1015 stackA || (stackA = []);
1016 stackB || (stackB = []);
1018 var length = stackA.length;
1020 if (stackA[length] == value) {
1021 return stackB[length];
1024 // init cloned object
1026 result = isArr ? ctor(result.length) : {};
1028 // add array properties assigned by `RegExp#exec`
1030 if (hasOwnProperty.call(value, 'index')) {
1031 result.index = value.index;
1033 if (hasOwnProperty.call(value, 'input')) {
1034 result.input = value.input;
1038 // add the source value to the stack of traversed objects
1039 // and associate it with its clone
1041 stackB.push(result);
1043 // recursively populate clone (susceptible to call stack limits)
1044 (isArr ? forEach : forOwn)(done ? result : value, function(objValue, key) {
1045 result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
1052 * Creates a deep clone of `value`. If a `callback` function is passed, it will
1053 * be executed to produce the cloned values. If `callback` returns the value it
1054 * was passed, cloning will be handled by the method instead. The `callback` is
1055 * bound to `thisArg` and invoked with one argument; (value).
1057 * Note: This function is loosely based on the structured clone algorithm. Functions
1058 * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
1059 * objects created by constructors other than `Object` are cloned to plain `Object` objects.
1060 * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
1065 * @param {Mixed} value The value to deep clone.
1066 * @param {Function} [callback] The function to customize cloning values.
1067 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1068 * @returns {Mixed} Returns the deep cloned `value`.
1072 * { 'name': 'moe', 'age': 40 },
1073 * { 'name': 'larry', 'age': 50 }
1076 * var deep = _.cloneDeep(stooges);
1077 * deep[0] === stooges[0];
1085 * var clone = _.cloneDeep(view, function(value) {
1086 * return _.isElement(value) ? value.cloneNode(true) : value;
1089 * clone.node == view.node;
1092 function cloneDeep(value, callback, thisArg) {
1093 return clone(value, true, callback, thisArg);
1097 * Assigns own enumerable properties of source object(s) to the destination
1098 * object for all destination properties that resolve to `undefined`. Once a
1099 * property is set, additional defaults of the same property will be ignored.
1105 * @param {Object} object The destination object.
1106 * @param {Object} [source1, source2, ...] The source objects.
1107 * @param- {Object} [guard] Internally used to allow working with `_.reduce`
1108 * without using its callback's `key` and `object` arguments as sources.
1109 * @returns {Object} Returns the destination object.
1112 * var food = { 'name': 'apple' };
1113 * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
1114 * // => { 'name': 'apple', 'type': 'fruit' }
1116 var defaults = createIterator(defaultsIteratorOptions);
1119 * Creates a sorted array of all enumerable properties, own and inherited,
1120 * of `object` that have function values.
1126 * @param {Object} object The object to inspect.
1127 * @returns {Array} Returns a new array of property names that have function values.
1131 * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
1133 function functions(object) {
1135 forIn(object, function(value, key) {
1136 if (isFunction(value)) {
1140 return result.sort();
1144 * Checks if the specified object `property` exists and is a direct property,
1145 * instead of an inherited property.
1150 * @param {Object} object The object to check.
1151 * @param {String} property The property to check for.
1152 * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
1155 * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
1158 function has(object, property) {
1159 return object ? hasOwnProperty.call(object, property) : false;
1163 * Creates an object composed of the inverted keys and values of the given `object`.
1168 * @param {Object} object The object to invert.
1169 * @returns {Object} Returns the created inverted object.
1172 * _.invert({ 'first': 'moe', 'second': 'larry' });
1173 * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed)
1175 function invert(object) {
1177 props = keys(object),
1178 length = props.length,
1181 while (++index < length) {
1182 var key = props[index];
1183 result[object[key]] = key;
1189 * Checks if `value` is a boolean value.
1194 * @param {Mixed} value The value to check.
1195 * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
1198 * _.isBoolean(null);
1201 function isBoolean(value) {
1202 return value === true || value === false || toString.call(value) == boolClass;
1206 * Checks if `value` is a date.
1211 * @param {Mixed} value The value to check.
1212 * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
1215 * _.isDate(new Date);
1218 function isDate(value) {
1219 return value instanceof Date || toString.call(value) == dateClass;
1223 * Checks if `value` is a DOM element.
1228 * @param {Mixed} value The value to check.
1229 * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
1232 * _.isElement(document.body);
1235 function isElement(value) {
1236 return value ? value.nodeType === 1 : false;
1240 * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
1241 * length of `0` and objects with no own enumerable properties are considered
1247 * @param {Array|Object|String} value The value to inspect.
1248 * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
1251 * _.isEmpty([1, 2, 3]);
1260 function isEmpty(value) {
1265 var className = toString.call(value),
1266 length = value.length;
1268 if ((className == arrayClass || className == stringClass ||
1269 className == argsClass) ||
1270 (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
1273 forOwn(value, function() {
1274 return (result = false);
1280 * Performs a deep comparison between two values to determine if they are
1281 * equivalent to each other. If `callback` is passed, it will be executed to
1282 * compare values. If `callback` returns `undefined`, comparisons will be handled
1283 * by the method instead. The `callback` is bound to `thisArg` and invoked with
1284 * two arguments; (a, b).
1289 * @param {Mixed} a The value to compare.
1290 * @param {Mixed} b The other value to compare.
1291 * @param {Function} [callback] The function to customize comparing values.
1292 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1293 * @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
1294 * @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
1295 * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`.
1298 * var moe = { 'name': 'moe', 'age': 40 };
1299 * var copy = { 'name': 'moe', 'age': 40 };
1304 * _.isEqual(moe, copy);
1307 * var words = ['hello', 'goodbye'];
1308 * var otherWords = ['hi', 'goodbye'];
1310 * _.isEqual(words, otherWords, function(a, b) {
1311 * var reGreet = /^(?:hello|hi)$/i,
1312 * aGreet = _.isString(a) && reGreet.test(a),
1313 * bGreet = _.isString(b) && reGreet.test(b);
1315 * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
1319 function isEqual(a, b, callback, thisArg, stackA, stackB) {
1320 // used to indicate that when comparing objects, `a` has at least the properties of `b`
1321 var whereIndicator = callback === indicatorObject;
1322 if (callback && !whereIndicator) {
1323 callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 2);
1324 var result = callback(a, b);
1325 if (typeof result != 'undefined') {
1329 // exit early for identical values
1331 // treat `+0` vs. `-0` as not equal
1332 return a !== 0 || (1 / a == 1 / b);
1334 var type = typeof a,
1335 otherType = typeof b;
1337 // exit early for unlike primitive values
1339 (!a || (type != 'function' && type != 'object')) &&
1340 (!b || (otherType != 'function' && otherType != 'object'))) {
1343 // exit early for `null` and `undefined`, avoiding ES3's Function#call behavior
1344 // http://es5.github.com/#x15.3.4.4
1345 if (a == null || b == null) {
1348 // compare [[Class]] names
1349 var className = toString.call(a),
1350 otherClass = toString.call(b);
1352 if (className == argsClass) {
1353 className = objectClass;
1355 if (otherClass == argsClass) {
1356 otherClass = objectClass;
1358 if (className != otherClass) {
1361 switch (className) {
1364 // coerce dates and booleans to numbers, dates to milliseconds and booleans
1365 // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal
1369 // treat `NaN` vs. `NaN` as equal
1372 // but treat `+0` vs. `-0` as not equal
1373 : (a == 0 ? (1 / a == 1 / b) : a == +b);
1377 // coerce regexes to strings (http://es5.github.com/#x15.10.6.4)
1378 // treat string primitives and their corresponding object instances as equal
1381 var isArr = className == arrayClass;
1383 // unwrap any `lodash` wrapped values
1384 if (a.__wrapped__ || b.__wrapped__) {
1385 return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, thisArg, stackA, stackB);
1387 // exit for functions and DOM nodes
1388 if (className != objectClass) {
1391 // in older versions of Opera, `arguments` objects have `Array` constructors
1392 var ctorA = a.constructor,
1393 ctorB = b.constructor;
1395 // non `Object` object instances with different constructors are not equal
1396 if (ctorA != ctorB && !(
1397 isFunction(ctorA) && ctorA instanceof ctorA &&
1398 isFunction(ctorB) && ctorB instanceof ctorB
1403 // assume cyclic structures are equal
1404 // the algorithm for detecting cyclic structures is adapted from ES 5.1
1405 // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
1406 stackA || (stackA = []);
1407 stackB || (stackB = []);
1409 var length = stackA.length;
1411 if (stackA[length] == a) {
1412 return stackB[length] == b;
1418 // add `a` and `b` to the stack of traversed objects
1422 // recursively compare objects and arrays (susceptible to call stack limits)
1427 // compare lengths to determine if a deep comparison is necessary
1428 result = size == a.length;
1429 if (!result && !whereIndicator) {
1432 // deep compare the contents, ignoring non-numeric properties
1437 if (whereIndicator) {
1439 if ((result = isEqual(a[index], value, callback, thisArg, stackA, stackB))) {
1443 } else if (!(result = isEqual(a[size], value, callback, thisArg, stackA, stackB))) {
1449 // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
1450 // which, in this case, is more costly
1451 forIn(b, function(value, key, b) {
1452 if (hasOwnProperty.call(b, key)) {
1453 // count the number of properties.
1455 // deep compare each property value.
1456 return (result = hasOwnProperty.call(a, key) && isEqual(a[key], value, callback, thisArg, stackA, stackB));
1460 if (result && !whereIndicator) {
1461 // ensure both objects have the same number of properties
1462 forIn(a, function(value, key, a) {
1463 if (hasOwnProperty.call(a, key)) {
1464 // `size` will be `-1` if `a` has more properties than `b`
1465 return (result = --size > -1);
1473 * Checks if `value` is, or can be coerced to, a finite number.
1475 * Note: This is not the same as native `isFinite`, which will return true for
1476 * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
1481 * @param {Mixed} value The value to check.
1482 * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
1497 * _.isFinite(Infinity);
1500 function isFinite(value) {
1501 return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
1505 * Checks if `value` is a function.
1510 * @param {Mixed} value The value to check.
1511 * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
1517 function isFunction(value) {
1518 return typeof value == 'function';
1520 // fallback for older versions of Chrome and Safari
1521 if (isFunction(/x/)) {
1522 isFunction = function(value) {
1523 return value instanceof Function || toString.call(value) == funcClass;
1528 * Checks if `value` is the language type of Object.
1529 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
1534 * @param {Mixed} value The value to check.
1535 * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
1541 * _.isObject([1, 2, 3]);
1547 function isObject(value) {
1548 // check if the value is the ECMAScript language type of Object
1549 // http://es5.github.com/#x8
1550 // and avoid a V8 bug
1551 // http://code.google.com/p/v8/issues/detail?id=2291
1552 return value ? objectTypes[typeof value] : false;
1556 * Checks if `value` is `NaN`.
1558 * Note: This is not the same as native `isNaN`, which will return `true` for
1559 * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
1564 * @param {Mixed} value The value to check.
1565 * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
1571 * _.isNaN(new Number(NaN));
1577 * _.isNaN(undefined);
1580 function isNaN(value) {
1581 // `NaN` as a primitive is the only value that is not equal to itself
1582 // (perform the [[Class]] check first to avoid errors with some host objects in IE)
1583 return isNumber(value) && value != +value
1587 * Checks if `value` is `null`.
1592 * @param {Mixed} value The value to check.
1593 * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
1599 * _.isNull(undefined);
1602 function isNull(value) {
1603 return value === null;
1607 * Checks if `value` is a number.
1612 * @param {Mixed} value The value to check.
1613 * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
1616 * _.isNumber(8.4 * 5);
1619 function isNumber(value) {
1620 return typeof value == 'number' || toString.call(value) == numberClass;
1624 * Checks if a given `value` is an object created by the `Object` constructor.
1629 * @param {Mixed} value The value to check.
1630 * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
1633 * function Stooge(name, age) {
1638 * _.isPlainObject(new Stooge('moe', 40));
1641 * _.isPlainObject([1, 2, 3]);
1644 * _.isPlainObject({ 'name': 'moe', 'age': 40 });
1647 var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
1648 if (!(value && typeof value == 'object')) {
1651 var valueOf = value.valueOf,
1652 objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
1655 ? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value))
1656 : shimIsPlainObject(value);
1660 * Checks if `value` is a regular expression.
1665 * @param {Mixed} value The value to check.
1666 * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
1669 * _.isRegExp(/moe/);
1672 function isRegExp(value) {
1673 return value instanceof RegExp || toString.call(value) == regexpClass;
1677 * Checks if `value` is a string.
1682 * @param {Mixed} value The value to check.
1683 * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
1686 * _.isString('moe');
1689 function isString(value) {
1690 return typeof value == 'string' || toString.call(value) == stringClass;
1694 * Checks if `value` is `undefined`.
1699 * @param {Mixed} value The value to check.
1700 * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
1703 * _.isUndefined(void 0);
1706 function isUndefined(value) {
1707 return typeof value == 'undefined';
1711 * Recursively merges own enumerable properties of the source object(s), that
1712 * don't resolve to `undefined`, into the destination object. Subsequent sources
1713 * will overwrite propery assignments of previous sources. If a `callback` function
1714 * is passed, it will be executed to produce the merged values of the destination
1715 * and source properties. If `callback` returns `undefined`, merging will be
1716 * handled by the method instead. The `callback` is bound to `thisArg` and
1717 * invoked with two arguments; (objectValue, sourceValue).
1722 * @param {Object} object The destination object.
1723 * @param {Object} [source1, source2, ...] The source objects.
1724 * @param {Function} [callback] The function to customize merging properties.
1725 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1726 * @param- {Object} [deepIndicator] Internally used to indicate that `stackA`
1727 * and `stackB` are arrays of traversed objects instead of source objects.
1728 * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
1729 * @param- {Array} [stackB=[]] Internally used to associate values with their
1730 * source counterparts.
1731 * @returns {Object} Returns the destination object.
1736 * { 'name': 'moe' },
1737 * { 'name': 'larry' }
1748 * _.merge(names, ages);
1749 * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
1752 * 'fruits': ['apple'],
1753 * 'vegetables': ['beet']
1757 * 'fruits': ['banana'],
1758 * 'vegetables': ['carrot']
1761 * _.merge(food, otherFood, function(a, b) {
1762 * return _.isArray(a) ? a.concat(b) : undefined;
1764 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
1766 function merge(object, source, deepIndicator) {
1767 var args = arguments,
1771 if (!isObject(object)) {
1774 if (deepIndicator === indicatorObject) {
1775 var callback = args[3],
1782 // allows working with `_.reduce` and `_.reduceRight` without
1783 // using their `callback` arguments, `index|key` and `collection`
1784 if (typeof deepIndicator != 'number') {
1785 length = args.length;
1787 if (length > 3 && typeof args[length - 2] == 'function') {
1788 callback = createCallback(args[--length - 1], args[length--], 2);
1789 } else if (length > 2 && typeof args[length - 1] == 'function') {
1790 callback = args[--length];
1793 while (++index < length) {
1794 (isArray(args[index]) ? forEach : forOwn)(args[index], function(source, key) {
1798 value = object[key];
1800 if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
1801 // avoid merging previously merged cyclic sources
1802 var stackLength = stackA.length;
1803 while (stackLength--) {
1804 if ((found = stackA[stackLength] == source)) {
1805 value = stackB[stackLength];
1811 ? (isArray(value) ? value : [])
1812 : (isPlainObject(value) ? value : {});
1815 result = callback(value, source);
1816 if (typeof result != 'undefined') {
1820 // add `source` and associated `value` to the stack of traversed objects
1821 stackA.push(source);
1824 // recursively merge objects and arrays (susceptible to call stack limits)
1826 value = merge(value, source, indicatorObject, callback, stackA, stackB);
1832 result = callback(value, source);
1833 if (typeof result == 'undefined') {
1837 if (typeof result != 'undefined') {
1841 object[key] = value;
1848 * Creates a shallow clone of `object` excluding the specified properties.
1849 * Property names may be specified as individual arguments or as arrays of
1850 * property names. If a `callback` function is passed, it will be executed
1851 * for each property in the `object`, omitting the properties `callback`
1852 * returns truthy for. The `callback` is bound to `thisArg` and invoked
1853 * with three arguments; (value, key, object).
1858 * @param {Object} object The source object.
1859 * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
1860 * or the function called per iteration.
1861 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1862 * @returns {Object} Returns an object without the omitted properties.
1865 * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
1866 * // => { 'name': 'moe' }
1868 * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
1869 * return typeof value == 'number';
1871 * // => { 'name': 'moe' }
1873 function omit(object, callback, thisArg) {
1874 var isFunc = typeof callback == 'function',
1878 callback = createCallback(callback, thisArg);
1880 var props = concat.apply(arrayRef, arguments);
1882 forIn(object, function(value, key, object) {
1884 ? !callback(value, key, object)
1885 : indexOf(props, key, 1) < 0
1887 result[key] = value;
1894 * Creates a two dimensional array of the given object's key-value pairs,
1895 * i.e. `[[key1, value1], [key2, value2]]`.
1900 * @param {Object} object The object to inspect.
1901 * @returns {Array} Returns new array of key-value pairs.
1904 * _.pairs({ 'moe': 30, 'larry': 40 });
1905 * // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
1907 function pairs(object) {
1909 props = keys(object),
1910 length = props.length,
1911 result = Array(length);
1913 while (++index < length) {
1914 var key = props[index];
1915 result[index] = [key, object[key]];
1921 * Creates a shallow clone of `object` composed of the specified properties.
1922 * Property names may be specified as individual arguments or as arrays of property
1923 * names. If `callback` is passed, it will be executed for each property in the
1924 * `object`, picking the properties `callback` returns truthy for. The `callback`
1925 * is bound to `thisArg` and invoked with three arguments; (value, key, object).
1930 * @param {Object} object The source object.
1931 * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
1932 * per iteration or properties to pick, either as individual arguments or arrays.
1933 * @param {Mixed} [thisArg] The `this` binding of `callback`.
1934 * @returns {Object} Returns an object composed of the picked properties.
1937 * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
1938 * // => { 'name': 'moe' }
1940 * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
1941 * return key.charAt(0) != '_';
1943 * // => { 'name': 'moe' }
1945 function pick(object, callback, thisArg) {
1947 if (typeof callback != 'function') {
1949 props = concat.apply(arrayRef, arguments),
1950 length = isObject(object) ? props.length : 0;
1952 while (++index < length) {
1953 var key = props[index];
1954 if (key in object) {
1955 result[key] = object[key];
1959 callback = createCallback(callback, thisArg);
1960 forIn(object, function(value, key, object) {
1961 if (callback(value, key, object)) {
1962 result[key] = value;
1970 * Creates an array composed of the own enumerable property values of `object`.
1975 * @param {Object} object The object to inspect.
1976 * @returns {Array} Returns a new array of property values.
1979 * _.values({ 'one': 1, 'two': 2, 'three': 3 });
1982 function values(object) {
1984 props = keys(object),
1985 length = props.length,
1986 result = Array(length);
1988 while (++index < length) {
1989 result[index] = object[props[index]];
1994 /*--------------------------------------------------------------------------*/
1997 * Creates an array of elements from the specified indexes, or keys, of the
1998 * `collection`. Indexes may be specified as individual arguments or as arrays
2003 * @category Collections
2004 * @param {Array|Object|String} collection The collection to iterate over.
2005 * @param {Array|Number|String} [index1, index2, ...] The indexes of
2006 * `collection` to retrieve, either as individual arguments or arrays.
2007 * @returns {Array} Returns a new array of elements corresponding to the
2011 * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
2012 * // => ['a', 'c', 'e']
2014 * _.at(['moe', 'larry', 'curly'], 0, 2);
2015 * // => ['moe', 'curly']
2017 function at(collection) {
2019 props = concat.apply(arrayRef, slice(arguments, 1)),
2020 length = props.length,
2021 result = Array(length);
2023 while(++index < length) {
2024 result[index] = collection[props[index]];
2030 * Checks if a given `target` element is present in a `collection` using strict
2031 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
2032 * as the offset from the end of the collection.
2037 * @category Collections
2038 * @param {Array|Object|String} collection The collection to iterate over.
2039 * @param {Mixed} target The value to check for.
2040 * @param {Number} [fromIndex=0] The index to search from.
2041 * @returns {Boolean} Returns `true` if the `target` element is found, else `false`.
2044 * _.contains([1, 2, 3], 1);
2047 * _.contains([1, 2, 3], 1, 2);
2050 * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
2053 * _.contains('curly', 'ur');
2056 function contains(collection, target, fromIndex) {
2058 length = collection ? collection.length : 0,
2061 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
2062 if (typeof length == 'number') {
2063 result = (isString(collection)
2064 ? collection.indexOf(target, fromIndex)
2065 : indexOf(collection, target, fromIndex)
2068 each(collection, function(value) {
2069 if (++index >= fromIndex) {
2070 return !(result = value === target);
2078 * Creates an object composed of keys returned from running each element of the
2079 * `collection` through the given `callback`. The corresponding value of each key
2080 * is the number of times the key was returned by the `callback`. The `callback`
2081 * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
2083 * If a property name is passed for `callback`, the created "_.pluck" style
2084 * callback will return the property value of the given element.
2086 * If an object is passed for `callback`, the created "_.where" style callback
2087 * will return `true` for elements that have the propeties of the given object,
2092 * @category Collections
2093 * @param {Array|Object|String} collection The collection to iterate over.
2094 * @param {Function|Object|String} [callback=identity] The function called per
2095 * iteration. If a property name or object is passed, it will be used to create
2096 * a "_.pluck" or "_.where" style callback, respectively.
2097 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2098 * @returns {Object} Returns the composed aggregate object.
2101 * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
2102 * // => { '4': 1, '6': 2 }
2104 * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
2105 * // => { '4': 1, '6': 2 }
2107 * _.countBy(['one', 'two', 'three'], 'length');
2108 * // => { '3': 2, '5': 1 }
2110 function countBy(collection, callback, thisArg) {
2112 callback = createCallback(callback, thisArg);
2114 forEach(collection, function(value, key, collection) {
2115 key = callback(value, key, collection) + '';
2116 (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
2122 * Checks if the `callback` returns a truthy value for **all** elements of a
2123 * `collection`. The `callback` is bound to `thisArg` and invoked with three
2124 * arguments; (value, index|key, collection).
2126 * If a property name is passed for `callback`, the created "_.pluck" style
2127 * callback will return the property value of the given element.
2129 * If an object is passed for `callback`, the created "_.where" style callback
2130 * will return `true` for elements that have the propeties of the given object,
2136 * @category Collections
2137 * @param {Array|Object|String} collection The collection to iterate over.
2138 * @param {Function|Object|String} [callback=identity] The function called per
2139 * iteration. If a property name or object is passed, it will be used to create
2140 * a "_.pluck" or "_.where" style callback, respectively.
2141 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2142 * @returns {Boolean} Returns `true` if all elements pass the callback check,
2146 * _.every([true, 1, null, 'yes'], Boolean);
2150 * { 'name': 'moe', 'age': 40 },
2151 * { 'name': 'larry', 'age': 50 }
2154 * // using "_.pluck" callback shorthand
2155 * _.every(stooges, 'age');
2158 * // using "_.where" callback shorthand
2159 * _.every(stooges, { 'age': 50 });
2162 function every(collection, callback, thisArg) {
2164 callback = createCallback(callback, thisArg);
2166 if (isArray(collection)) {
2168 length = collection.length;
2170 while (++index < length) {
2171 if (!(result = !!callback(collection[index], index, collection))) {
2176 each(collection, function(value, index, collection) {
2177 return (result = !!callback(value, index, collection));
2184 * Examines each element in a `collection`, returning an array of all elements
2185 * the `callback` returns truthy for. The `callback` is bound to `thisArg` and
2186 * invoked with three arguments; (value, index|key, collection).
2188 * If a property name is passed for `callback`, the created "_.pluck" style
2189 * callback will return the property value of the given element.
2191 * If an object is passed for `callback`, the created "_.where" style callback
2192 * will return `true` for elements that have the propeties of the given object,
2198 * @category Collections
2199 * @param {Array|Object|String} collection The collection to iterate over.
2200 * @param {Function|Object|String} [callback=identity] The function called per
2201 * iteration. If a property name or object is passed, it will be used to create
2202 * a "_.pluck" or "_.where" style callback, respectively.
2203 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2204 * @returns {Array} Returns a new array of elements that passed the callback check.
2207 * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2211 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2212 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2215 * // using "_.pluck" callback shorthand
2216 * _.filter(food, 'organic');
2217 * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
2219 * // using "_.where" callback shorthand
2220 * _.filter(food, { 'type': 'fruit' });
2221 * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
2223 function filter(collection, callback, thisArg) {
2225 callback = createCallback(callback, thisArg);
2227 if (isArray(collection)) {
2229 length = collection.length;
2231 while (++index < length) {
2232 var value = collection[index];
2233 if (callback(value, index, collection)) {
2238 each(collection, function(value, index, collection) {
2239 if (callback(value, index, collection)) {
2248 * Examines each element in a `collection`, returning the first that the `callback`
2249 * returns truthy for. The `callback` is bound to `thisArg` and invoked with three
2250 * arguments; (value, index|key, collection).
2252 * If a property name is passed for `callback`, the created "_.pluck" style
2253 * callback will return the property value of the given element.
2255 * If an object is passed for `callback`, the created "_.where" style callback
2256 * will return `true` for elements that have the propeties of the given object,
2262 * @category Collections
2263 * @param {Array|Object|String} collection The collection to iterate over.
2264 * @param {Function|Object|String} [callback=identity] The function called per
2265 * iteration. If a property name or object is passed, it will be used to create
2266 * a "_.pluck" or "_.where" style callback, respectively.
2267 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2268 * @returns {Mixed} Returns the element that passed the callback check,
2272 * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2276 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2277 * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
2278 * { 'name': 'beet', 'organic': false, 'type': 'vegetable' },
2279 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2282 * // using "_.where" callback shorthand
2283 * var veggie = _.find(food, { 'type': 'vegetable' });
2284 * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
2286 * // using "_.pluck" callback shorthand
2287 * var healthy = _.find(food, 'organic');
2288 * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
2290 function find(collection, callback, thisArg) {
2292 callback = createCallback(callback, thisArg);
2294 forEach(collection, function(value, index, collection) {
2295 if (callback(value, index, collection)) {
2304 * Iterates over a `collection`, executing the `callback` for each element in
2305 * the `collection`. The `callback` is bound to `thisArg` and invoked with three
2306 * arguments; (value, index|key, collection). Callbacks may exit iteration early
2307 * by explicitly returning `false`.
2312 * @category Collections
2313 * @param {Array|Object|String} collection The collection to iterate over.
2314 * @param {Function} [callback=identity] The function called per iteration.
2315 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2316 * @returns {Array|Object|String} Returns `collection`.
2319 * _([1, 2, 3]).forEach(alert).join(',');
2320 * // => alerts each number and returns '1,2,3'
2322 * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);
2323 * // => alerts each number value (order is not guaranteed)
2325 function forEach(collection, callback, thisArg) {
2326 if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
2328 length = collection.length;
2330 while (++index < length) {
2331 if (callback(collection[index], index, collection) === false) {
2336 each(collection, callback, thisArg);
2342 * Creates an object composed of keys returned from running each element of the
2343 * `collection` through the `callback`. The corresponding value of each key is
2344 * an array of elements passed to `callback` that returned the key. The `callback`
2345 * is bound to `thisArg` and invoked with three 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 {Object} Returns the composed aggregate object.
2365 * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
2366 * // => { '4': [4.2], '6': [6.1, 6.4] }
2368 * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
2369 * // => { '4': [4.2], '6': [6.1, 6.4] }
2371 * // using "_.pluck" callback shorthand
2372 * _.groupBy(['one', 'two', 'three'], 'length');
2373 * // => { '3': ['one', 'two'], '5': ['three'] }
2375 function groupBy(collection, callback, thisArg) {
2377 callback = createCallback(callback, thisArg);
2379 forEach(collection, function(value, key, collection) {
2380 key = callback(value, key, collection) + '';
2381 (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
2387 * Invokes the method named by `methodName` on each element in the `collection`,
2388 * returning an array of the results of each invoked method. Additional arguments
2389 * will be passed to each invoked method. If `methodName` is a function, it will
2390 * be invoked for, and `this` bound to, each element in the `collection`.
2394 * @category Collections
2395 * @param {Array|Object|String} collection The collection to iterate over.
2396 * @param {Function|String} methodName The name of the method to invoke or
2397 * the function invoked per iteration.
2398 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
2399 * @returns {Array} Returns a new array of the results of each invoked method.
2402 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
2403 * // => [[1, 5, 7], [1, 2, 3]]
2405 * _.invoke([123, 456], String.prototype.split, '');
2406 * // => [['1', '2', '3'], ['4', '5', '6']]
2408 function invoke(collection, methodName) {
2409 var args = slice(arguments, 2),
2411 isFunc = typeof methodName == 'function',
2412 length = collection ? collection.length : 0,
2413 result = Array(typeof length == 'number' ? length : 0);
2415 forEach(collection, function(value) {
2416 result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
2422 * Creates an array of values by running each element in the `collection`
2423 * through the `callback`. The `callback` is bound to `thisArg` and invoked with
2424 * three arguments; (value, index|key, collection).
2426 * If a property name is passed for `callback`, the created "_.pluck" style
2427 * callback will return the property value of the given element.
2429 * If an object is passed for `callback`, the created "_.where" style callback
2430 * will return `true` for elements that have the propeties of the given object,
2436 * @category Collections
2437 * @param {Array|Object|String} collection The collection to iterate over.
2438 * @param {Function|Object|String} [callback=identity] The function called per
2439 * iteration. If a property name or object is passed, it will be used to create
2440 * a "_.pluck" or "_.where" style callback, respectively.
2441 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2442 * @returns {Array} Returns a new array of the results of each `callback` execution.
2445 * _.map([1, 2, 3], function(num) { return num * 3; });
2448 * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
2449 * // => [3, 6, 9] (order is not guaranteed)
2452 * { 'name': 'moe', 'age': 40 },
2453 * { 'name': 'larry', 'age': 50 }
2456 * // using "_.pluck" callback shorthand
2457 * _.map(stooges, 'name');
2458 * // => ['moe', 'larry']
2460 function map(collection, callback, thisArg) {
2462 length = collection ? collection.length : 0,
2463 result = Array(typeof length == 'number' ? length : 0);
2465 callback = createCallback(callback, thisArg);
2466 if (isArray(collection)) {
2467 while (++index < length) {
2468 result[index] = callback(collection[index], index, collection);
2471 each(collection, function(value, key, collection) {
2472 result[++index] = callback(value, key, collection);
2479 * Retrieves the maximum value of an `array`. If `callback` is passed,
2480 * it will be executed for each value in the `array` to generate the
2481 * criterion by which the value is ranked. The `callback` is bound to
2482 * `thisArg` and invoked with three arguments; (value, index, collection).
2484 * If a property name is passed for `callback`, the created "_.pluck" style
2485 * callback will return the property value of the given element.
2487 * If an object is passed for `callback`, the created "_.where" style callback
2488 * will return `true` for elements that have the propeties of the given object,
2493 * @category Collections
2494 * @param {Array|Object|String} collection The collection to iterate over.
2495 * @param {Function|Object|String} [callback=identity] The function called per
2496 * iteration. If a property name or object is passed, it will be used to create
2497 * a "_.pluck" or "_.where" style callback, respectively.
2498 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2499 * @returns {Mixed} Returns the maximum value.
2502 * _.max([4, 2, 8, 6]);
2506 * { 'name': 'moe', 'age': 40 },
2507 * { 'name': 'larry', 'age': 50 }
2510 * _.max(stooges, function(stooge) { return stooge.age; });
2511 * // => { 'name': 'larry', 'age': 50 };
2513 * // using "_.pluck" callback shorthand
2514 * _.max(stooges, 'age');
2515 * // => { 'name': 'larry', 'age': 50 };
2517 function max(collection, callback, thisArg) {
2518 var computed = -Infinity,
2521 if (!callback && isArray(collection)) {
2523 length = collection.length;
2525 while (++index < length) {
2526 var value = collection[index];
2527 if (value > result) {
2532 callback = !callback && isString(collection)
2534 : createCallback(callback, thisArg);
2536 each(collection, function(value, index, collection) {
2537 var current = callback(value, index, collection);
2538 if (current > computed) {
2548 * Retrieves the minimum value of an `array`. If `callback` is passed,
2549 * it will be executed for each value in the `array` to generate the
2550 * criterion by which the value is ranked. The `callback` is bound to `thisArg`
2551 * and invoked with three arguments; (value, index, collection).
2553 * If a property name is passed for `callback`, the created "_.pluck" style
2554 * callback will return the property value of the given element.
2556 * If an object is passed for `callback`, the created "_.where" style callback
2557 * will return `true` for elements that have the propeties of the given object,
2562 * @category Collections
2563 * @param {Array|Object|String} collection The collection to iterate over.
2564 * @param {Function|Object|String} [callback=identity] The function called per
2565 * iteration. If a property name or object is passed, it will be used to create
2566 * a "_.pluck" or "_.where" style callback, respectively.
2567 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2568 * @returns {Mixed} Returns the minimum value.
2571 * _.min([4, 2, 8, 6]);
2575 * { 'name': 'moe', 'age': 40 },
2576 * { 'name': 'larry', 'age': 50 }
2579 * _.min(stooges, function(stooge) { return stooge.age; });
2580 * // => { 'name': 'moe', 'age': 40 };
2582 * // using "_.pluck" callback shorthand
2583 * _.min(stooges, 'age');
2584 * // => { 'name': 'moe', 'age': 40 };
2586 function min(collection, callback, thisArg) {
2587 var computed = Infinity,
2590 if (!callback && isArray(collection)) {
2592 length = collection.length;
2594 while (++index < length) {
2595 var value = collection[index];
2596 if (value < result) {
2601 callback = !callback && isString(collection)
2603 : createCallback(callback, thisArg);
2605 each(collection, function(value, index, collection) {
2606 var current = callback(value, index, collection);
2607 if (current < computed) {
2617 * Retrieves the value of a specified property from all elements in the `collection`.
2622 * @category Collections
2623 * @param {Array|Object|String} collection The collection to iterate over.
2624 * @param {String} property The property to pluck.
2625 * @returns {Array} Returns a new array of property values.
2629 * { 'name': 'moe', 'age': 40 },
2630 * { 'name': 'larry', 'age': 50 }
2633 * _.pluck(stooges, 'name');
2634 * // => ['moe', 'larry']
2639 * Reduces a `collection` to a value that is the accumulated result of running
2640 * each element in the `collection` through the `callback`, where each successive
2641 * `callback` execution consumes the return value of the previous execution.
2642 * If `accumulator` is not passed, the first element of the `collection` will be
2643 * used as the initial `accumulator` value. The `callback` is bound to `thisArg`
2644 * and invoked with four arguments; (accumulator, value, index|key, collection).
2648 * @alias foldl, inject
2649 * @category Collections
2650 * @param {Array|Object|String} collection The collection to iterate over.
2651 * @param {Function} [callback=identity] The function called per iteration.
2652 * @param {Mixed} [accumulator] Initial value of the accumulator.
2653 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2654 * @returns {Mixed} Returns the accumulated value.
2657 * var sum = _.reduce([1, 2, 3], function(sum, num) {
2662 * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2663 * result[key] = num * 3;
2666 * // => { 'a': 3, 'b': 6, 'c': 9 }
2668 function reduce(collection, callback, accumulator, thisArg) {
2669 var noaccum = arguments.length < 3;
2670 callback = createCallback(callback, thisArg, 4);
2672 if (isArray(collection)) {
2674 length = collection.length;
2677 accumulator = collection[++index];
2679 while (++index < length) {
2680 accumulator = callback(accumulator, collection[index], index, collection);
2683 each(collection, function(value, index, collection) {
2684 accumulator = noaccum
2685 ? (noaccum = false, value)
2686 : callback(accumulator, value, index, collection)
2693 * This method is similar to `_.reduce`, except that it iterates over a
2694 * `collection` from right to left.
2699 * @category Collections
2700 * @param {Array|Object|String} collection The collection to iterate over.
2701 * @param {Function} [callback=identity] The function called per iteration.
2702 * @param {Mixed} [accumulator] Initial value of the accumulator.
2703 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2704 * @returns {Mixed} Returns the accumulated value.
2707 * var list = [[0, 1], [2, 3], [4, 5]];
2708 * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
2709 * // => [4, 5, 2, 3, 0, 1]
2711 function reduceRight(collection, callback, accumulator, thisArg) {
2712 var iterable = collection,
2713 length = collection ? collection.length : 0,
2714 noaccum = arguments.length < 3;
2716 if (typeof length != 'number') {
2717 var props = keys(collection);
2718 length = props.length;
2720 callback = createCallback(callback, thisArg, 4);
2721 forEach(collection, function(value, index, collection) {
2722 index = props ? props[--length] : --length;
2723 accumulator = noaccum
2724 ? (noaccum = false, iterable[index])
2725 : callback(accumulator, iterable[index], index, collection);
2731 * The opposite of `_.filter`, this method returns the elements of a
2732 * `collection` that `callback` does **not** return truthy for.
2734 * If a property name is passed for `callback`, the created "_.pluck" style
2735 * callback will return the property value of the given element.
2737 * If an object is passed for `callback`, the created "_.where" style callback
2738 * will return `true` for elements that have the propeties of the given object,
2743 * @category Collections
2744 * @param {Array|Object|String} collection The collection to iterate over.
2745 * @param {Function|Object|String} [callback=identity] The function called per
2746 * iteration. If a property name or object is passed, it will be used to create
2747 * a "_.pluck" or "_.where" style callback, respectively.
2748 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2749 * @returns {Array} Returns a new array of elements that did **not** pass the
2753 * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2757 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2758 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2761 * // using "_.pluck" callback shorthand
2762 * _.reject(food, 'organic');
2763 * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
2765 * // using "_.where" callback shorthand
2766 * _.reject(food, { 'type': 'fruit' });
2767 * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
2769 function reject(collection, callback, thisArg) {
2770 callback = createCallback(callback, thisArg);
2771 return filter(collection, function(value, index, collection) {
2772 return !callback(value, index, collection);
2777 * Creates an array of shuffled `array` values, using a version of the
2778 * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
2782 * @category Collections
2783 * @param {Array|Object|String} collection The collection to shuffle.
2784 * @returns {Array} Returns a new shuffled collection.
2787 * _.shuffle([1, 2, 3, 4, 5, 6]);
2788 * // => [4, 1, 6, 3, 5, 2]
2790 function shuffle(collection) {
2792 length = collection ? collection.length : 0,
2793 result = Array(typeof length == 'number' ? length : 0);
2795 forEach(collection, function(value) {
2796 var rand = floor(nativeRandom() * (++index + 1));
2797 result[index] = result[rand];
2798 result[rand] = value;
2804 * Gets the size of the `collection` by returning `collection.length` for arrays
2805 * and array-like objects or the number of own enumerable properties for objects.
2809 * @category Collections
2810 * @param {Array|Object|String} collection The collection to inspect.
2811 * @returns {Number} Returns `collection.length` or number of own enumerable properties.
2817 * _.size({ 'one': 1, 'two': 2, 'three': 3 });
2823 function size(collection) {
2824 var length = collection ? collection.length : 0;
2825 return typeof length == 'number' ? length : keys(collection).length;
2829 * Checks if the `callback` returns a truthy value for **any** element of a
2830 * `collection`. The function returns as soon as it finds passing value, and
2831 * does not iterate over the entire `collection`. The `callback` is bound to
2832 * `thisArg` and invoked with three arguments; (value, index|key, collection).
2834 * If a property name is passed for `callback`, the created "_.pluck" style
2835 * callback will return the property value of the given element.
2837 * If an object is passed for `callback`, the created "_.where" style callback
2838 * will return `true` for elements that have the propeties of the given object,
2844 * @category Collections
2845 * @param {Array|Object|String} collection The collection to iterate over.
2846 * @param {Function|Object|String} [callback=identity] The function called per
2847 * iteration. If a property name or object is passed, it will be used to create
2848 * a "_.pluck" or "_.where" style callback, respectively.
2849 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2850 * @returns {Boolean} Returns `true` if any element passes the callback check,
2854 * _.some([null, 0, 'yes', false], Boolean);
2858 * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2859 * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
2862 * // using "_.pluck" callback shorthand
2863 * _.some(food, 'organic');
2866 * // using "_.where" callback shorthand
2867 * _.some(food, { 'type': 'meat' });
2870 function some(collection, callback, thisArg) {
2872 callback = createCallback(callback, thisArg);
2874 if (isArray(collection)) {
2876 length = collection.length;
2878 while (++index < length) {
2879 if ((result = callback(collection[index], index, collection))) {
2884 each(collection, function(value, index, collection) {
2885 return !(result = callback(value, index, collection));
2892 * Creates an array of elements, sorted in ascending order by the results of
2893 * running each element in the `collection` through the `callback`. This method
2894 * performs a stable sort, that is, it will preserve the original sort order of
2895 * equal elements. The `callback` is bound to `thisArg` and invoked with three
2896 * arguments; (value, index|key, collection).
2898 * If a property name is passed for `callback`, the created "_.pluck" style
2899 * callback will return the property value of the given element.
2901 * If an object is passed for `callback`, the created "_.where" style callback
2902 * will return `true` for elements that have the propeties of the given object,
2907 * @category Collections
2908 * @param {Array|Object|String} collection The collection to iterate over.
2909 * @param {Function|Object|String} [callback=identity] The function called per
2910 * iteration. If a property name or object is passed, it will be used to create
2911 * a "_.pluck" or "_.where" style callback, respectively.
2912 * @param {Mixed} [thisArg] The `this` binding of `callback`.
2913 * @returns {Array} Returns a new array of sorted elements.
2916 * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
2919 * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
2922 * // using "_.pluck" callback shorthand
2923 * _.sortBy(['banana', 'strawberry', 'apple'], 'length');
2924 * // => ['apple', 'banana', 'strawberry']
2926 function sortBy(collection, callback, thisArg) {
2928 length = collection ? collection.length : 0,
2929 result = Array(typeof length == 'number' ? length : 0);
2931 callback = createCallback(callback, thisArg);
2932 forEach(collection, function(value, key, collection) {
2934 'criteria': callback(value, key, collection),
2940 length = result.length;
2941 result.sort(compareAscending);
2943 result[length] = result[length].value;
2949 * Converts the `collection` to an array.
2953 * @category Collections
2954 * @param {Array|Object|String} collection The collection to convert.
2955 * @returns {Array} Returns the new converted array.
2958 * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
2961 function toArray(collection) {
2962 if (collection && typeof collection.length == 'number') {
2963 return slice(collection);
2965 return values(collection);
2969 * Examines each element in a `collection`, returning an array of all elements
2970 * that have the given `properties`. When checking `properties`, this method
2971 * performs a deep comparison between values to determine if they are equivalent
2977 * @category Collections
2978 * @param {Array|Object|String} collection The collection to iterate over.
2979 * @param {Object} properties The object of property values to filter by.
2980 * @returns {Array} Returns a new array of elements that have the given `properties`.
2984 * { 'name': 'moe', 'age': 40 },
2985 * { 'name': 'larry', 'age': 50 }
2988 * _.where(stooges, { 'age': 40 });
2989 * // => [{ 'name': 'moe', 'age': 40 }]
2993 /*--------------------------------------------------------------------------*/
2996 * Creates an array with all falsey values of `array` removed. The values
2997 * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
3002 * @param {Array} array The array to compact.
3003 * @returns {Array} Returns a new filtered array.
3006 * _.compact([0, 1, false, 2, '', 3]);
3009 function compact(array) {
3011 length = array ? array.length : 0,
3014 while (++index < length) {
3015 var value = array[index];
3024 * Creates an array of `array` elements not present in the other arrays
3025 * using strict equality for comparisons, i.e. `===`.
3030 * @param {Array} array The array to process.
3031 * @param {Array} [array1, array2, ...] Arrays to check.
3032 * @returns {Array} Returns a new array of `array` elements not present in the
3036 * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
3039 function difference(array) {
3041 length = array ? array.length : 0,
3042 flattened = concat.apply(arrayRef, arguments),
3043 contains = cachedContains(flattened, length),
3046 while (++index < length) {
3047 var value = array[index];
3048 if (!contains(value)) {
3056 * Gets the first element of the `array`. If a number `n` is passed, the first
3057 * `n` elements of the `array` are returned. If a `callback` function is passed,
3058 * the first elements the `callback` returns truthy for are returned. The `callback`
3059 * is bound to `thisArg` and invoked with three arguments; (value, index, array).
3061 * If a property name is passed for `callback`, the created "_.pluck" style
3062 * callback will return the property value of the given element.
3064 * If an object is passed for `callback`, the created "_.where" style callback
3065 * will return `true` for elements that have the propeties of the given object,
3072 * @param {Array} array The array to query.
3073 * @param {Function|Object|Number|String} [callback|n] The function called
3074 * per element or the number of elements to return. If a property name or
3075 * object is passed, it will be used to create a "_.pluck" or "_.where"
3076 * style callback, respectively.
3077 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3078 * @returns {Mixed} Returns the first element(s) of `array`.
3081 * _.first([1, 2, 3]);
3084 * _.first([1, 2, 3], 2);
3087 * _.first([1, 2, 3], function(num) {
3093 * { 'name': 'banana', 'organic': true },
3094 * { 'name': 'beet', 'organic': false },
3097 * // using "_.pluck" callback shorthand
3098 * _.first(food, 'organic');
3099 * // => [{ 'name': 'banana', 'organic': true }]
3102 * { 'name': 'apple', 'type': 'fruit' },
3103 * { 'name': 'banana', 'type': 'fruit' },
3104 * { 'name': 'beet', 'type': 'vegetable' }
3107 * // using "_.where" callback shorthand
3108 * _.first(food, { 'type': 'fruit' });
3109 * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
3111 function first(array, callback, thisArg) {
3114 length = array.length;
3116 if (typeof callback != 'number' && callback != null) {
3118 callback = createCallback(callback, thisArg);
3119 while (++index < length && callback(array[index], index, array)) {
3124 if (n == null || thisArg) {
3128 return slice(array, 0, nativeMin(nativeMax(0, n), length));
3133 * Flattens a nested array (the nesting can be to any depth). If `shallow` is
3134 * truthy, `array` will only be flattened a single level.
3139 * @param {Array} array The array to compact.
3140 * @param {Boolean} shallow A flag to indicate only flattening a single level.
3141 * @returns {Array} Returns a new flattened array.
3144 * _.flatten([1, [2], [3, [[4]]]]);
3145 * // => [1, 2, 3, 4];
3147 * _.flatten([1, [2], [3, [[4]]]], true);
3148 * // => [1, 2, 3, [[4]]];
3150 function flatten(array, shallow) {
3152 length = array ? array.length : 0,
3155 while (++index < length) {
3156 var value = array[index];
3158 // recursively flatten arrays (susceptible to call stack limits)
3159 if (isArray(value)) {
3160 push.apply(result, shallow ? value : flatten(value));
3169 * Gets the index at which the first occurrence of `value` is found using
3170 * strict equality for comparisons, i.e. `===`. If the `array` is already
3171 * sorted, passing `true` for `fromIndex` will run a faster binary search.
3176 * @param {Array} array The array to search.
3177 * @param {Mixed} value The value to search for.
3178 * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to
3179 * perform a binary search on a sorted `array`.
3180 * @returns {Number} Returns the index of the matched value or `-1`.
3183 * _.indexOf([1, 2, 3, 1, 2, 3], 2);
3186 * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
3189 * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
3192 function indexOf(array, value, fromIndex) {
3194 length = array ? array.length : 0;
3196 if (typeof fromIndex == 'number') {
3197 index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
3198 } else if (fromIndex) {
3199 index = sortedIndex(array, value);
3200 return array[index] === value ? index : -1;
3202 while (++index < length) {
3203 if (array[index] === value) {
3211 * Gets all but the last element of `array`. If a number `n` is passed, the
3212 * last `n` elements are excluded from the result. If a `callback` function
3213 * is passed, the last elements the `callback` returns truthy for are excluded
3214 * from the result. The `callback` is bound to `thisArg` and invoked with three
3215 * arguments; (value, index, array).
3217 * If a property name is passed for `callback`, the created "_.pluck" style
3218 * callback will return the property value of the given element.
3220 * If an object is passed for `callback`, the created "_.where" style callback
3221 * will return `true` for elements that have the propeties of the given object,
3227 * @param {Array} array The array to query.
3228 * @param {Function|Object|Number|String} [callback|n=1] The function called
3229 * per element or the number of elements to exclude. If a property name or
3230 * object is passed, it will be used to create a "_.pluck" or "_.where"
3231 * style callback, respectively.
3232 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3233 * @returns {Array} Returns a slice of `array`.
3236 * _.initial([1, 2, 3]);
3239 * _.initial([1, 2, 3], 2);
3242 * _.initial([1, 2, 3], function(num) {
3248 * { 'name': 'beet', 'organic': false },
3249 * { 'name': 'carrot', 'organic': true }
3252 * // using "_.pluck" callback shorthand
3253 * _.initial(food, 'organic');
3254 * // => [{ 'name': 'beet', 'organic': false }]
3257 * { 'name': 'banana', 'type': 'fruit' },
3258 * { 'name': 'beet', 'type': 'vegetable' },
3259 * { 'name': 'carrot', 'type': 'vegetable' }
3262 * // using "_.where" callback shorthand
3263 * _.initial(food, { 'type': 'vegetable' });
3264 * // => [{ 'name': 'banana', 'type': 'fruit' }]
3266 function initial(array, callback, thisArg) {
3271 length = array.length;
3273 if (typeof callback != 'number' && callback != null) {
3275 callback = createCallback(callback, thisArg);
3276 while (index-- && callback(array[index], index, array)) {
3280 n = (callback == null || thisArg) ? 1 : callback || n;
3282 return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
3286 * Computes the intersection of all the passed-in arrays using strict equality
3287 * for comparisons, i.e. `===`.
3292 * @param {Array} [array1, array2, ...] Arrays to process.
3293 * @returns {Array} Returns a new array of unique elements that are present
3294 * in **all** of the arrays.
3297 * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
3300 function intersection(array) {
3301 var args = arguments,
3302 argsLength = args.length,
3303 cache = { '0': {} },
3305 length = array ? array.length : 0,
3306 isLarge = length >= 100,
3311 while (++index < length) {
3312 var value = array[index];
3314 var key = value + '';
3315 var inited = hasOwnProperty.call(cache[0], key)
3316 ? !(seen = cache[0][key])
3317 : (seen = cache[0][key] = []);
3319 if (inited || indexOf(seen, value) < 0) {
3323 var argsIndex = argsLength;
3324 while (--argsIndex) {
3325 if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex], 0, 100)))(value)) {
3336 * Gets the last element of the `array`. If a number `n` is passed, the last
3337 * `n` elements of the `array` are returned. If a `callback` function is passed,
3338 * the last elements the `callback` returns truthy for are returned. The `callback`
3339 * is bound to `thisArg` and invoked with three arguments; (value, index, array).
3342 * If a property name is passed for `callback`, the created "_.pluck" style
3343 * callback will return the property value of the given element.
3345 * If an object is passed for `callback`, the created "_.where" style callback
3346 * will return `true` for elements that have the propeties of the given object,
3352 * @param {Array} array The array to query.
3353 * @param {Function|Object|Number|String} [callback|n] The function called
3354 * per element or the number of elements to return. If a property name or
3355 * object is passed, it will be used to create a "_.pluck" or "_.where"
3356 * style callback, respectively.
3357 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3358 * @returns {Mixed} Returns the last element(s) of `array`.
3361 * _.last([1, 2, 3]);
3364 * _.last([1, 2, 3], 2);
3367 * _.last([1, 2, 3], function(num) {
3373 * { 'name': 'beet', 'organic': false },
3374 * { 'name': 'carrot', 'organic': true }
3377 * // using "_.pluck" callback shorthand
3378 * _.last(food, 'organic');
3379 * // => [{ 'name': 'carrot', 'organic': true }]
3382 * { 'name': 'banana', 'type': 'fruit' },
3383 * { 'name': 'beet', 'type': 'vegetable' },
3384 * { 'name': 'carrot', 'type': 'vegetable' }
3387 * // using "_.where" callback shorthand
3388 * _.last(food, { 'type': 'vegetable' });
3389 * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
3391 function last(array, callback, thisArg) {
3394 length = array.length;
3396 if (typeof callback != 'number' && callback != null) {
3398 callback = createCallback(callback, thisArg);
3399 while (index-- && callback(array[index], index, array)) {
3404 if (n == null || thisArg) {
3405 return array[length - 1];
3408 return slice(array, nativeMax(0, length - n));
3413 * Gets the index at which the last occurrence of `value` is found using strict
3414 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
3415 * as the offset from the end of the collection.
3420 * @param {Array} array The array to search.
3421 * @param {Mixed} value The value to search for.
3422 * @param {Number} [fromIndex=array.length-1] The index to search from.
3423 * @returns {Number} Returns the index of the matched value or `-1`.
3426 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
3429 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
3432 function lastIndexOf(array, value, fromIndex) {
3433 var index = array ? array.length : 0;
3434 if (typeof fromIndex == 'number') {
3435 index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
3438 if (array[index] === value) {
3446 * Creates an object composed from arrays of `keys` and `values`. Pass either
3447 * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or
3448 * two arrays, one of `keys` and one of corresponding `values`.
3453 * @param {Array} keys The array of keys.
3454 * @param {Array} [values=[]] The array of values.
3455 * @returns {Object} Returns an object composed of the given keys and
3456 * corresponding values.
3459 * _.object(['moe', 'larry'], [30, 40]);
3460 * // => { 'moe': 30, 'larry': 40 }
3462 function object(keys, values) {
3464 length = keys ? keys.length : 0,
3467 while (++index < length) {
3468 var key = keys[index];
3470 result[key] = values[index];
3472 result[key[0]] = key[1];
3479 * Creates an array of numbers (positive and/or negative) progressing from
3480 * `start` up to but not including `end`.
3485 * @param {Number} [start=0] The start of the range.
3486 * @param {Number} end The end of the range.
3487 * @param {Number} [step=1] The value to increment or descrement by.
3488 * @returns {Array} Returns a new range array.
3492 * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3495 * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
3497 * _.range(0, 30, 5);
3498 * // => [0, 5, 10, 15, 20, 25]
3500 * _.range(0, -10, -1);
3501 * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
3506 function range(start, end, step) {
3507 start = +start || 0;
3514 // use `Array(length)` so V8 will avoid the slower "dictionary" mode
3515 // http://youtu.be/XAqIpGU8ZZk#t=17m25s
3517 length = nativeMax(0, ceil((end - start) / step)),
3518 result = Array(length);
3520 while (++index < length) {
3521 result[index] = start;
3528 * The opposite of `_.initial`, this method gets all but the first value of `array`.
3529 * If a number `n` is passed, the first `n` values are excluded from the result.
3530 * If a `callback` function is passed, the first elements the `callback` returns
3531 * truthy for are excluded from the result. The `callback` is bound to `thisArg`
3532 * and invoked with three arguments; (value, index, array).
3534 * If a property name is passed for `callback`, the created "_.pluck" style
3535 * callback will return the property value of the given element.
3537 * If an object is passed for `callback`, the created "_.where" style callback
3538 * will return `true` for elements that have the propeties of the given object,
3545 * @param {Array} array The array to query.
3546 * @param {Function|Object|Number|String} [callback|n=1] The function called
3547 * per element or the number of elements to exclude. If a property name or
3548 * object is passed, it will be used to create a "_.pluck" or "_.where"
3549 * style callback, respectively.
3550 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3551 * @returns {Array} Returns a slice of `array`.
3554 * _.rest([1, 2, 3]);
3557 * _.rest([1, 2, 3], 2);
3560 * _.rest([1, 2, 3], function(num) {
3566 * { 'name': 'banana', 'organic': true },
3567 * { 'name': 'beet', 'organic': false },
3570 * // using "_.pluck" callback shorthand
3571 * _.rest(food, 'organic');
3572 * // => [{ 'name': 'beet', 'organic': false }]
3575 * { 'name': 'apple', 'type': 'fruit' },
3576 * { 'name': 'banana', 'type': 'fruit' },
3577 * { 'name': 'beet', 'type': 'vegetable' }
3580 * // using "_.where" callback shorthand
3581 * _.rest(food, { 'type': 'fruit' });
3582 * // => [{ 'name': 'beet', 'type': 'vegetable' }]
3584 function rest(array, callback, thisArg) {
3585 if (typeof callback != 'number' && callback != null) {
3588 length = array ? array.length : 0;
3590 callback = createCallback(callback, thisArg);
3591 while (++index < length && callback(array[index], index, array)) {
3595 n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
3597 return slice(array, n);
3601 * Uses a binary search to determine the smallest index at which the `value`
3602 * should be inserted into `array` in order to maintain the sort order of the
3603 * sorted `array`. If `callback` is passed, it will be executed for `value` and
3604 * each element in `array` to compute their sort ranking. The `callback` is
3605 * bound to `thisArg` and invoked with one argument; (value).
3607 * If a property name is passed for `callback`, the created "_.pluck" style
3608 * callback will return the property value of the given element.
3610 * If an object is passed for `callback`, the created "_.where" style callback
3611 * will return `true` for elements that have the propeties of the given object,
3617 * @param {Array} array The array to iterate over.
3618 * @param {Mixed} value The value to evaluate.
3619 * @param {Function|Object|String} [callback=identity] The function called per
3620 * iteration. If a property name or object is passed, it will be used to create
3621 * a "_.pluck" or "_.where" style callback, respectively.
3622 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3623 * @returns {Number} Returns the index at which the value should be inserted
3627 * _.sortedIndex([20, 30, 50], 40);
3630 * // using "_.pluck" callback shorthand
3631 * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
3635 * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
3638 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3639 * return dict.wordToNumber[word];
3643 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3644 * return this.wordToNumber[word];
3648 function sortedIndex(array, value, callback, thisArg) {
3650 high = array ? array.length : low;
3652 // explicitly reference `identity` for better inlining in Firefox
3653 callback = callback ? createCallback(callback, thisArg, 1) : identity;
3654 value = callback(value);
3656 while (low < high) {
3657 var mid = (low + high) >>> 1;
3658 callback(array[mid]) < value
3666 * Computes the union of the passed-in arrays using strict equality for
3667 * comparisons, i.e. `===`.
3672 * @param {Array} [array1, array2, ...] Arrays to process.
3673 * @returns {Array} Returns a new array of unique values, in order, that are
3674 * present in one or more of the arrays.
3677 * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
3678 * // => [1, 2, 3, 101, 10]
3681 return uniq(concat.apply(arrayRef, arguments));
3685 * Creates a duplicate-value-free version of the `array` using strict equality
3686 * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
3687 * for `isSorted` will run a faster algorithm. If `callback` is passed, each
3688 * element of `array` is passed through a callback` before uniqueness is computed.
3689 * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
3691 * If a property name is passed for `callback`, the created "_.pluck" style
3692 * callback will return the property value of the given element.
3694 * If an object is passed for `callback`, the created "_.where" style callback
3695 * will return `true` for elements that have the propeties of the given object,
3702 * @param {Array} array The array to process.
3703 * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
3704 * @param {Function|Object|String} [callback=identity] The function called per
3705 * iteration. If a property name or object is passed, it will be used to create
3706 * a "_.pluck" or "_.where" style callback, respectively.
3707 * @param {Mixed} [thisArg] The `this` binding of `callback`.
3708 * @returns {Array} Returns a duplicate-value-free array.
3711 * _.uniq([1, 2, 1, 3, 1]);
3714 * _.uniq([1, 1, 2, 2, 3], true);
3717 * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); });
3720 * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math);
3723 * // using "_.pluck" callback shorthand
3724 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
3725 * // => [{ 'x': 1 }, { 'x': 2 }]
3727 function uniq(array, isSorted, callback, thisArg) {
3729 length = array ? array.length : 0,
3734 if (typeof isSorted == 'function') {
3736 callback = isSorted;
3739 // init value cache for large arrays
3740 var isLarge = !isSorted && length >= 75;
3746 callback = createCallback(callback, thisArg);
3748 while (++index < length) {
3749 var value = array[index],
3750 computed = callback ? callback(value, index, array) : value;
3753 var key = computed + '';
3754 var inited = hasOwnProperty.call(cache, key)
3755 ? !(seen = cache[key])
3756 : (seen = cache[key] = []);
3759 ? !index || seen[seen.length - 1] !== computed
3760 : inited || indexOf(seen, computed) < 0
3762 if (callback || isLarge) {
3763 seen.push(computed);
3772 * Creates an array with all occurrences of the passed values removed using
3773 * strict equality for comparisons, i.e. `===`.
3778 * @param {Array} array The array to filter.
3779 * @param {Mixed} [value1, value2, ...] Values to remove.
3780 * @returns {Array} Returns a new filtered array.
3783 * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
3786 function without(array) {
3788 length = array ? array.length : 0,
3789 contains = cachedContains(arguments, 1),
3792 while (++index < length) {
3793 var value = array[index];
3794 if (!contains(value)) {
3802 * Groups the elements of each array at their corresponding indexes. Useful for
3803 * separate data sources that are coordinated through matching array indexes.
3804 * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix
3805 * in a similar fashion.
3810 * @param {Array} [array1, array2, ...] Arrays to process.
3811 * @returns {Array} Returns a new array of grouped elements.
3814 * _.zip(['moe', 'larry'], [30, 40], [true, false]);
3815 * // => [['moe', 30, true], ['larry', 40, false]]
3817 function zip(array) {
3819 length = array ? max(pluck(arguments, 'length')) : 0,
3820 result = Array(length);
3822 while (++index < length) {
3823 result[index] = pluck(arguments, index);
3828 /*--------------------------------------------------------------------------*/
3831 * Creates a function that is restricted to executing `func` only after it is
3832 * called `n` times. The `func` is executed with the `this` binding of the
3837 * @category Functions
3838 * @param {Number} n The number of times the function must be called before
3840 * @param {Function} func The function to restrict.
3841 * @returns {Function} Returns the new restricted function.
3844 * var renderNotes = _.after(notes.length, render);
3845 * _.forEach(notes, function(note) {
3846 * note.asyncSave({ 'success': renderNotes });
3848 * // `renderNotes` is run once, after all notes have saved
3850 function after(n, func) {
3856 return func.apply(this, arguments);
3862 * Creates a function that, when called, invokes `func` with the `this`
3863 * binding of `thisArg` and prepends any additional `bind` arguments to those
3864 * passed to the bound function.
3868 * @category Functions
3869 * @param {Function} func The function to bind.
3870 * @param {Mixed} [thisArg] The `this` binding of `func`.
3871 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
3872 * @returns {Function} Returns the new bound function.
3875 * var func = function(greeting) {
3876 * return greeting + ' ' + this.name;
3879 * func = _.bind(func, { 'name': 'moe' }, 'hi');
3883 function bind(func, thisArg) {
3884 // use `Function#bind` if it exists and is fast
3885 // (in V8 `Function#bind` is slower except when partially applied)
3886 return isBindFast || (nativeBind && arguments.length > 2)
3887 ? nativeBind.call.apply(nativeBind, arguments)
3888 : createBound(func, thisArg, slice(arguments, 2));
3892 * Binds methods on `object` to `object`, overwriting the existing method.
3893 * Method names may be specified as individual arguments or as arrays of method
3894 * names. If no method names are provided, all the function properties of `object`
3899 * @category Functions
3900 * @param {Object} object The object to bind and assign the bound methods to.
3901 * @param {String} [methodName1, methodName2, ...] Method names on the object to bind.
3902 * @returns {Object} Returns `object`.
3907 * 'onClick': function() { alert('clicked ' + this.label); }
3911 * jQuery('#docs').on('click', view.onClick);
3912 * // => alerts 'clicked docs', when the button is clicked
3914 function bindAll(object) {
3915 var funcs = concat.apply(arrayRef, arguments),
3916 index = funcs.length > 1 ? 0 : (funcs = functions(object), -1),
3917 length = funcs.length;
3919 while (++index < length) {
3920 var key = funcs[index];
3921 object[key] = bind(object[key], object);
3927 * Creates a function that, when called, invokes the method at `object[key]`
3928 * and prepends any additional `bindKey` arguments to those passed to the bound
3929 * function. This method differs from `_.bind` by allowing bound functions to
3930 * reference methods that will be redefined or don't yet exist.
3931 * See http://michaux.ca/articles/lazy-function-definition-pattern.
3935 * @category Functions
3936 * @param {Object} object The object the method belongs to.
3937 * @param {String} key The key of the method.
3938 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
3939 * @returns {Function} Returns the new bound function.
3944 * 'greet': function(greeting) {
3945 * return greeting + ' ' + this.name;
3949 * var func = _.bindKey(object, 'greet', 'hi');
3953 * object.greet = function(greeting) {
3954 * return greeting + ', ' + this.name + '!';
3960 function bindKey(object, key) {
3961 return createBound(object, key, slice(arguments, 2));
3965 * Creates a function that is the composition of the passed functions,
3966 * where each function consumes the return value of the function that follows.
3967 * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
3968 * Each function is executed with the `this` binding of the composed function.
3972 * @category Functions
3973 * @param {Function} [func1, func2, ...] Functions to compose.
3974 * @returns {Function} Returns the new composed function.
3977 * var greet = function(name) { return 'hi ' + name; };
3978 * var exclaim = function(statement) { return statement + '!'; };
3979 * var welcome = _.compose(exclaim, greet);
3983 function compose() {
3984 var funcs = arguments;
3986 var args = arguments,
3987 length = funcs.length;
3990 args = [funcs[length].apply(this, args)];
3997 * Creates a function that will delay the execution of `func` until after
3998 * `wait` milliseconds have elapsed since the last time it was invoked. Pass
3999 * `true` for `immediate` to cause debounce to invoke `func` on the leading,
4000 * instead of the trailing, edge of the `wait` timeout. Subsequent calls to
4001 * the debounced function will return the result of the last `func` call.
4005 * @category Functions
4006 * @param {Function} func The function to debounce.
4007 * @param {Number} wait The number of milliseconds to delay.
4008 * @param {Boolean} immediate A flag to indicate execution is on the leading
4009 * edge of the timeout.
4010 * @returns {Function} Returns the new debounced function.
4013 * var lazyLayout = _.debounce(calculateLayout, 300);
4014 * jQuery(window).on('resize', lazyLayout);
4016 function debounce(func, wait, immediate) {
4022 function delayed() {
4025 result = func.apply(thisArg, args);
4029 var isImmediate = immediate && !timeoutId;
4033 clearTimeout(timeoutId);
4034 timeoutId = setTimeout(delayed, wait);
4037 result = func.apply(thisArg, args);
4044 * Executes the `func` function after `wait` milliseconds. Additional arguments
4045 * will be passed to `func` when it is invoked.
4049 * @category Functions
4050 * @param {Function} func The function to delay.
4051 * @param {Number} wait The number of milliseconds to delay execution.
4052 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
4053 * @returns {Number} Returns the `setTimeout` timeout id.
4056 * var log = _.bind(console.log, console);
4057 * _.delay(log, 1000, 'logged later');
4058 * // => 'logged later' (Appears after one second.)
4060 function delay(func, wait) {
4061 var args = slice(arguments, 2);
4062 return setTimeout(function() { func.apply(undefined, args); }, wait);
4066 * Defers executing the `func` function until the current call stack has cleared.
4067 * Additional arguments will be passed to `func` when it is invoked.
4071 * @category Functions
4072 * @param {Function} func The function to defer.
4073 * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
4074 * @returns {Number} Returns the `setTimeout` timeout id.
4077 * _.defer(function() { alert('deferred'); });
4078 * // returns from the function before `alert` is called
4080 function defer(func) {
4081 var args = slice(arguments, 1);
4082 return setTimeout(function() { func.apply(undefined, args); }, 1);
4084 // use `setImmediate` if it's available in Node.js
4085 if (isV8 && freeModule && typeof setImmediate == 'function') {
4086 defer = bind(setImmediate, window);
4090 * Creates a function that memoizes the result of `func`. If `resolver` is
4091 * passed, it will be used to determine the cache key for storing the result
4092 * based on the arguments passed to the memoized function. By default, the first
4093 * argument passed to the memoized function is used as the cache key. The `func`
4094 * is executed with the `this` binding of the memoized function.
4098 * @category Functions
4099 * @param {Function} func The function to have its output memoized.
4100 * @param {Function} [resolver] A function used to resolve the cache key.
4101 * @returns {Function} Returns the new memoizing function.
4104 * var fibonacci = _.memoize(function(n) {
4105 * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
4108 function memoize(func, resolver) {
4111 var key = (resolver ? resolver.apply(this, arguments) : arguments[0]) + '';
4112 return hasOwnProperty.call(cache, key)
4114 : (cache[key] = func.apply(this, arguments));
4119 * Creates a function that is restricted to execute `func` once. Repeat calls to
4120 * the function will return the value of the first call. The `func` is executed
4121 * with the `this` binding of the created function.
4125 * @category Functions
4126 * @param {Function} func The function to restrict.
4127 * @returns {Function} Returns the new restricted function.
4130 * var initialize = _.once(createApplication);
4133 * // `initialize` executes `createApplication` once
4135 function once(func) {
4144 result = func.apply(this, arguments);
4146 // clear the `func` variable so the function may be garbage collected
4153 * Creates a function that, when called, invokes `func` with any additional
4154 * `partial` arguments prepended to those passed to the new function. This
4155 * method is similar to `_.bind`, except it does **not** alter the `this` binding.
4159 * @category Functions
4160 * @param {Function} func The function to partially apply arguments to.
4161 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
4162 * @returns {Function} Returns the new partially applied function.
4165 * var greet = function(greeting, name) { return greeting + ' ' + name; };
4166 * var hi = _.partial(greet, 'hi');
4170 function partial(func) {
4171 return createBound(func, slice(arguments, 1));
4175 * This method is similar to `_.partial`, except that `partial` arguments are
4176 * appended to those passed to the new function.
4180 * @category Functions
4181 * @param {Function} func The function to partially apply arguments to.
4182 * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
4183 * @returns {Function} Returns the new partially applied function.
4186 * var defaultsDeep = _.partialRight(_.merge, _.defaults);
4189 * 'variable': 'data',
4190 * 'imports': { 'jq': $ }
4193 * defaultsDeep(options, _.templateSettings);
4199 * // => { '_': _, 'jq': $ }
4201 function partialRight(func) {
4202 return createBound(func, slice(arguments, 1), null, indicatorObject);
4206 * Creates a function that, when executed, will only call the `func`
4207 * function at most once per every `wait` milliseconds. If the throttled
4208 * function is invoked more than once during the `wait` timeout, `func` will
4209 * also be called on the trailing edge of the timeout. Subsequent calls to the
4210 * throttled function will return the result of the last `func` call.
4214 * @category Functions
4215 * @param {Function} func The function to throttle.
4216 * @param {Number} wait The number of milliseconds to throttle executions to.
4217 * @returns {Function} Returns the new throttled function.
4220 * var throttled = _.throttle(updatePosition, 100);
4221 * jQuery(window).on('scroll', throttled);
4223 function throttle(func, wait) {
4230 function trailingCall() {
4231 lastCalled = new Date;
4233 result = func.apply(thisArg, args);
4237 remaining = wait - (now - lastCalled);
4242 if (remaining <= 0) {
4243 clearTimeout(timeoutId);
4246 result = func.apply(thisArg, args);
4248 else if (!timeoutId) {
4249 timeoutId = setTimeout(trailingCall, remaining);
4256 * Creates a function that passes `value` to the `wrapper` function as its
4257 * first argument. Additional arguments passed to the function are appended
4258 * to those passed to the `wrapper` function. The `wrapper` is executed with
4259 * the `this` binding of the created function.
4263 * @category Functions
4264 * @param {Mixed} value The value to wrap.
4265 * @param {Function} wrapper The wrapper function.
4266 * @returns {Function} Returns the new function.
4269 * var hello = function(name) { return 'hello ' + name; };
4270 * hello = _.wrap(hello, function(func) {
4271 * return 'before, ' + func('moe') + ', after';
4274 * // => 'before, hello moe, after'
4276 function wrap(value, wrapper) {
4279 push.apply(args, arguments);
4280 return wrapper.apply(this, args);
4284 /*--------------------------------------------------------------------------*/
4287 * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
4288 * corresponding HTML entities.
4292 * @category Utilities
4293 * @param {String} string The string to escape.
4294 * @returns {String} Returns the escaped string.
4297 * _.escape('Moe, Larry & Curly');
4298 * // => 'Moe, Larry & Curly'
4300 function escape(string) {
4301 return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar);
4305 * This function returns the first argument passed to it.
4309 * @category Utilities
4310 * @param {Mixed} value Any value.
4311 * @returns {Mixed} Returns `value`.
4314 * var moe = { 'name': 'moe' };
4315 * moe === _.identity(moe);
4318 function identity(value) {
4323 * Adds functions properties of `object` to the `lodash` function and chainable
4328 * @category Utilities
4329 * @param {Object} object The object of function properties to add to `lodash`.
4333 * 'capitalize': function(string) {
4334 * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
4338 * _.capitalize('moe');
4341 * _('moe').capitalize();
4344 function mixin(object) {
4345 forEach(functions(object), function(methodName) {
4346 var func = lodash[methodName] = object[methodName];
4348 lodash.prototype[methodName] = function() {
4349 var args = [this.__wrapped__];
4350 push.apply(args, arguments);
4351 return new lodash(func.apply(lodash, args));
4357 * Reverts the '_' variable to its previous value and returns a reference to
4358 * the `lodash` function.
4362 * @category Utilities
4363 * @returns {Function} Returns the `lodash` function.
4366 * var lodash = _.noConflict();
4368 function noConflict() {
4374 * Produces a random number between `min` and `max` (inclusive). If only one
4375 * argument is passed, a number between `0` and the given number will be returned.
4379 * @category Utilities
4380 * @param {Number} [min=0] The minimum possible value.
4381 * @param {Number} [max=1] The maximum possible value.
4382 * @returns {Number} Returns a random number.
4386 * // => a number between 0 and 5
4389 * // => also a number between 0 and 5
4391 function random(min, max) {
4392 if (min == null && max == null) {
4400 return min + floor(nativeRandom() * ((+max || 0) - min + 1));
4404 * Resolves the value of `property` on `object`. If `property` is a function,
4405 * it will be invoked and its result returned, else the property value is
4406 * returned. If `object` is falsey, then `null` is returned.
4410 * @category Utilities
4411 * @param {Object} object The object to inspect.
4412 * @param {String} property The property to get the value of.
4413 * @returns {Mixed} Returns the resolved value.
4417 * 'cheese': 'crumpets',
4418 * 'stuff': function() {
4419 * return 'nonsense';
4423 * _.result(object, 'cheese');
4426 * _.result(object, 'stuff');
4429 function result(object, property) {
4430 var value = object ? object[property] : undefined;
4431 return isFunction(value) ? object[property]() : value;
4435 * A micro-templating method that handles arbitrary delimiters, preserves
4436 * whitespace, and correctly escapes quotes within interpolated code.
4438 * Note: In the development build, `_.template` utilizes sourceURLs for easier
4439 * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
4441 * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp`
4442 * build and using precompiled templates, or loading Lo-Dash in a sandbox.
4444 * For more information on precompiling templates see:
4445 * http://lodash.com/#custom-builds
4447 * For more information on Chrome extension sandboxes see:
4448 * http://developer.chrome.com/stable/extensions/sandboxingEval.html
4452 * @category Utilities
4453 * @param {String} text The template text.
4454 * @param {Obect} data The data object used to populate the text.
4455 * @param {Object} options The options object.
4456 * escape - The "escape" delimiter regexp.
4457 * evaluate - The "evaluate" delimiter regexp.
4458 * interpolate - The "interpolate" delimiter regexp.
4459 * sourceURL - The sourceURL of the template's compiled source.
4460 * variable - The data object variable name.
4462 * @returns {Function|String} Returns a compiled function when no `data` object
4463 * is given, else it returns the interpolated text.
4466 * // using a compiled template
4467 * var compiled = _.template('hello <%= name %>');
4468 * compiled({ 'name': 'moe' });
4471 * var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
4472 * _.template(list, { 'people': ['moe', 'larry'] });
4473 * // => '<li>moe</li><li>larry</li>'
4475 * // using the "escape" delimiter to escape HTML in data property values
4476 * _.template('<b><%- value %></b>', { 'value': '<script>' });
4477 * // => '<b><script></b>'
4479 * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
4480 * _.template('hello ${ name }', { 'name': 'curly' });
4481 * // => 'hello curly'
4483 * // using the internal `print` function in "evaluate" delimiters
4484 * _.template('<% print("hello " + epithet); %>!', { 'epithet': 'stooge' });
4485 * // => 'hello stooge!'
4487 * // using custom template delimiters
4488 * _.templateSettings = {
4489 * 'interpolate': /{{([\s\S]+?)}}/g
4492 * _.template('hello {{ name }}!', { 'name': 'mustache' });
4493 * // => 'hello mustache!'
4495 * // using the `sourceURL` option to specify a custom sourceURL for the template
4496 * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
4498 * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
4500 * // using the `variable` option to ensure a with-statement isn't used in the compiled template
4501 * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
4503 * // => function(data) {
4504 * var __t, __p = '', __e = _.escape;
4505 * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
4509 * // using the `source` property to inline compiled templates for meaningful
4510 * // line numbers in error messages and a stack trace
4511 * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
4513 * "main": ' + _.template(mainText).source + '\
4517 function template(text, data, options) {
4518 // based on John Resig's `tmpl` implementation
4519 // http://ejohn.org/blog/javascript-micro-templating/
4520 // and Laura Doktorova's doT.js
4521 // https://github.com/olado/doT
4522 var settings = lodash.templateSettings;
4523 text || (text = '');
4525 // avoid missing dependencies when `iteratorTemplate` is not defined
4526 options = defaults({}, options, settings);
4528 var imports = defaults({}, options.imports, settings.imports),
4529 importsKeys = keys(imports),
4530 importsValues = values(imports);
4534 interpolate = options.interpolate || reNoMatch,
4535 source = "__p += '";
4537 // compile regexp to match each delimiter
4538 var reDelimiters = RegExp(
4539 (options.escape || reNoMatch).source + '|' +
4540 interpolate.source + '|' +
4541 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
4542 (options.evaluate || reNoMatch).source + '|$'
4545 text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
4546 interpolateValue || (interpolateValue = esTemplateValue);
4548 // escape characters that cannot be included in string literals
4549 source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
4551 // replace delimiters with snippets
4553 source += "' +\n__e(" + escapeValue + ") +\n'";
4555 if (evaluateValue) {
4556 isEvaluating = true;
4557 source += "';\n" + evaluateValue + ";\n__p += '";
4559 if (interpolateValue) {
4560 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
4562 index = offset + match.length;
4564 // the JS engine embedded in Adobe products requires returning the `match`
4565 // string in order to produce the correct `offset` value
4571 // if `variable` is not specified and the template contains "evaluate"
4572 // delimiters, wrap a with-statement around the generated code to add the
4573 // data object to the top of the scope chain
4574 var variable = options.variable,
4575 hasVariable = variable;
4579 source = 'with (' + variable + ') {\n' + source + '\n}\n';
4581 // cleanup code by stripping empty strings
4582 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
4583 .replace(reEmptyStringMiddle, '$1')
4584 .replace(reEmptyStringTrailing, '$1;');
4586 // frame code as the function body
4587 source = 'function(' + variable + ') {\n' +
4588 (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
4589 "var __t, __p = '', __e = _.escape" +
4591 ? ', __j = Array.prototype.join;\n' +
4592 "function print() { __p += __j.call(arguments, '') }\n"
4598 // Use a sourceURL for easier debugging and wrap in a multi-line comment to
4599 // avoid issues with Narwhal, IE conditional compilation, and the JS engine
4600 // embedded in Adobe products.
4601 // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
4602 var sourceURL = '\n/*\n//@ sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
4605 var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
4611 return result(data);
4613 // provide the compiled function's source via its `toString` method, in
4614 // supported environments, or the `source` property as a convenience for
4615 // inlining compiled templates during the build process
4616 result.source = source;
4621 * Executes the `callback` function `n` times, returning an array of the results
4622 * of each `callback` execution. The `callback` is bound to `thisArg` and invoked
4623 * with one argument; (index).
4627 * @category Utilities
4628 * @param {Number} n The number of times to execute the callback.
4629 * @param {Function} callback The function called per iteration.
4630 * @param {Mixed} [thisArg] The `this` binding of `callback`.
4631 * @returns {Array} Returns a new array of the results of each `callback` execution.
4634 * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
4637 * _.times(3, function(n) { mage.castSpell(n); });
4638 * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
4640 * _.times(3, function(n) { this.cast(n); }, mage);
4641 * // => also calls `mage.castSpell(n)` three times
4643 function times(n, callback, thisArg) {
4648 while (++index < n) {
4649 result[index] = callback.call(thisArg, index);
4655 * The opposite of `_.escape`, this method converts the HTML entities
4656 * `&`, `<`, `>`, `"`, and `'` in `string` to their
4657 * corresponding characters.
4661 * @category Utilities
4662 * @param {String} string The string to unescape.
4663 * @returns {String} Returns the unescaped string.
4666 * _.unescape('Moe, Larry & Curly');
4667 * // => 'Moe, Larry & Curly'
4669 function unescape(string) {
4670 return string == null ? '' : (string + '').replace(reEscapedHtml, unescapeHtmlChar);
4674 * Generates a unique ID. If `prefix` is passed, the ID will be appended to it.
4678 * @category Utilities
4679 * @param {String} [prefix] The value to prefix the ID with.
4680 * @returns {String} Returns the unique ID.
4683 * _.uniqueId('contact_');
4684 * // => 'contact_104'
4689 function uniqueId(prefix) {
4690 var id = ++idCounter;
4691 return (prefix == null ? '' : prefix + '') + id;
4694 /*--------------------------------------------------------------------------*/
4697 * Invokes `interceptor` with the `value` as the first argument, and then
4698 * returns `value`. The purpose of this method is to "tap into" a method chain,
4699 * in order to perform operations on intermediate results within the chain.
4703 * @category Chaining
4704 * @param {Mixed} value The value to pass to `interceptor`.
4705 * @param {Function} interceptor The function to invoke.
4706 * @returns {Mixed} Returns `value`.
4710 * .filter(function(num) { return num % 2 == 0; })
4712 * .map(function(num) { return num * num; })
4714 * // => // [2, 4] (alerted)
4717 function tap(value, interceptor) {
4723 * Produces the `toString` result of the wrapped value.
4727 * @category Chaining
4728 * @returns {String} Returns the string result.
4731 * _([1, 2, 3]).toString();
4734 function wrapperToString() {
4735 return this.__wrapped__ + '';
4739 * Extracts the wrapped value.
4744 * @category Chaining
4745 * @returns {Mixed} Returns the wrapped value.
4748 * _([1, 2, 3]).valueOf();
4751 function wrapperValueOf() {
4752 return this.__wrapped__;
4755 /*--------------------------------------------------------------------------*/
4757 // add functions that return wrapped values when chaining
4758 lodash.after = after;
4759 lodash.assign = assign;
4762 lodash.bindAll = bindAll;
4763 lodash.bindKey = bindKey;
4764 lodash.compact = compact;
4765 lodash.compose = compose;
4766 lodash.countBy = countBy;
4767 lodash.debounce = debounce;
4768 lodash.defaults = defaults;
4769 lodash.defer = defer;
4770 lodash.delay = delay;
4771 lodash.difference = difference;
4772 lodash.filter = filter;
4773 lodash.flatten = flatten;
4774 lodash.forEach = forEach;
4775 lodash.forIn = forIn;
4776 lodash.forOwn = forOwn;
4777 lodash.functions = functions;
4778 lodash.groupBy = groupBy;
4779 lodash.initial = initial;
4780 lodash.intersection = intersection;
4781 lodash.invert = invert;
4782 lodash.invoke = invoke;
4786 lodash.memoize = memoize;
4787 lodash.merge = merge;
4789 lodash.object = object;
4792 lodash.pairs = pairs;
4793 lodash.partial = partial;
4794 lodash.partialRight = partialRight;
4796 lodash.pluck = pluck;
4797 lodash.range = range;
4798 lodash.reject = reject;
4800 lodash.shuffle = shuffle;
4801 lodash.sortBy = sortBy;
4803 lodash.throttle = throttle;
4804 lodash.times = times;
4805 lodash.toArray = toArray;
4806 lodash.union = union;
4808 lodash.values = values;
4809 lodash.where = where;
4810 lodash.without = without;
4815 lodash.collect = map;
4817 lodash.each = forEach;
4818 lodash.extend = assign;
4819 lodash.methods = functions;
4820 lodash.select = filter;
4822 lodash.unique = uniq;
4824 // add functions to `lodash.prototype`
4827 /*--------------------------------------------------------------------------*/
4829 // add functions that return unwrapped values when chaining
4830 lodash.clone = clone;
4831 lodash.cloneDeep = cloneDeep;
4832 lodash.contains = contains;
4833 lodash.escape = escape;
4834 lodash.every = every;
4837 lodash.identity = identity;
4838 lodash.indexOf = indexOf;
4839 lodash.isArguments = isArguments;
4840 lodash.isArray = isArray;
4841 lodash.isBoolean = isBoolean;
4842 lodash.isDate = isDate;
4843 lodash.isElement = isElement;
4844 lodash.isEmpty = isEmpty;
4845 lodash.isEqual = isEqual;
4846 lodash.isFinite = isFinite;
4847 lodash.isFunction = isFunction;
4848 lodash.isNaN = isNaN;
4849 lodash.isNull = isNull;
4850 lodash.isNumber = isNumber;
4851 lodash.isObject = isObject;
4852 lodash.isPlainObject = isPlainObject;
4853 lodash.isRegExp = isRegExp;
4854 lodash.isString = isString;
4855 lodash.isUndefined = isUndefined;
4856 lodash.lastIndexOf = lastIndexOf;
4857 lodash.mixin = mixin;
4858 lodash.noConflict = noConflict;
4859 lodash.random = random;
4860 lodash.reduce = reduce;
4861 lodash.reduceRight = reduceRight;
4862 lodash.result = result;
4865 lodash.sortedIndex = sortedIndex;
4866 lodash.template = template;
4867 lodash.unescape = unescape;
4868 lodash.uniqueId = uniqueId;
4873 lodash.detect = find;
4874 lodash.foldl = reduce;
4875 lodash.foldr = reduceRight;
4876 lodash.include = contains;
4877 lodash.inject = reduce;
4879 forOwn(lodash, function(func, methodName) {
4880 if (!lodash.prototype[methodName]) {
4881 lodash.prototype[methodName] = function() {
4882 var args = [this.__wrapped__];
4883 push.apply(args, arguments);
4884 return func.apply(lodash, args);
4889 /*--------------------------------------------------------------------------*/
4891 // add functions capable of returning wrapped and unwrapped values when chaining
4892 lodash.first = first;
4896 lodash.take = first;
4897 lodash.head = first;
4899 forOwn(lodash, function(func, methodName) {
4900 if (!lodash.prototype[methodName]) {
4901 lodash.prototype[methodName]= function(callback, thisArg) {
4902 var result = func(this.__wrapped__, callback, thisArg);
4903 return callback == null || (thisArg && typeof callback != 'function')
4905 : new lodash(result);
4910 /*--------------------------------------------------------------------------*/
4913 * The semantic version number.
4919 lodash.VERSION = '1.0.2';
4921 // add "Chaining" functions to the wrapper
4922 lodash.prototype.toString = wrapperToString;
4923 lodash.prototype.value = wrapperValueOf;
4924 lodash.prototype.valueOf = wrapperValueOf;
4926 // add `Array` functions that return unwrapped values
4927 each(['join', 'pop', 'shift'], function(methodName) {
4928 var func = arrayRef[methodName];
4929 lodash.prototype[methodName] = function() {
4930 return func.apply(this.__wrapped__, arguments);
4934 // add `Array` functions that return the wrapped value
4935 each(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
4936 var func = arrayRef[methodName];
4937 lodash.prototype[methodName] = function() {
4938 func.apply(this.__wrapped__, arguments);
4943 // add `Array` functions that return new wrapped values
4944 each(['concat', 'slice', 'splice'], function(methodName) {
4945 var func = arrayRef[methodName];
4946 lodash.prototype[methodName] = function() {
4947 return new lodash(func.apply(this.__wrapped__, arguments));
4951 /*--------------------------------------------------------------------------*/
4954 // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
4955 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
4956 // Expose Lo-Dash to the global object even when an AMD loader is present in
4957 // case Lo-Dash was injected by a third-party script and not intended to be
4958 // loaded as a module. The global assignment can be reverted in the Lo-Dash
4959 // module via its `noConflict()` method.
4962 // define as an anonymous module so, through path mapping, it can be
4963 // referenced as the "underscore" module
4968 // check for `exports` after `define` in case a build optimizer adds an `exports` object
4969 else if (freeExports) {
4970 // in Node.js or RingoJS v0.8.0+
4972 (freeModule.exports = lodash)._ = lodash;
4974 // in Narwhal or RingoJS v0.7.0-
4976 freeExports._ = lodash;
4980 // in a browser or Rhino