PageRenderTime 58ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/ajax/libs/lodash.js/1.2.0/lodash.underscore.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 1651 lines | 828 code | 72 blank | 751 comment | 134 complexity | 0e7cab5cc097f63840df5ed4b5371680 MD5 | raw file
  1. /**
  2. * @license
  3. * Lo-Dash 1.2.0 (Custom Build) <http://lodash.com/>
  4. * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js`
  5. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  6. * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
  7. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
  8. * Available under MIT license <http://lodash.com/license>
  9. */
  10. ;(function(window) {
  11. /** Used as a safe reference for `undefined` in pre ES5 environments */
  12. var undefined;
  13. /** Detect free variable `exports` */
  14. var freeExports = typeof exports == 'object' && exports;
  15. /** Detect free variable `module` */
  16. var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
  17. /** Detect free variable `global`, from Node.js or Browserified code, and use it as `window` */
  18. var freeGlobal = typeof global == 'object' && global;
  19. if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
  20. window = freeGlobal;
  21. }
  22. /** Used to generate unique IDs */
  23. var idCounter = 0;
  24. /** Used internally to indicate various things */
  25. var indicatorObject = {};
  26. /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
  27. var keyPrefix = +new Date + '';
  28. /** Used as the size when optimizations are enabled for large arrays */
  29. var largeArraySize = 200;
  30. /** Used to match empty string literals in compiled template source */
  31. var reEmptyStringLeading = /\b__p \+= '';/g,
  32. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  33. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  34. /** Used to match HTML entities */
  35. var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
  36. /**
  37. * Used to match ES6 template delimiters
  38. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
  39. */
  40. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  41. /** Used to match regexp flags from their coerced string values */
  42. var reFlags = /\w*$/;
  43. /** Used to match "interpolate" template delimiters */
  44. var reInterpolate = /<%=([\s\S]+?)%>/g;
  45. /** Used to ensure capturing order of template delimiters */
  46. var reNoMatch = /($^)/;
  47. /** Used to match HTML characters */
  48. var reUnescapedHtml = /[&<>"']/g;
  49. /** Used to match unescaped characters in compiled string literals */
  50. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  51. /** Used to make template sourceURLs easier to identify */
  52. var templateCounter = 0;
  53. /** `Object#toString` result shortcuts */
  54. var argsClass = '[object Arguments]',
  55. arrayClass = '[object Array]',
  56. boolClass = '[object Boolean]',
  57. dateClass = '[object Date]',
  58. funcClass = '[object Function]',
  59. numberClass = '[object Number]',
  60. objectClass = '[object Object]',
  61. regexpClass = '[object RegExp]',
  62. stringClass = '[object String]';
  63. /** Used to determine if values are of the language type Object */
  64. var objectTypes = {
  65. 'boolean': false,
  66. 'function': true,
  67. 'object': true,
  68. 'number': false,
  69. 'string': false,
  70. 'undefined': false
  71. };
  72. /** Used to escape characters for inclusion in compiled string literals */
  73. var stringEscapes = {
  74. '\\': '\\',
  75. "'": "'",
  76. '\n': 'n',
  77. '\r': 'r',
  78. '\t': 't',
  79. '\u2028': 'u2028',
  80. '\u2029': 'u2029'
  81. };
  82. /*--------------------------------------------------------------------------*/
  83. /** Used for `Array` and `Object` method references */
  84. var arrayRef = Array(),
  85. objectRef = Object();
  86. /** Used to restore the original `_` reference in `noConflict` */
  87. var oldDash = window._;
  88. /** Used to detect if a method is native */
  89. var reNative = RegExp('^' +
  90. String(objectRef.valueOf)
  91. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  92. .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
  93. );
  94. /** Native method shortcuts */
  95. var ceil = Math.ceil,
  96. clearTimeout = window.clearTimeout,
  97. concat = arrayRef.concat,
  98. floor = Math.floor,
  99. hasOwnProperty = objectRef.hasOwnProperty,
  100. push = arrayRef.push,
  101. setTimeout = window.setTimeout,
  102. toString = objectRef.toString;
  103. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  104. var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
  105. nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
  106. nativeIsFinite = window.isFinite,
  107. nativeIsNaN = window.isNaN,
  108. nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
  109. nativeMax = Math.max,
  110. nativeMin = Math.min,
  111. nativeRandom = Math.random,
  112. nativeSlice = arrayRef.slice;
  113. /** Detect various environments */
  114. var isIeOpera = reNative.test(window.attachEvent),
  115. isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
  116. /*--------------------------------------------------------------------------*/
  117. /**
  118. * Creates a `lodash` object, which wraps the given `value`, to enable method
  119. * chaining.
  120. *
  121. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  122. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  123. * and `unshift`
  124. *
  125. * Chaining is supported in custom builds as long as the `value` method is
  126. * implicitly or explicitly included in the build.
  127. *
  128. * The chainable wrapper functions are:
  129. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
  130. * `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`,
  131. * `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`,
  132. * `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`,
  133. * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
  134. * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
  135. * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
  136. * `tap`, `throttle`, `times`, `toArray`, `union`, `uniq`, `unshift`, `unzip`,
  137. * `values`, `where`, `without`, `wrap`, and `zip`
  138. *
  139. * The non-chainable wrapper functions are:
  140. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
  141. * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`,
  142. * `isElement`, `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`,
  143. * `isNull`, `isNumber`, `isObject`, `isPlainObject`, `isRegExp`, `isString`,
  144. * `isUndefined`, `join`, `lastIndexOf`, `mixin`, `noConflict`, `parseInt`,
  145. * `pop`, `random`, `reduce`, `reduceRight`, `result`, `shift`, `size`, `some`,
  146. * `sortedIndex`, `runInContext`, `template`, `unescape`, `uniqueId`, and `value`
  147. *
  148. * The wrapper functions `first` and `last` return wrapped values when `n` is
  149. * passed, otherwise they return unwrapped values.
  150. *
  151. * @name _
  152. * @constructor
  153. * @category Chaining
  154. * @param {Mixed} value The value to wrap in a `lodash` instance.
  155. * @returns {Object} Returns a `lodash` instance.
  156. * @example
  157. *
  158. * var wrapped = _([1, 2, 3]);
  159. *
  160. * // returns an unwrapped value
  161. * wrapped.reduce(function(sum, num) {
  162. * return sum + num;
  163. * });
  164. * // => 6
  165. *
  166. * // returns a wrapped value
  167. * var squares = wrapped.map(function(num) {
  168. * return num * num;
  169. * });
  170. *
  171. * _.isArray(squares);
  172. * // => false
  173. *
  174. * _.isArray(squares.value());
  175. * // => true
  176. */
  177. function lodash(value) {
  178. return (value instanceof lodash)
  179. ? value
  180. : new lodashWrapper(value);
  181. }
  182. /**
  183. * An object used to flag environments features.
  184. *
  185. * @static
  186. * @memberOf _
  187. * @type Object
  188. */
  189. var support = {};
  190. (function() {
  191. var object = { '0': 1, 'length': 1 };
  192. /**
  193. * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
  194. *
  195. * @memberOf _.support
  196. * @type Boolean
  197. */
  198. support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
  199. /**
  200. * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
  201. *
  202. * @memberOf _.support
  203. * @type Boolean
  204. */
  205. support.fastBind = nativeBind && !isV8;
  206. /**
  207. * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
  208. *
  209. * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
  210. * and `splice()` functions that fail to remove the last element, `value[0]`,
  211. * of array-like objects even though the `length` property is set to `0`.
  212. * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
  213. * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
  214. *
  215. * @memberOf _.support
  216. * @type Boolean
  217. */
  218. support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
  219. }(1));
  220. /**
  221. * By default, the template delimiters used by Lo-Dash are similar to those in
  222. * embedded Ruby (ERB). Change the following template settings to use alternative
  223. * delimiters.
  224. *
  225. * @static
  226. * @memberOf _
  227. * @type Object
  228. */
  229. lodash.templateSettings = {
  230. /**
  231. * Used to detect `data` property values to be HTML-escaped.
  232. *
  233. * @memberOf _.templateSettings
  234. * @type RegExp
  235. */
  236. 'escape': /<%-([\s\S]+?)%>/g,
  237. /**
  238. * Used to detect code to be evaluated.
  239. *
  240. * @memberOf _.templateSettings
  241. * @type RegExp
  242. */
  243. 'evaluate': /<%([\s\S]+?)%>/g,
  244. /**
  245. * Used to detect `data` property values to inject.
  246. *
  247. * @memberOf _.templateSettings
  248. * @type RegExp
  249. */
  250. 'interpolate': reInterpolate,
  251. /**
  252. * Used to reference the data object in the template text.
  253. *
  254. * @memberOf _.templateSettings
  255. * @type String
  256. */
  257. 'variable': ''
  258. };
  259. /*--------------------------------------------------------------------------*/
  260. /**
  261. * Used by `_.max` and `_.min` as the default `callback` when a given
  262. * `collection` is a string value.
  263. *
  264. * @private
  265. * @param {String} value The character to inspect.
  266. * @returns {Number} Returns the code unit of given character.
  267. */
  268. function charAtCallback(value) {
  269. return value.charCodeAt(0);
  270. }
  271. /**
  272. * Used by `sortBy` to compare transformed `collection` values, stable sorting
  273. * them in ascending order.
  274. *
  275. * @private
  276. * @param {Object} a The object to compare to `b`.
  277. * @param {Object} b The object to compare to `a`.
  278. * @returns {Number} Returns the sort order indicator of `1` or `-1`.
  279. */
  280. function compareAscending(a, b) {
  281. var ai = a.index,
  282. bi = b.index;
  283. a = a.criteria;
  284. b = b.criteria;
  285. // ensure a stable sort in V8 and other engines
  286. // http://code.google.com/p/v8/issues/detail?id=90
  287. if (a !== b) {
  288. if (a > b || typeof a == 'undefined') {
  289. return 1;
  290. }
  291. if (a < b || typeof b == 'undefined') {
  292. return -1;
  293. }
  294. }
  295. return ai < bi ? -1 : 1;
  296. }
  297. /**
  298. * Creates a function that, when called, invokes `func` with the `this` binding
  299. * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
  300. * bound function.
  301. *
  302. * @private
  303. * @param {Function|String} func The function to bind or the method name.
  304. * @param {Mixed} [thisArg] The `this` binding of `func`.
  305. * @param {Array} partialArgs An array of arguments to be partially applied.
  306. * @param {Object} [idicator] Used to indicate binding by key or partially
  307. * applying arguments from the right.
  308. * @returns {Function} Returns the new bound function.
  309. */
  310. function createBound(func, thisArg, partialArgs, indicator) {
  311. var isFunc = isFunction(func),
  312. isPartial = !partialArgs,
  313. key = thisArg;
  314. // juggle arguments
  315. if (isPartial) {
  316. var rightIndicator = indicator;
  317. partialArgs = thisArg;
  318. }
  319. else if (!isFunc) {
  320. if (!indicator) {
  321. throw new TypeError;
  322. }
  323. thisArg = func;
  324. }
  325. function bound() {
  326. // `Function#bind` spec
  327. // http://es5.github.com/#x15.3.4.5
  328. var args = arguments,
  329. thisBinding = isPartial ? this : thisArg;
  330. if (!isFunc) {
  331. func = thisArg[key];
  332. }
  333. if (partialArgs.length) {
  334. args = args.length
  335. ? (args = nativeSlice.call(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
  336. : partialArgs;
  337. }
  338. if (this instanceof bound) {
  339. // ensure `new bound` is an instance of `func`
  340. noop.prototype = func.prototype;
  341. thisBinding = new noop;
  342. noop.prototype = null;
  343. // mimic the constructor's `return` behavior
  344. // http://es5.github.com/#x13.2.2
  345. var result = func.apply(thisBinding, args);
  346. return isObject(result) ? result : thisBinding;
  347. }
  348. return func.apply(thisBinding, args);
  349. }
  350. return bound;
  351. }
  352. /**
  353. * Used by `template` to escape characters for inclusion in compiled
  354. * string literals.
  355. *
  356. * @private
  357. * @param {String} match The matched character to escape.
  358. * @returns {String} Returns the escaped character.
  359. */
  360. function escapeStringChar(match) {
  361. return '\\' + stringEscapes[match];
  362. }
  363. /**
  364. * Used by `escape` to convert characters to HTML entities.
  365. *
  366. * @private
  367. * @param {String} match The matched character to escape.
  368. * @returns {String} Returns the escaped character.
  369. */
  370. function escapeHtmlChar(match) {
  371. return htmlEscapes[match];
  372. }
  373. /**
  374. * A fast path for creating `lodash` wrapper objects.
  375. *
  376. * @private
  377. * @param {Mixed} value The value to wrap in a `lodash` instance.
  378. * @returns {Object} Returns a `lodash` instance.
  379. */
  380. function lodashWrapper(value) {
  381. this.__wrapped__ = value;
  382. }
  383. // ensure `new lodashWrapper` is an instance of `lodash`
  384. lodashWrapper.prototype = lodash.prototype;
  385. /**
  386. * A no-operation function.
  387. *
  388. * @private
  389. */
  390. function noop() {
  391. // no operation performed
  392. }
  393. /**
  394. * Used by `unescape` to convert HTML entities to characters.
  395. *
  396. * @private
  397. * @param {String} match The matched character to unescape.
  398. * @returns {String} Returns the unescaped character.
  399. */
  400. function unescapeHtmlChar(match) {
  401. return htmlUnescapes[match];
  402. }
  403. /*--------------------------------------------------------------------------*/
  404. /**
  405. * Checks if `value` is an `arguments` object.
  406. *
  407. * @static
  408. * @memberOf _
  409. * @category Objects
  410. * @param {Mixed} value The value to check.
  411. * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
  412. * @example
  413. *
  414. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  415. * // => true
  416. *
  417. * _.isArguments([1, 2, 3]);
  418. * // => false
  419. */
  420. function isArguments(value) {
  421. return toString.call(value) == argsClass;
  422. }
  423. // fallback for browsers that can't detect `arguments` objects by [[Class]]
  424. if (!isArguments(arguments)) {
  425. isArguments = function(value) {
  426. return value ? hasOwnProperty.call(value, 'callee') : false;
  427. };
  428. }
  429. /**
  430. * A fallback implementation of `Object.keys` which produces an array of the
  431. * given object's own enumerable property names.
  432. *
  433. * @private
  434. * @type Function
  435. * @param {Object} object The object to inspect.
  436. * @returns {Array} Returns a new array of property names.
  437. */
  438. var shimKeys = function (object) {
  439. var index, iterable = object, result = [];
  440. if (!iterable) return result;
  441. if (!(objectTypes[typeof object])) return result;
  442. for (index in iterable) {
  443. if (hasOwnProperty.call(iterable, index)) {
  444. result.push(index);
  445. }
  446. }
  447. return result
  448. };
  449. /**
  450. * Creates an array composed of the own enumerable property names of `object`.
  451. *
  452. * @static
  453. * @memberOf _
  454. * @category Objects
  455. * @param {Object} object The object to inspect.
  456. * @returns {Array} Returns a new array of property names.
  457. * @example
  458. *
  459. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  460. * // => ['one', 'two', 'three'] (order is not guaranteed)
  461. */
  462. var keys = !nativeKeys ? shimKeys : function(object) {
  463. if (!isObject(object)) {
  464. return [];
  465. }
  466. return nativeKeys(object);
  467. };
  468. /**
  469. * Used to convert characters to HTML entities:
  470. *
  471. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  472. * don't require escaping in HTML and have no special meaning unless they're part
  473. * of a tag or an unquoted attribute value.
  474. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  475. */
  476. var htmlEscapes = {
  477. '&': '&amp;',
  478. '<': '&lt;',
  479. '>': '&gt;',
  480. '"': '&quot;',
  481. "'": '&#39;'
  482. };
  483. /** Used to convert HTML entities to characters */
  484. var htmlUnescapes = invert(htmlEscapes);
  485. /*--------------------------------------------------------------------------*/
  486. /**
  487. * Assigns own enumerable properties of source object(s) to the destination
  488. * object. Subsequent sources will overwrite property assignments of previous
  489. * sources. If a `callback` function is passed, it will be executed to produce
  490. * the assigned values. The `callback` is bound to `thisArg` and invoked with
  491. * two arguments; (objectValue, sourceValue).
  492. *
  493. * @static
  494. * @memberOf _
  495. * @type Function
  496. * @alias extend
  497. * @category Objects
  498. * @param {Object} object The destination object.
  499. * @param {Object} [source1, source2, ...] The source objects.
  500. * @param {Function} [callback] The function to customize assigning values.
  501. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  502. * @returns {Object} Returns the destination object.
  503. * @example
  504. *
  505. * _.assign({ 'name': 'moe' }, { 'age': 40 });
  506. * // => { 'name': 'moe', 'age': 40 }
  507. *
  508. * var defaults = _.partialRight(_.assign, function(a, b) {
  509. * return typeof a == 'undefined' ? b : a;
  510. * });
  511. *
  512. * var food = { 'name': 'apple' };
  513. * defaults(food, { 'name': 'banana', 'type': 'fruit' });
  514. * // => { 'name': 'apple', 'type': 'fruit' }
  515. */
  516. function assign(object) {
  517. if (!object) {
  518. return object;
  519. }
  520. for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
  521. var iterable = arguments[argsIndex];
  522. if (iterable) {
  523. for (var key in iterable) {
  524. object[key] = iterable[key];
  525. }
  526. }
  527. }
  528. return object;
  529. }
  530. /**
  531. * Creates a clone of `value`. If `deep` is `true`, nested objects will also
  532. * be cloned, otherwise they will be assigned by reference. If a `callback`
  533. * function is passed, it will be executed to produce the cloned values. If
  534. * `callback` returns `undefined`, cloning will be handled by the method instead.
  535. * The `callback` is bound to `thisArg` and invoked with one argument; (value).
  536. *
  537. * @static
  538. * @memberOf _
  539. * @category Objects
  540. * @param {Mixed} value The value to clone.
  541. * @param {Boolean} [deep=false] A flag to indicate a deep clone.
  542. * @param {Function} [callback] The function to customize cloning values.
  543. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  544. * @param- {Array} [stackA=[]] Tracks traversed source objects.
  545. * @param- {Array} [stackB=[]] Associates clones with source counterparts.
  546. * @returns {Mixed} Returns the cloned `value`.
  547. * @example
  548. *
  549. * var stooges = [
  550. * { 'name': 'moe', 'age': 40 },
  551. * { 'name': 'larry', 'age': 50 }
  552. * ];
  553. *
  554. * var shallow = _.clone(stooges);
  555. * shallow[0] === stooges[0];
  556. * // => true
  557. *
  558. * var deep = _.clone(stooges, true);
  559. * deep[0] === stooges[0];
  560. * // => false
  561. *
  562. * _.mixin({
  563. * 'clone': _.partialRight(_.clone, function(value) {
  564. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  565. * })
  566. * });
  567. *
  568. * var clone = _.clone(document.body);
  569. * clone.childNodes.length;
  570. * // => 0
  571. */
  572. function clone(value) {
  573. return isObject(value)
  574. ? (isArray(value) ? nativeSlice.call(value) : assign({}, value))
  575. : value;
  576. }
  577. /**
  578. * Assigns own enumerable properties of source object(s) to the destination
  579. * object for all destination properties that resolve to `undefined`. Once a
  580. * property is set, additional defaults of the same property will be ignored.
  581. *
  582. * @static
  583. * @memberOf _
  584. * @type Function
  585. * @category Objects
  586. * @param {Object} object The destination object.
  587. * @param {Object} [source1, source2, ...] The source objects.
  588. * @param- {Object} [guard] Allows working with `_.reduce` without using its
  589. * callback's `key` and `object` arguments as sources.
  590. * @returns {Object} Returns the destination object.
  591. * @example
  592. *
  593. * var food = { 'name': 'apple' };
  594. * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
  595. * // => { 'name': 'apple', 'type': 'fruit' }
  596. */
  597. function defaults(object) {
  598. if (!object) {
  599. return object;
  600. }
  601. for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
  602. var iterable = arguments[argsIndex];
  603. if (iterable) {
  604. for (var key in iterable) {
  605. if (object[key] == null) {
  606. object[key] = iterable[key];
  607. }
  608. }
  609. }
  610. }
  611. return object;
  612. }
  613. /**
  614. * Iterates over `object`'s own and inherited enumerable properties, executing
  615. * the `callback` for each property. The `callback` is bound to `thisArg` and
  616. * invoked with three arguments; (value, key, object). Callbacks may exit iteration
  617. * early by explicitly returning `false`.
  618. *
  619. * @static
  620. * @memberOf _
  621. * @type Function
  622. * @category Objects
  623. * @param {Object} object The object to iterate over.
  624. * @param {Function} [callback=identity] The function called per iteration.
  625. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  626. * @returns {Object} Returns `object`.
  627. * @example
  628. *
  629. * function Dog(name) {
  630. * this.name = name;
  631. * }
  632. *
  633. * Dog.prototype.bark = function() {
  634. * alert('Woof, woof!');
  635. * };
  636. *
  637. * _.forIn(new Dog('Dagny'), function(value, key) {
  638. * alert(key);
  639. * });
  640. * // => alerts 'name' and 'bark' (order is not guaranteed)
  641. */
  642. var forIn = function (collection, callback) {
  643. var index, iterable = collection, result = iterable;
  644. if (!iterable) return result;
  645. if (!objectTypes[typeof iterable]) return result;
  646. for (index in iterable) {
  647. if (callback(iterable[index], index, collection) === indicatorObject) return result;
  648. }
  649. return result
  650. };
  651. /**
  652. * Iterates over an object's own enumerable properties, executing the `callback`
  653. * for each property. The `callback` is bound to `thisArg` and invoked with three
  654. * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
  655. * returning `false`.
  656. *
  657. * @static
  658. * @memberOf _
  659. * @type Function
  660. * @category Objects
  661. * @param {Object} object The object to iterate over.
  662. * @param {Function} [callback=identity] The function called per iteration.
  663. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  664. * @returns {Object} Returns `object`.
  665. * @example
  666. *
  667. * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  668. * alert(key);
  669. * });
  670. * // => alerts '0', '1', and 'length' (order is not guaranteed)
  671. */
  672. var forOwn = function (collection, callback) {
  673. var index, iterable = collection, result = iterable;
  674. if (!iterable) return result;
  675. if (!objectTypes[typeof iterable]) return result;
  676. for (index in iterable) {
  677. if (hasOwnProperty.call(iterable, index)) {
  678. if (callback(iterable[index], index, collection) === indicatorObject) return result;
  679. }
  680. }
  681. return result
  682. };
  683. /**
  684. * Creates a sorted array of all enumerable properties, own and inherited,
  685. * of `object` that have function values.
  686. *
  687. * @static
  688. * @memberOf _
  689. * @alias methods
  690. * @category Objects
  691. * @param {Object} object The object to inspect.
  692. * @returns {Array} Returns a new array of property names that have function values.
  693. * @example
  694. *
  695. * _.functions(_);
  696. * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
  697. */
  698. function functions(object) {
  699. var result = [];
  700. forIn(object, function(value, key) {
  701. if (isFunction(value)) {
  702. result.push(key);
  703. }
  704. });
  705. return result.sort();
  706. }
  707. /**
  708. * Checks if the specified object `property` exists and is a direct property,
  709. * instead of an inherited property.
  710. *
  711. * @static
  712. * @memberOf _
  713. * @category Objects
  714. * @param {Object} object The object to check.
  715. * @param {String} property The property to check for.
  716. * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
  717. * @example
  718. *
  719. * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
  720. * // => true
  721. */
  722. function has(object, property) {
  723. return object ? hasOwnProperty.call(object, property) : false;
  724. }
  725. /**
  726. * Creates an object composed of the inverted keys and values of the given `object`.
  727. *
  728. * @static
  729. * @memberOf _
  730. * @category Objects
  731. * @param {Object} object The object to invert.
  732. * @returns {Object} Returns the created inverted object.
  733. * @example
  734. *
  735. * _.invert({ 'first': 'moe', 'second': 'larry' });
  736. * // => { 'moe': 'first', 'larry': 'second' }
  737. */
  738. function invert(object) {
  739. var index = -1,
  740. props = keys(object),
  741. length = props.length,
  742. result = {};
  743. while (++index < length) {
  744. var key = props[index];
  745. result[object[key]] = key;
  746. }
  747. return result;
  748. }
  749. /**
  750. * Checks if `value` is an array.
  751. *
  752. * @static
  753. * @memberOf _
  754. * @category Objects
  755. * @param {Mixed} value The value to check.
  756. * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
  757. * @example
  758. *
  759. * (function() { return _.isArray(arguments); })();
  760. * // => false
  761. *
  762. * _.isArray([1, 2, 3]);
  763. * // => true
  764. */
  765. var isArray = nativeIsArray || function(value) {
  766. return toString.call(value) == arrayClass;
  767. };
  768. /**
  769. * Checks if `value` is a boolean value.
  770. *
  771. * @static
  772. * @memberOf _
  773. * @category Objects
  774. * @param {Mixed} value The value to check.
  775. * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
  776. * @example
  777. *
  778. * _.isBoolean(null);
  779. * // => false
  780. */
  781. function isBoolean(value) {
  782. return value === true || value === false || toString.call(value) == boolClass;
  783. }
  784. /**
  785. * Checks if `value` is a date.
  786. *
  787. * @static
  788. * @memberOf _
  789. * @category Objects
  790. * @param {Mixed} value The value to check.
  791. * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
  792. * @example
  793. *
  794. * _.isDate(new Date);
  795. * // => true
  796. */
  797. function isDate(value) {
  798. return toString.call(value) == dateClass;
  799. }
  800. /**
  801. * Checks if `value` is a DOM element.
  802. *
  803. * @static
  804. * @memberOf _
  805. * @category Objects
  806. * @param {Mixed} value The value to check.
  807. * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
  808. * @example
  809. *
  810. * _.isElement(document.body);
  811. * // => true
  812. */
  813. function isElement(value) {
  814. return value ? value.nodeType === 1 : false;
  815. }
  816. /**
  817. * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
  818. * length of `0` and objects with no own enumerable properties are considered
  819. * "empty".
  820. *
  821. * @static
  822. * @memberOf _
  823. * @category Objects
  824. * @param {Array|Object|String} value The value to inspect.
  825. * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
  826. * @example
  827. *
  828. * _.isEmpty([1, 2, 3]);
  829. * // => false
  830. *
  831. * _.isEmpty({});
  832. * // => true
  833. *
  834. * _.isEmpty('');
  835. * // => true
  836. */
  837. function isEmpty(value) {
  838. if (!value) {
  839. return true;
  840. }
  841. if (isArray(value) || isString(value)) {
  842. return !value.length;
  843. }
  844. for (var key in value) {
  845. if (hasOwnProperty.call(value, key)) {
  846. return false;
  847. }
  848. }
  849. return true;
  850. }
  851. /**
  852. * Performs a deep comparison between two values to determine if they are
  853. * equivalent to each other. If `callback` is passed, it will be executed to
  854. * compare values. If `callback` returns `undefined`, comparisons will be handled
  855. * by the method instead. The `callback` is bound to `thisArg` and invoked with
  856. * two arguments; (a, b).
  857. *
  858. * @static
  859. * @memberOf _
  860. * @category Objects
  861. * @param {Mixed} a The value to compare.
  862. * @param {Mixed} b The other value to compare.
  863. * @param {Function} [callback] The function to customize comparing values.
  864. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  865. * @param- {Array} [stackA=[]] Tracks traversed `a` objects.
  866. * @param- {Array} [stackB=[]] Tracks traversed `b` objects.
  867. * @returns {Boolean} Returns `true`, if the values are equivalent, else `false`.
  868. * @example
  869. *
  870. * var moe = { 'name': 'moe', 'age': 40 };
  871. * var copy = { 'name': 'moe', 'age': 40 };
  872. *
  873. * moe == copy;
  874. * // => false
  875. *
  876. * _.isEqual(moe, copy);
  877. * // => true
  878. *
  879. * var words = ['hello', 'goodbye'];
  880. * var otherWords = ['hi', 'goodbye'];
  881. *
  882. * _.isEqual(words, otherWords, function(a, b) {
  883. * var reGreet = /^(?:hello|hi)$/i,
  884. * aGreet = _.isString(a) && reGreet.test(a),
  885. * bGreet = _.isString(b) && reGreet.test(b);
  886. *
  887. * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  888. * });
  889. * // => true
  890. */
  891. function isEqual(a, b, stackA, stackB) {
  892. if (a === b) {
  893. return a !== 0 || (1 / a == 1 / b);
  894. }
  895. var type = typeof a,
  896. otherType = typeof b;
  897. if (a === a &&
  898. (!a || (type != 'function' && type != 'object')) &&
  899. (!b || (otherType != 'function' && otherType != 'object'))) {
  900. return false;
  901. }
  902. if (a == null || b == null) {
  903. return a === b;
  904. }
  905. var className = toString.call(a),
  906. otherClass = toString.call(b);
  907. if (className != otherClass) {
  908. return false;
  909. }
  910. switch (className) {
  911. case boolClass:
  912. case dateClass:
  913. return +a == +b;
  914. case numberClass:
  915. return a != +a
  916. ? b != +b
  917. : (a == 0 ? (1 / a == 1 / b) : a == +b);
  918. case regexpClass:
  919. case stringClass:
  920. return a == String(b);
  921. }
  922. var isArr = className == arrayClass;
  923. if (!isArr) {
  924. if (a instanceof lodash || b instanceof lodash) {
  925. return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, stackA, stackB);
  926. }
  927. if (className != objectClass) {
  928. return false;
  929. }
  930. var ctorA = a.constructor,
  931. ctorB = b.constructor;
  932. if (ctorA != ctorB && !(
  933. isFunction(ctorA) && ctorA instanceof ctorA &&
  934. isFunction(ctorB) && ctorB instanceof ctorB
  935. )) {
  936. return false;
  937. }
  938. }
  939. stackA || (stackA = []);
  940. stackB || (stackB = []);
  941. var length = stackA.length;
  942. while (length--) {
  943. if (stackA[length] == a) {
  944. return stackB[length] == b;
  945. }
  946. }
  947. var result = true,
  948. size = 0;
  949. stackA.push(a);
  950. stackB.push(b);
  951. if (isArr) {
  952. size = b.length;
  953. result = size == a.length;
  954. if (result) {
  955. while (size--) {
  956. if (!(result = isEqual(a[size], b[size], stackA, stackB))) {
  957. break;
  958. }
  959. }
  960. }
  961. return result;
  962. }
  963. forIn(b, function(value, key, b) {
  964. if (hasOwnProperty.call(b, key)) {
  965. size++;
  966. return !(result = hasOwnProperty.call(a, key) && isEqual(a[key], value, stackA, stackB)) && indicatorObject;
  967. }
  968. });
  969. if (result) {
  970. forIn(a, function(value, key, a) {
  971. if (hasOwnProperty.call(a, key)) {
  972. return !(result = --size > -1) && indicatorObject;
  973. }
  974. });
  975. }
  976. return result;
  977. }
  978. /**
  979. * Checks if `value` is, or can be coerced to, a finite number.
  980. *
  981. * Note: This is not the same as native `isFinite`, which will return true for
  982. * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
  983. *
  984. * @static
  985. * @memberOf _
  986. * @category Objects
  987. * @param {Mixed} value The value to check.
  988. * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
  989. * @example
  990. *
  991. * _.isFinite(-101);
  992. * // => true
  993. *
  994. * _.isFinite('10');
  995. * // => true
  996. *
  997. * _.isFinite(true);
  998. * // => false
  999. *
  1000. * _.isFinite('');
  1001. * // => false
  1002. *
  1003. * _.isFinite(Infinity);
  1004. * // => false
  1005. */
  1006. function isFinite(value) {
  1007. return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
  1008. }
  1009. /**
  1010. * Checks if `value` is a function.
  1011. *
  1012. * @static
  1013. * @memberOf _
  1014. * @category Objects
  1015. * @param {Mixed} value The value to check.
  1016. * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
  1017. * @example
  1018. *
  1019. * _.isFunction(_);
  1020. * // => true
  1021. */
  1022. function isFunction(value) {
  1023. return typeof value == 'function';
  1024. }
  1025. // fallback for older versions of Chrome and Safari
  1026. if (isFunction(/x/)) {
  1027. isFunction = function(value) {
  1028. return toString.call(value) == funcClass;
  1029. };
  1030. }
  1031. /**
  1032. * Checks if `value` is the language type of Object.
  1033. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  1034. *
  1035. * @static
  1036. * @memberOf _
  1037. * @category Objects
  1038. * @param {Mixed} value The value to check.
  1039. * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
  1040. * @example
  1041. *
  1042. * _.isObject({});
  1043. * // => true
  1044. *
  1045. * _.isObject([1, 2, 3]);
  1046. * // => true
  1047. *
  1048. * _.isObject(1);
  1049. * // => false
  1050. */
  1051. function isObject(value) {
  1052. // check if the value is the ECMAScript language type of Object
  1053. // http://es5.github.com/#x8
  1054. // and avoid a V8 bug
  1055. // http://code.google.com/p/v8/issues/detail?id=2291
  1056. return value ? objectTypes[typeof value] : false;
  1057. }
  1058. /**
  1059. * Checks if `value` is `NaN`.
  1060. *
  1061. * Note: This is not the same as native `isNaN`, which will return `true` for
  1062. * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
  1063. *
  1064. * @static
  1065. * @memberOf _
  1066. * @category Objects
  1067. * @param {Mixed} value The value to check.
  1068. * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
  1069. * @example
  1070. *
  1071. * _.isNaN(NaN);
  1072. * // => true
  1073. *
  1074. * _.isNaN(new Number(NaN));
  1075. * // => true
  1076. *
  1077. * isNaN(undefined);
  1078. * // => true
  1079. *
  1080. * _.isNaN(undefined);
  1081. * // => false
  1082. */
  1083. function isNaN(value) {
  1084. // `NaN` as a primitive is the only value that is not equal to itself
  1085. // (perform the [[Class]] check first to avoid errors with some host objects in IE)
  1086. return isNumber(value) && value != +value
  1087. }
  1088. /**
  1089. * Checks if `value` is `null`.
  1090. *
  1091. * @static
  1092. * @memberOf _
  1093. * @category Objects
  1094. * @param {Mixed} value The value to check.
  1095. * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
  1096. * @example
  1097. *
  1098. * _.isNull(null);
  1099. * // => true
  1100. *
  1101. * _.isNull(undefined);
  1102. * // => false
  1103. */
  1104. function isNull(value) {
  1105. return value === null;
  1106. }
  1107. /**
  1108. * Checks if `value` is a number.
  1109. *
  1110. * @static
  1111. * @memberOf _
  1112. * @category Objects
  1113. * @param {Mixed} value The value to check.
  1114. * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
  1115. * @example
  1116. *
  1117. * _.isNumber(8.4 * 5);
  1118. * // => true
  1119. */
  1120. function isNumber(value) {
  1121. return typeof value == 'number' || toString.call(value) == numberClass;
  1122. }
  1123. /**
  1124. * Checks if `value` is a regular expression.
  1125. *
  1126. * @static
  1127. * @memberOf _
  1128. * @category Objects
  1129. * @param {Mixed} value The value to check.
  1130. * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
  1131. * @example
  1132. *
  1133. * _.isRegExp(/moe/);
  1134. * // => true
  1135. */
  1136. function isRegExp(value) {
  1137. return toString.call(value) == regexpClass;
  1138. }
  1139. /**
  1140. * Checks if `value` is a string.
  1141. *
  1142. * @static
  1143. * @memberOf _
  1144. * @category Objects
  1145. * @param {Mixed} value The value to check.
  1146. * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
  1147. * @example
  1148. *
  1149. * _.isString('moe');
  1150. * // => true
  1151. */
  1152. function isString(value) {
  1153. return typeof value == 'string' || toString.call(value) == stringClass;
  1154. }
  1155. /**
  1156. * Checks if `value` is `undefined`.
  1157. *
  1158. * @static
  1159. * @memberOf _
  1160. * @category Objects
  1161. * @param {Mixed} value The value to check.
  1162. * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
  1163. * @example
  1164. *
  1165. * _.isUndefined(void 0);
  1166. * // => true
  1167. */
  1168. function isUndefined(value) {
  1169. return typeof value == 'undefined';
  1170. }
  1171. /**
  1172. * Creates a shallow clone of `object` excluding the specified properties.
  1173. * Property names may be specified as individual arguments or as arrays of
  1174. * property names. If a `callback` function is passed, it will be executed
  1175. * for each property in the `object`, omitting the properties `callback`
  1176. * returns truthy for. The `callback` is bound to `thisArg` and invoked
  1177. * with three arguments; (value, key, object).
  1178. *
  1179. * @static
  1180. * @memberOf _
  1181. * @category Objects
  1182. * @param {Object} object The source object.
  1183. * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
  1184. * or the function called per iteration.
  1185. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1186. * @returns {Object} Returns an object without the omitted properties.
  1187. * @example
  1188. *
  1189. * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
  1190. * // => { 'name': 'moe' }
  1191. *
  1192. * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
  1193. * return typeof value == 'number';
  1194. * });
  1195. * // => { 'name': 'moe' }
  1196. */
  1197. function omit(object) {
  1198. var props = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
  1199. result = {};
  1200. forIn(object, function(value, key) {
  1201. if (indexOf(props, key) < 0) {
  1202. result[key] = value;
  1203. }
  1204. });
  1205. return result;
  1206. }
  1207. /**
  1208. * Creates a two dimensional array of the given object's key-value pairs,
  1209. * i.e. `[[key1, value1], [key2, value2]]`.
  1210. *
  1211. * @static
  1212. * @memberOf _
  1213. * @category Objects
  1214. * @param {Object} object The object to inspect.
  1215. * @returns {Array} Returns new array of key-value pairs.
  1216. * @example
  1217. *
  1218. * _.pairs({ 'moe': 30, 'larry': 40 });
  1219. * // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
  1220. */
  1221. function pairs(object) {
  1222. var index = -1,
  1223. props = keys(object),
  1224. length = props.length,
  1225. result = Array(length);
  1226. while (++index < length) {
  1227. var key = props[index];
  1228. result[index] = [key, object[key]];
  1229. }
  1230. return result;
  1231. }
  1232. /**
  1233. * Creates a shallow clone of `object` composed of the specified properties.
  1234. * Property names may be specified as individual arguments or as arrays of property
  1235. * names. If `callback` is passed, it will be executed for each property in the
  1236. * `object`, picking the properties `callback` returns truthy for. The `callback`
  1237. * is bound to `thisArg` and invoked with three arguments; (value, key, object).
  1238. *
  1239. * @static
  1240. * @memberOf _
  1241. * @category Objects
  1242. * @param {Object} object The source object.
  1243. * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
  1244. * per iteration or properties to pick, either as individual arguments or arrays.
  1245. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1246. * @returns {Object} Returns an object composed of the picked properties.
  1247. * @example
  1248. *
  1249. * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
  1250. * // => { 'name': 'moe' }
  1251. *
  1252. * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
  1253. * return key.charAt(0) != '_';
  1254. * });
  1255. * // => { 'name': 'moe' }
  1256. */
  1257. function pick(object) {
  1258. var index = -1,
  1259. props = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
  1260. length = props.length,
  1261. result = {};
  1262. while (++index < length) {
  1263. var prop = props[index];
  1264. if (prop in object) {
  1265. result[prop] = object[prop];
  1266. }
  1267. }
  1268. return result;
  1269. }
  1270. /**
  1271. * Creates an array composed of the own enumerable property values of `object`.
  1272. *
  1273. * @static
  1274. * @memberOf _
  1275. * @category Objects
  1276. * @param {Object} object The object to inspect.
  1277. * @returns {Array} Returns a new array of property values.
  1278. * @example
  1279. *
  1280. * _.values({ 'one': 1, 'two': 2, 'three': 3 });
  1281. * // => [1, 2, 3] (order is not guaranteed)
  1282. */
  1283. function values(object) {
  1284. var index = -1,
  1285. props = keys(object),
  1286. length = props.length,
  1287. result = Array(length);
  1288. while (++index < length) {
  1289. result[index] = object[props[index]];
  1290. }
  1291. return result;
  1292. }
  1293. /*--------------------------------------------------------------------------*/
  1294. /**
  1295. * Checks if a given `target` element is present in a `collection` using strict
  1296. * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
  1297. * as the offset from the end of the collection.
  1298. *
  1299. * @static
  1300. * @memberOf _
  1301. * @alias include
  1302. * @category Collections
  1303. * @param {Array|Object|String} collection The collection to iterate over.
  1304. * @param {Mixed} target The value to check for.
  1305. * @param {Number} [fromIndex=0] The index to search from.
  1306. * @returns {Boolean} Returns `true` if the `target` element is found, else `false`.
  1307. * @example
  1308. *
  1309. * _.contains([1, 2, 3], 1);
  1310. * // => true
  1311. *
  1312. * _.contains([1, 2, 3], 1, 2);
  1313. * // => false
  1314. *
  1315. * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
  1316. * // => true
  1317. *
  1318. * _.contains('curly', 'ur');
  1319. * // => true
  1320. */
  1321. function contains(collection, target) {
  1322. var length = collection ? collection.length : 0,
  1323. result = false;
  1324. if (typeof length == 'number') {
  1325. result = indexOf(collection, target) > -1;
  1326. } else {
  1327. forOwn(collection, function(value) {
  1328. return (result = value === target) && indicatorObject;
  1329. });
  1330. }
  1331. return result;
  1332. }
  1333. /**
  1334. * Creates an object composed of keys returned from running each element of the
  1335. * `collection` through the given `callback`. The corresponding value of each key
  1336. * is the number of times the key was returned by the `callback`. The `callback`
  1337. * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
  1338. *
  1339. * If a property name is passed for `callback`, the created "_.pluck" style
  1340. * callback will return the property value of the given element.
  1341. *
  1342. * If an object is passed for `callback`, the created "_.where" style callback
  1343. * will return `true` for elements that have the properties of the given object,
  1344. * else `false`.
  1345. *
  1346. * @static
  1347. * @memberOf _
  1348. * @category Collections
  1349. * @param {Array|Object|String} collection The collection to iterate over.
  1350. * @param {Function|Object|String} [callback=identity] The function called per
  1351. * iteration. If a property name or object is passed, it will be used to create
  1352. * a "_.pluck" or "_.where" style callback, respectively.
  1353. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1354. * @returns {Object} Returns the composed aggregate object.
  1355. * @example
  1356. *
  1357. * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
  1358. * // => { '4': 1, '6': 2 }
  1359. *
  1360. * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  1361. * // => { '4': 1, '6': 2 }
  1362. *
  1363. * _.countBy(['one', 'two', 'three'], 'length');
  1364. * // => { '3': 2, '5': 1 }
  1365. */
  1366. function countBy(collection, callback, thisArg) {
  1367. var result = {};
  1368. callback = createCallback(callback, thisArg);
  1369. forEach(collection, function(value, key, collection) {
  1370. key = String(callback(value, key, collection));
  1371. (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
  1372. });
  1373. return result;
  1374. }
  1375. /**
  1376. * Checks if the `callback` returns a truthy value for **all** elements of a
  1377. * `collection`. The `callback` is bound to `thisArg` and invoked with three
  1378. * arguments; (value, index|key, collection).
  1379. *
  1380. * If a property name is passed for `callback`, the created "_.pluck" style
  1381. * callback will return the property value of the given element.
  1382. *
  1383. * If an object is passed for `callback`, the created "_.where" style callback
  1384. * will return `true` for elements that have the properties of the given object,
  1385. * else `false`.
  1386. *
  1387. * @static
  1388. * @memberOf _
  1389. * @alias all
  1390. * @category Collections
  1391. * @param {Array|Object|String} collection The collection to iterate over.
  1392. * @param {Function|Object|String} [callback=identity] The function called per
  1393. * iteration. If a property name or object is passed, it will be used to create
  1394. * a "_.pluck" or "_.where" style callback, respectively.
  1395. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1396. * @returns {Boolean} Returns `true` if all elements pass the callback check,
  1397. * else `false`.
  1398. * @example
  1399. *
  1400. * _.every([true, 1, null, 'yes'], Boolean);
  1401. * // => false
  1402. *
  1403. * var stooges = [
  1404. * { 'name': 'moe', 'age': 40 },
  1405. * { 'name': 'larry', 'age': 50 }
  1406. * ];
  1407. *
  1408. * // using "_.pluck" callback shorthand
  1409. * _.every(stooges, 'age');
  1410. * // => true
  1411. *
  1412. * // using "_.where" callback shorthand
  1413. * _.every(stooges, { 'age': 50 });
  1414. * // => false
  1415. */
  1416. function every(collection, callback, thisArg) {
  1417. var result = true;
  1418. callback = createCallback(callback, thisArg);
  1419. var index = -1,
  1420. length = collection ? collection.length : 0;
  1421. if (typeof length == 'number') {
  1422. while (++index < length) {
  1423. if (!(result = !!callback(collection[index], index, collection))) {
  1424. break;
  1425. }
  1426. }
  1427. } else {
  1428. forOwn(collection, function(value, index, collection) {
  1429. return !(result = !!callback(value, index, collection)) && indicatorObject;
  1430. });
  1431. }
  1432. return result;
  1433. }
  1434. /**
  1435. * Examines each element in a `collection`, returning an array of all elements
  1436. * the `callback` returns truthy for. The `callback` is bound to `thisArg` and
  1437. * invoked with three arguments; (value, index|key, collection).
  1438. *
  1439. * If a property name is passed for `callback`, the created "_.pluck" style
  1440. * callback will return the property value of the given element.
  1441. *
  1442. * If an object is passed for `callback`, the created "_.where" style callback
  1443. * will return `true` for elements that have the properties of the given object,
  1444. * else `false`.
  1445. *
  1446. * @static
  1447. * @memberOf _
  1448. * @alias select
  1449. * @category Collections
  1450. * @param {Array|Object|String} collection The collection to iterate over.
  1451. * @param {Function|Object|String} [callback=identity] The function called per
  1452. * iteration. If a property name or object is passed, it will be used to create
  1453. * a "_.pluck" or "_.where" style callback, respectively.
  1454. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1455. * @returns {Array} Returns a new array of elements that passed the callback check.
  1456. * @example
  1457. *
  1458. * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  1459. * // => [2, 4, 6]
  1460. *
  1461. * var food = [
  1462. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  1463. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  1464. * ];
  1465. *
  1466. * // using "_.pluck" callback shorthand
  1467. * _.filter(food, 'organic');
  1468. * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
  1469. *
  1470. * // using "_.where" callback shorthand
  1471. * _.filter(food, { 'type': 'fruit' });
  1472. * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
  1473. */
  1474. function filter(collection, callback, thisArg) {
  1475. var result = [];
  1476. callback = createCallback(callback, thisArg);
  1477. var index = -1,
  1478. length = collection ? collection.length : 0;
  1479. if (typeof length == 'number') {
  1480. while (++index < length) {
  1481. var value = collection[index];
  1482. if (callback(value, index, collection)) {
  1483. result.push(value);
  1484. }
  1485. }
  1486. } else {
  1487. forOwn(collection, function(value, index, collection) {
  1488. if (callback(value, index, collection)) {
  1489. result.push(value);
  1490. }
  1491. });
  1492. }
  1493. return result;
  1494. }
  1495. /**
  1496. * Examines each element in a `collection`, returning the first that the `callback`
  1497. * returns truthy for. The `callback` is bound to `thisArg` and invoked with three
  1498. * arguments; (value, index|key, collection).
  1499. *
  1500. * If a property name is passed for `callback`, the created "_.pluck" style
  1501. * callback will return the property value of the given element.
  1502. *
  1503. * If an object is passed for `callback`, the created "_.where" style callback
  1504. * will return `true` for elements that have the properties of the given object,
  1505. * else `false`.
  1506. *
  1507. * @static
  1508. * @memberOf _
  1509. * @alias detect
  1510. * @category Collections
  1511. * @param {Array|Object|String} collection The collection to iterate over.
  1512. * @param {Function|Object|String} [callback=identity] The function called per
  1513. * iteration. If a property name or object is passed, it will be used to create
  1514. * a "_.pluck" or "_.where" style callback, respectively.
  1515. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1516. * @returns {Mixed} Returns the found element, else `undefined`.
  1517. * @example
  1518. *
  1519. * _.find([1, 2, 3, 4], function(num) {
  1520. * return num % 2 == 0;
  1521. * });
  1522. * // => 2
  1523. *
  1524. * var food = [
  1525. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  1526. * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
  1527. * { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
  1528. * ];
  1529. *
  1530. * // using "_.where" callback shorthand
  1531. * _.find(food, { 'type': 'vegetable' });
  1532. * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
  1533. *
  1534. * // using "_.pluck" ca