|
1 /** |
|
2 * @license |
|
3 * Lo-Dash 2.4.1 (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.5.2 <http://underscorejs.org/LICENSE> |
|
7 * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors |
|
8 * Available under MIT license <http://lodash.com/license> |
|
9 */ |
|
10 ;(function() { |
|
11 |
|
12 /** Used as a safe reference for `undefined` in pre ES5 environments */ |
|
13 var undefined; |
|
14 |
|
15 /** Used to pool arrays and objects used internally */ |
|
16 var arrayPool = [], |
|
17 objectPool = []; |
|
18 |
|
19 /** Used to generate unique IDs */ |
|
20 var idCounter = 0; |
|
21 |
|
22 /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ |
|
23 var keyPrefix = +new Date + ''; |
|
24 |
|
25 /** Used as the size when optimizations are enabled for large arrays */ |
|
26 var largeArraySize = 75; |
|
27 |
|
28 /** Used as the max size of the `arrayPool` and `objectPool` */ |
|
29 var maxPoolSize = 40; |
|
30 |
|
31 /** Used to detect and test whitespace */ |
|
32 var whitespace = ( |
|
33 // whitespace |
|
34 ' \t\x0B\f\xA0\ufeff' + |
|
35 |
|
36 // line terminators |
|
37 '\n\r\u2028\u2029' + |
|
38 |
|
39 // unicode category "Zs" space separators |
|
40 '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' |
|
41 ); |
|
42 |
|
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; |
|
47 |
|
48 /** |
|
49 * Used to match ES6 template delimiters |
|
50 * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals |
|
51 */ |
|
52 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; |
|
53 |
|
54 /** Used to match regexp flags from their coerced string values */ |
|
55 var reFlags = /\w*$/; |
|
56 |
|
57 /** Used to detected named functions */ |
|
58 var reFuncName = /^\s*function[ \n\r\t]+\w/; |
|
59 |
|
60 /** Used to match "interpolate" template delimiters */ |
|
61 var reInterpolate = /<%=([\s\S]+?)%>/g; |
|
62 |
|
63 /** Used to match leading whitespace and zeros to be removed */ |
|
64 var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); |
|
65 |
|
66 /** Used to ensure capturing order of template delimiters */ |
|
67 var reNoMatch = /($^)/; |
|
68 |
|
69 /** Used to detect functions containing a `this` reference */ |
|
70 var reThis = /\bthis\b/; |
|
71 |
|
72 /** Used to match unescaped characters in compiled string literals */ |
|
73 var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; |
|
74 |
|
75 /** Used to assign default `context` object properties */ |
|
76 var contextProps = [ |
|
77 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object', |
|
78 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', |
|
79 'parseInt', 'setTimeout' |
|
80 ]; |
|
81 |
|
82 /** Used to make template sourceURLs easier to identify */ |
|
83 var templateCounter = 0; |
|
84 |
|
85 /** `Object#toString` result shortcuts */ |
|
86 var argsClass = '[object Arguments]', |
|
87 arrayClass = '[object Array]', |
|
88 boolClass = '[object Boolean]', |
|
89 dateClass = '[object Date]', |
|
90 funcClass = '[object Function]', |
|
91 numberClass = '[object Number]', |
|
92 objectClass = '[object Object]', |
|
93 regexpClass = '[object RegExp]', |
|
94 stringClass = '[object String]'; |
|
95 |
|
96 /** Used to identify object classifications that `_.clone` supports */ |
|
97 var cloneableClasses = {}; |
|
98 cloneableClasses[funcClass] = false; |
|
99 cloneableClasses[argsClass] = cloneableClasses[arrayClass] = |
|
100 cloneableClasses[boolClass] = cloneableClasses[dateClass] = |
|
101 cloneableClasses[numberClass] = cloneableClasses[objectClass] = |
|
102 cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; |
|
103 |
|
104 /** Used as an internal `_.debounce` options object */ |
|
105 var debounceOptions = { |
|
106 'leading': false, |
|
107 'maxWait': 0, |
|
108 'trailing': false |
|
109 }; |
|
110 |
|
111 /** Used as the property descriptor for `__bindData__` */ |
|
112 var descriptor = { |
|
113 'configurable': false, |
|
114 'enumerable': false, |
|
115 'value': null, |
|
116 'writable': false |
|
117 }; |
|
118 |
|
119 /** Used to determine if values are of the language type Object */ |
|
120 var objectTypes = { |
|
121 'boolean': false, |
|
122 'function': true, |
|
123 'object': true, |
|
124 'number': false, |
|
125 'string': false, |
|
126 'undefined': false |
|
127 }; |
|
128 |
|
129 /** Used to escape characters for inclusion in compiled string literals */ |
|
130 var stringEscapes = { |
|
131 '\\': '\\', |
|
132 "'": "'", |
|
133 '\n': 'n', |
|
134 '\r': 'r', |
|
135 '\t': 't', |
|
136 '\u2028': 'u2028', |
|
137 '\u2029': 'u2029' |
|
138 }; |
|
139 |
|
140 /** Used as a reference to the global object */ |
|
141 var root = (objectTypes[typeof window] && window) || this; |
|
142 |
|
143 /** Detect free variable `exports` */ |
|
144 var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; |
|
145 |
|
146 /** Detect free variable `module` */ |
|
147 var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; |
|
148 |
|
149 /** Detect the popular CommonJS extension `module.exports` */ |
|
150 var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; |
|
151 |
|
152 /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ |
|
153 var freeGlobal = objectTypes[typeof global] && global; |
|
154 if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { |
|
155 root = freeGlobal; |
|
156 } |
|
157 |
|
158 /*--------------------------------------------------------------------------*/ |
|
159 |
|
160 /** |
|
161 * The base implementation of `_.indexOf` without support for binary searches |
|
162 * or `fromIndex` constraints. |
|
163 * |
|
164 * @private |
|
165 * @param {Array} array The array to search. |
|
166 * @param {*} value The value to search for. |
|
167 * @param {number} [fromIndex=0] The index to search from. |
|
168 * @returns {number} Returns the index of the matched value or `-1`. |
|
169 */ |
|
170 function baseIndexOf(array, value, fromIndex) { |
|
171 var index = (fromIndex || 0) - 1, |
|
172 length = array ? array.length : 0; |
|
173 |
|
174 while (++index < length) { |
|
175 if (array[index] === value) { |
|
176 return index; |
|
177 } |
|
178 } |
|
179 return -1; |
|
180 } |
|
181 |
|
182 /** |
|
183 * An implementation of `_.contains` for cache objects that mimics the return |
|
184 * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. |
|
185 * |
|
186 * @private |
|
187 * @param {Object} cache The cache object to inspect. |
|
188 * @param {*} value The value to search for. |
|
189 * @returns {number} Returns `0` if `value` is found, else `-1`. |
|
190 */ |
|
191 function cacheIndexOf(cache, value) { |
|
192 var type = typeof value; |
|
193 cache = cache.cache; |
|
194 |
|
195 if (type == 'boolean' || value == null) { |
|
196 return cache[value] ? 0 : -1; |
|
197 } |
|
198 if (type != 'number' && type != 'string') { |
|
199 type = 'object'; |
|
200 } |
|
201 var key = type == 'number' ? value : keyPrefix + value; |
|
202 cache = (cache = cache[type]) && cache[key]; |
|
203 |
|
204 return type == 'object' |
|
205 ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) |
|
206 : (cache ? 0 : -1); |
|
207 } |
|
208 |
|
209 /** |
|
210 * Adds a given value to the corresponding cache object. |
|
211 * |
|
212 * @private |
|
213 * @param {*} value The value to add to the cache. |
|
214 */ |
|
215 function cachePush(value) { |
|
216 var cache = this.cache, |
|
217 type = typeof value; |
|
218 |
|
219 if (type == 'boolean' || value == null) { |
|
220 cache[value] = true; |
|
221 } else { |
|
222 if (type != 'number' && type != 'string') { |
|
223 type = 'object'; |
|
224 } |
|
225 var key = type == 'number' ? value : keyPrefix + value, |
|
226 typeCache = cache[type] || (cache[type] = {}); |
|
227 |
|
228 if (type == 'object') { |
|
229 (typeCache[key] || (typeCache[key] = [])).push(value); |
|
230 } else { |
|
231 typeCache[key] = true; |
|
232 } |
|
233 } |
|
234 } |
|
235 |
|
236 /** |
|
237 * Used by `_.max` and `_.min` as the default callback when a given |
|
238 * collection is a string value. |
|
239 * |
|
240 * @private |
|
241 * @param {string} value The character to inspect. |
|
242 * @returns {number} Returns the code unit of given character. |
|
243 */ |
|
244 function charAtCallback(value) { |
|
245 return value.charCodeAt(0); |
|
246 } |
|
247 |
|
248 /** |
|
249 * Used by `sortBy` to compare transformed `collection` elements, stable sorting |
|
250 * them in ascending order. |
|
251 * |
|
252 * @private |
|
253 * @param {Object} a The object to compare to `b`. |
|
254 * @param {Object} b The object to compare to `a`. |
|
255 * @returns {number} Returns the sort order indicator of `1` or `-1`. |
|
256 */ |
|
257 function compareAscending(a, b) { |
|
258 var ac = a.criteria, |
|
259 bc = b.criteria, |
|
260 index = -1, |
|
261 length = ac.length; |
|
262 |
|
263 while (++index < length) { |
|
264 var value = ac[index], |
|
265 other = bc[index]; |
|
266 |
|
267 if (value !== other) { |
|
268 if (value > other || typeof value == 'undefined') { |
|
269 return 1; |
|
270 } |
|
271 if (value < other || typeof other == 'undefined') { |
|
272 return -1; |
|
273 } |
|
274 } |
|
275 } |
|
276 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications |
|
277 // that causes it, under certain circumstances, to return the same value for |
|
278 // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 |
|
279 // |
|
280 // This also ensures a stable sort in V8 and other engines. |
|
281 // See http://code.google.com/p/v8/issues/detail?id=90 |
|
282 return a.index - b.index; |
|
283 } |
|
284 |
|
285 /** |
|
286 * Creates a cache object to optimize linear searches of large arrays. |
|
287 * |
|
288 * @private |
|
289 * @param {Array} [array=[]] The array to search. |
|
290 * @returns {null|Object} Returns the cache object or `null` if caching should not be used. |
|
291 */ |
|
292 function createCache(array) { |
|
293 var index = -1, |
|
294 length = array.length, |
|
295 first = array[0], |
|
296 mid = array[(length / 2) | 0], |
|
297 last = array[length - 1]; |
|
298 |
|
299 if (first && typeof first == 'object' && |
|
300 mid && typeof mid == 'object' && last && typeof last == 'object') { |
|
301 return false; |
|
302 } |
|
303 var cache = getObject(); |
|
304 cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; |
|
305 |
|
306 var result = getObject(); |
|
307 result.array = array; |
|
308 result.cache = cache; |
|
309 result.push = cachePush; |
|
310 |
|
311 while (++index < length) { |
|
312 result.push(array[index]); |
|
313 } |
|
314 return result; |
|
315 } |
|
316 |
|
317 /** |
|
318 * Used by `template` to escape characters for inclusion in compiled |
|
319 * string literals. |
|
320 * |
|
321 * @private |
|
322 * @param {string} match The matched character to escape. |
|
323 * @returns {string} Returns the escaped character. |
|
324 */ |
|
325 function escapeStringChar(match) { |
|
326 return '\\' + stringEscapes[match]; |
|
327 } |
|
328 |
|
329 /** |
|
330 * Gets an array from the array pool or creates a new one if the pool is empty. |
|
331 * |
|
332 * @private |
|
333 * @returns {Array} The array from the pool. |
|
334 */ |
|
335 function getArray() { |
|
336 return arrayPool.pop() || []; |
|
337 } |
|
338 |
|
339 /** |
|
340 * Gets an object from the object pool or creates a new one if the pool is empty. |
|
341 * |
|
342 * @private |
|
343 * @returns {Object} The object from the pool. |
|
344 */ |
|
345 function getObject() { |
|
346 return objectPool.pop() || { |
|
347 'array': null, |
|
348 'cache': null, |
|
349 'criteria': null, |
|
350 'false': false, |
|
351 'index': 0, |
|
352 'null': false, |
|
353 'number': null, |
|
354 'object': null, |
|
355 'push': null, |
|
356 'string': null, |
|
357 'true': false, |
|
358 'undefined': false, |
|
359 'value': null |
|
360 }; |
|
361 } |
|
362 |
|
363 /** |
|
364 * Releases the given array back to the array pool. |
|
365 * |
|
366 * @private |
|
367 * @param {Array} [array] The array to release. |
|
368 */ |
|
369 function releaseArray(array) { |
|
370 array.length = 0; |
|
371 if (arrayPool.length < maxPoolSize) { |
|
372 arrayPool.push(array); |
|
373 } |
|
374 } |
|
375 |
|
376 /** |
|
377 * Releases the given object back to the object pool. |
|
378 * |
|
379 * @private |
|
380 * @param {Object} [object] The object to release. |
|
381 */ |
|
382 function releaseObject(object) { |
|
383 var cache = object.cache; |
|
384 if (cache) { |
|
385 releaseObject(cache); |
|
386 } |
|
387 object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; |
|
388 if (objectPool.length < maxPoolSize) { |
|
389 objectPool.push(object); |
|
390 } |
|
391 } |
|
392 |
|
393 /** |
|
394 * Slices the `collection` from the `start` index up to, but not including, |
|
395 * the `end` index. |
|
396 * |
|
397 * Note: This function is used instead of `Array#slice` to support node lists |
|
398 * in IE < 9 and to ensure dense arrays are returned. |
|
399 * |
|
400 * @private |
|
401 * @param {Array|Object|string} collection The collection to slice. |
|
402 * @param {number} start The start index. |
|
403 * @param {number} end The end index. |
|
404 * @returns {Array} Returns the new array. |
|
405 */ |
|
406 function slice(array, start, end) { |
|
407 start || (start = 0); |
|
408 if (typeof end == 'undefined') { |
|
409 end = array ? array.length : 0; |
|
410 } |
|
411 var index = -1, |
|
412 length = end - start || 0, |
|
413 result = Array(length < 0 ? 0 : length); |
|
414 |
|
415 while (++index < length) { |
|
416 result[index] = array[start + index]; |
|
417 } |
|
418 return result; |
|
419 } |
|
420 |
|
421 /*--------------------------------------------------------------------------*/ |
|
422 |
|
423 /** |
|
424 * Create a new `lodash` function using the given context object. |
|
425 * |
|
426 * @static |
|
427 * @memberOf _ |
|
428 * @category Utilities |
|
429 * @param {Object} [context=root] The context object. |
|
430 * @returns {Function} Returns the `lodash` function. |
|
431 */ |
|
432 function runInContext(context) { |
|
433 // Avoid issues with some ES3 environments that attempt to use values, named |
|
434 // after built-in constructors like `Object`, for the creation of literals. |
|
435 // ES5 clears this up by stating that literals must use built-in constructors. |
|
436 // See http://es5.github.io/#x11.1.5. |
|
437 context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; |
|
438 |
|
439 /** Native constructor references */ |
|
440 var Array = context.Array, |
|
441 Boolean = context.Boolean, |
|
442 Date = context.Date, |
|
443 Function = context.Function, |
|
444 Math = context.Math, |
|
445 Number = context.Number, |
|
446 Object = context.Object, |
|
447 RegExp = context.RegExp, |
|
448 String = context.String, |
|
449 TypeError = context.TypeError; |
|
450 |
|
451 /** |
|
452 * Used for `Array` method references. |
|
453 * |
|
454 * Normally `Array.prototype` would suffice, however, using an array literal |
|
455 * avoids issues in Narwhal. |
|
456 */ |
|
457 var arrayRef = []; |
|
458 |
|
459 /** Used for native method references */ |
|
460 var objectProto = Object.prototype; |
|
461 |
|
462 /** Used to restore the original `_` reference in `noConflict` */ |
|
463 var oldDash = context._; |
|
464 |
|
465 /** Used to resolve the internal [[Class]] of values */ |
|
466 var toString = objectProto.toString; |
|
467 |
|
468 /** Used to detect if a method is native */ |
|
469 var reNative = RegExp('^' + |
|
470 String(toString) |
|
471 .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') |
|
472 .replace(/toString| for [^\]]+/g, '.*?') + '$' |
|
473 ); |
|
474 |
|
475 /** Native method shortcuts */ |
|
476 var ceil = Math.ceil, |
|
477 clearTimeout = context.clearTimeout, |
|
478 floor = Math.floor, |
|
479 fnToString = Function.prototype.toString, |
|
480 getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, |
|
481 hasOwnProperty = objectProto.hasOwnProperty, |
|
482 push = arrayRef.push, |
|
483 setTimeout = context.setTimeout, |
|
484 splice = arrayRef.splice, |
|
485 unshift = arrayRef.unshift; |
|
486 |
|
487 /** Used to set meta data on functions */ |
|
488 var defineProperty = (function() { |
|
489 // IE 8 only accepts DOM elements |
|
490 try { |
|
491 var o = {}, |
|
492 func = isNative(func = Object.defineProperty) && func, |
|
493 result = func(o, o, o) && func; |
|
494 } catch(e) { } |
|
495 return result; |
|
496 }()); |
|
497 |
|
498 /* Native method shortcuts for methods with the same name as other `lodash` methods */ |
|
499 var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, |
|
500 nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, |
|
501 nativeIsFinite = context.isFinite, |
|
502 nativeIsNaN = context.isNaN, |
|
503 nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, |
|
504 nativeMax = Math.max, |
|
505 nativeMin = Math.min, |
|
506 nativeParseInt = context.parseInt, |
|
507 nativeRandom = Math.random; |
|
508 |
|
509 /** Used to lookup a built-in constructor by [[Class]] */ |
|
510 var ctorByClass = {}; |
|
511 ctorByClass[arrayClass] = Array; |
|
512 ctorByClass[boolClass] = Boolean; |
|
513 ctorByClass[dateClass] = Date; |
|
514 ctorByClass[funcClass] = Function; |
|
515 ctorByClass[objectClass] = Object; |
|
516 ctorByClass[numberClass] = Number; |
|
517 ctorByClass[regexpClass] = RegExp; |
|
518 ctorByClass[stringClass] = String; |
|
519 |
|
520 /*--------------------------------------------------------------------------*/ |
|
521 |
|
522 /** |
|
523 * Creates a `lodash` object which wraps the given value to enable intuitive |
|
524 * method chaining. |
|
525 * |
|
526 * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: |
|
527 * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, |
|
528 * and `unshift` |
|
529 * |
|
530 * Chaining is supported in custom builds as long as the `value` method is |
|
531 * implicitly or explicitly included in the build. |
|
532 * |
|
533 * The chainable wrapper functions are: |
|
534 * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, |
|
535 * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, |
|
536 * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, |
|
537 * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, |
|
538 * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, |
|
539 * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, |
|
540 * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, |
|
541 * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, |
|
542 * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, |
|
543 * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, |
|
544 * and `zip` |
|
545 * |
|
546 * The non-chainable wrapper functions are: |
|
547 * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, |
|
548 * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, |
|
549 * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, |
|
550 * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, |
|
551 * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, |
|
552 * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, |
|
553 * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, |
|
554 * `template`, `unescape`, `uniqueId`, and `value` |
|
555 * |
|
556 * The wrapper functions `first` and `last` return wrapped values when `n` is |
|
557 * provided, otherwise they return unwrapped values. |
|
558 * |
|
559 * Explicit chaining can be enabled by using the `_.chain` method. |
|
560 * |
|
561 * @name _ |
|
562 * @constructor |
|
563 * @category Chaining |
|
564 * @param {*} value The value to wrap in a `lodash` instance. |
|
565 * @returns {Object} Returns a `lodash` instance. |
|
566 * @example |
|
567 * |
|
568 * var wrapped = _([1, 2, 3]); |
|
569 * |
|
570 * // returns an unwrapped value |
|
571 * wrapped.reduce(function(sum, num) { |
|
572 * return sum + num; |
|
573 * }); |
|
574 * // => 6 |
|
575 * |
|
576 * // returns a wrapped value |
|
577 * var squares = wrapped.map(function(num) { |
|
578 * return num * num; |
|
579 * }); |
|
580 * |
|
581 * _.isArray(squares); |
|
582 * // => false |
|
583 * |
|
584 * _.isArray(squares.value()); |
|
585 * // => true |
|
586 */ |
|
587 function lodash(value) { |
|
588 // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor |
|
589 return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) |
|
590 ? value |
|
591 : new lodashWrapper(value); |
|
592 } |
|
593 |
|
594 /** |
|
595 * A fast path for creating `lodash` wrapper objects. |
|
596 * |
|
597 * @private |
|
598 * @param {*} value The value to wrap in a `lodash` instance. |
|
599 * @param {boolean} chainAll A flag to enable chaining for all methods |
|
600 * @returns {Object} Returns a `lodash` instance. |
|
601 */ |
|
602 function lodashWrapper(value, chainAll) { |
|
603 this.__chain__ = !!chainAll; |
|
604 this.__wrapped__ = value; |
|
605 } |
|
606 // ensure `new lodashWrapper` is an instance of `lodash` |
|
607 lodashWrapper.prototype = lodash.prototype; |
|
608 |
|
609 /** |
|
610 * An object used to flag environments features. |
|
611 * |
|
612 * @static |
|
613 * @memberOf _ |
|
614 * @type Object |
|
615 */ |
|
616 var support = lodash.support = {}; |
|
617 |
|
618 /** |
|
619 * Detect if functions can be decompiled by `Function#toString` |
|
620 * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). |
|
621 * |
|
622 * @memberOf _.support |
|
623 * @type boolean |
|
624 */ |
|
625 support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); |
|
626 |
|
627 /** |
|
628 * Detect if `Function#name` is supported (all but IE). |
|
629 * |
|
630 * @memberOf _.support |
|
631 * @type boolean |
|
632 */ |
|
633 support.funcNames = typeof Function.name == 'string'; |
|
634 |
|
635 /** |
|
636 * By default, the template delimiters used by Lo-Dash are similar to those in |
|
637 * embedded Ruby (ERB). Change the following template settings to use alternative |
|
638 * delimiters. |
|
639 * |
|
640 * @static |
|
641 * @memberOf _ |
|
642 * @type Object |
|
643 */ |
|
644 lodash.templateSettings = { |
|
645 |
|
646 /** |
|
647 * Used to detect `data` property values to be HTML-escaped. |
|
648 * |
|
649 * @memberOf _.templateSettings |
|
650 * @type RegExp |
|
651 */ |
|
652 'escape': /<%-([\s\S]+?)%>/g, |
|
653 |
|
654 /** |
|
655 * Used to detect code to be evaluated. |
|
656 * |
|
657 * @memberOf _.templateSettings |
|
658 * @type RegExp |
|
659 */ |
|
660 'evaluate': /<%([\s\S]+?)%>/g, |
|
661 |
|
662 /** |
|
663 * Used to detect `data` property values to inject. |
|
664 * |
|
665 * @memberOf _.templateSettings |
|
666 * @type RegExp |
|
667 */ |
|
668 'interpolate': reInterpolate, |
|
669 |
|
670 /** |
|
671 * Used to reference the data object in the template text. |
|
672 * |
|
673 * @memberOf _.templateSettings |
|
674 * @type string |
|
675 */ |
|
676 'variable': '', |
|
677 |
|
678 /** |
|
679 * Used to import variables into the compiled template. |
|
680 * |
|
681 * @memberOf _.templateSettings |
|
682 * @type Object |
|
683 */ |
|
684 'imports': { |
|
685 |
|
686 /** |
|
687 * A reference to the `lodash` function. |
|
688 * |
|
689 * @memberOf _.templateSettings.imports |
|
690 * @type Function |
|
691 */ |
|
692 '_': lodash |
|
693 } |
|
694 }; |
|
695 |
|
696 /*--------------------------------------------------------------------------*/ |
|
697 |
|
698 /** |
|
699 * The base implementation of `_.bind` that creates the bound function and |
|
700 * sets its meta data. |
|
701 * |
|
702 * @private |
|
703 * @param {Array} bindData The bind data array. |
|
704 * @returns {Function} Returns the new bound function. |
|
705 */ |
|
706 function baseBind(bindData) { |
|
707 var func = bindData[0], |
|
708 partialArgs = bindData[2], |
|
709 thisArg = bindData[4]; |
|
710 |
|
711 function bound() { |
|
712 // `Function#bind` spec |
|
713 // http://es5.github.io/#x15.3.4.5 |
|
714 if (partialArgs) { |
|
715 // avoid `arguments` object deoptimizations by using `slice` instead |
|
716 // of `Array.prototype.slice.call` and not assigning `arguments` to a |
|
717 // variable as a ternary expression |
|
718 var args = slice(partialArgs); |
|
719 push.apply(args, arguments); |
|
720 } |
|
721 // mimic the constructor's `return` behavior |
|
722 // http://es5.github.io/#x13.2.2 |
|
723 if (this instanceof bound) { |
|
724 // ensure `new bound` is an instance of `func` |
|
725 var thisBinding = baseCreate(func.prototype), |
|
726 result = func.apply(thisBinding, args || arguments); |
|
727 return isObject(result) ? result : thisBinding; |
|
728 } |
|
729 return func.apply(thisArg, args || arguments); |
|
730 } |
|
731 setBindData(bound, bindData); |
|
732 return bound; |
|
733 } |
|
734 |
|
735 /** |
|
736 * The base implementation of `_.clone` without argument juggling or support |
|
737 * for `thisArg` binding. |
|
738 * |
|
739 * @private |
|
740 * @param {*} value The value to clone. |
|
741 * @param {boolean} [isDeep=false] Specify a deep clone. |
|
742 * @param {Function} [callback] The function to customize cloning values. |
|
743 * @param {Array} [stackA=[]] Tracks traversed source objects. |
|
744 * @param {Array} [stackB=[]] Associates clones with source counterparts. |
|
745 * @returns {*} Returns the cloned value. |
|
746 */ |
|
747 function baseClone(value, isDeep, callback, stackA, stackB) { |
|
748 if (callback) { |
|
749 var result = callback(value); |
|
750 if (typeof result != 'undefined') { |
|
751 return result; |
|
752 } |
|
753 } |
|
754 // inspect [[Class]] |
|
755 var isObj = isObject(value); |
|
756 if (isObj) { |
|
757 var className = toString.call(value); |
|
758 if (!cloneableClasses[className]) { |
|
759 return value; |
|
760 } |
|
761 var ctor = ctorByClass[className]; |
|
762 switch (className) { |
|
763 case boolClass: |
|
764 case dateClass: |
|
765 return new ctor(+value); |
|
766 |
|
767 case numberClass: |
|
768 case stringClass: |
|
769 return new ctor(value); |
|
770 |
|
771 case regexpClass: |
|
772 result = ctor(value.source, reFlags.exec(value)); |
|
773 result.lastIndex = value.lastIndex; |
|
774 return result; |
|
775 } |
|
776 } else { |
|
777 return value; |
|
778 } |
|
779 var isArr = isArray(value); |
|
780 if (isDeep) { |
|
781 // check for circular references and return corresponding clone |
|
782 var initedStack = !stackA; |
|
783 stackA || (stackA = getArray()); |
|
784 stackB || (stackB = getArray()); |
|
785 |
|
786 var length = stackA.length; |
|
787 while (length--) { |
|
788 if (stackA[length] == value) { |
|
789 return stackB[length]; |
|
790 } |
|
791 } |
|
792 result = isArr ? ctor(value.length) : {}; |
|
793 } |
|
794 else { |
|
795 result = isArr ? slice(value) : assign({}, value); |
|
796 } |
|
797 // add array properties assigned by `RegExp#exec` |
|
798 if (isArr) { |
|
799 if (hasOwnProperty.call(value, 'index')) { |
|
800 result.index = value.index; |
|
801 } |
|
802 if (hasOwnProperty.call(value, 'input')) { |
|
803 result.input = value.input; |
|
804 } |
|
805 } |
|
806 // exit for shallow clone |
|
807 if (!isDeep) { |
|
808 return result; |
|
809 } |
|
810 // add the source value to the stack of traversed objects |
|
811 // and associate it with its clone |
|
812 stackA.push(value); |
|
813 stackB.push(result); |
|
814 |
|
815 // recursively populate clone (susceptible to call stack limits) |
|
816 (isArr ? forEach : forOwn)(value, function(objValue, key) { |
|
817 result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); |
|
818 }); |
|
819 |
|
820 if (initedStack) { |
|
821 releaseArray(stackA); |
|
822 releaseArray(stackB); |
|
823 } |
|
824 return result; |
|
825 } |
|
826 |
|
827 /** |
|
828 * The base implementation of `_.create` without support for assigning |
|
829 * properties to the created object. |
|
830 * |
|
831 * @private |
|
832 * @param {Object} prototype The object to inherit from. |
|
833 * @returns {Object} Returns the new object. |
|
834 */ |
|
835 function baseCreate(prototype, properties) { |
|
836 return isObject(prototype) ? nativeCreate(prototype) : {}; |
|
837 } |
|
838 // fallback for browsers without `Object.create` |
|
839 if (!nativeCreate) { |
|
840 baseCreate = (function() { |
|
841 function Object() {} |
|
842 return function(prototype) { |
|
843 if (isObject(prototype)) { |
|
844 Object.prototype = prototype; |
|
845 var result = new Object; |
|
846 Object.prototype = null; |
|
847 } |
|
848 return result || context.Object(); |
|
849 }; |
|
850 }()); |
|
851 } |
|
852 |
|
853 /** |
|
854 * The base implementation of `_.createCallback` without support for creating |
|
855 * "_.pluck" or "_.where" style callbacks. |
|
856 * |
|
857 * @private |
|
858 * @param {*} [func=identity] The value to convert to a callback. |
|
859 * @param {*} [thisArg] The `this` binding of the created callback. |
|
860 * @param {number} [argCount] The number of arguments the callback accepts. |
|
861 * @returns {Function} Returns a callback function. |
|
862 */ |
|
863 function baseCreateCallback(func, thisArg, argCount) { |
|
864 if (typeof func != 'function') { |
|
865 return identity; |
|
866 } |
|
867 // exit early for no `thisArg` or already bound by `Function#bind` |
|
868 if (typeof thisArg == 'undefined' || !('prototype' in func)) { |
|
869 return func; |
|
870 } |
|
871 var bindData = func.__bindData__; |
|
872 if (typeof bindData == 'undefined') { |
|
873 if (support.funcNames) { |
|
874 bindData = !func.name; |
|
875 } |
|
876 bindData = bindData || !support.funcDecomp; |
|
877 if (!bindData) { |
|
878 var source = fnToString.call(func); |
|
879 if (!support.funcNames) { |
|
880 bindData = !reFuncName.test(source); |
|
881 } |
|
882 if (!bindData) { |
|
883 // checks if `func` references the `this` keyword and stores the result |
|
884 bindData = reThis.test(source); |
|
885 setBindData(func, bindData); |
|
886 } |
|
887 } |
|
888 } |
|
889 // exit early if there are no `this` references or `func` is bound |
|
890 if (bindData === false || (bindData !== true && bindData[1] & 1)) { |
|
891 return func; |
|
892 } |
|
893 switch (argCount) { |
|
894 case 1: return function(value) { |
|
895 return func.call(thisArg, value); |
|
896 }; |
|
897 case 2: return function(a, b) { |
|
898 return func.call(thisArg, a, b); |
|
899 }; |
|
900 case 3: return function(value, index, collection) { |
|
901 return func.call(thisArg, value, index, collection); |
|
902 }; |
|
903 case 4: return function(accumulator, value, index, collection) { |
|
904 return func.call(thisArg, accumulator, value, index, collection); |
|
905 }; |
|
906 } |
|
907 return bind(func, thisArg); |
|
908 } |
|
909 |
|
910 /** |
|
911 * The base implementation of `createWrapper` that creates the wrapper and |
|
912 * sets its meta data. |
|
913 * |
|
914 * @private |
|
915 * @param {Array} bindData The bind data array. |
|
916 * @returns {Function} Returns the new function. |
|
917 */ |
|
918 function baseCreateWrapper(bindData) { |
|
919 var func = bindData[0], |
|
920 bitmask = bindData[1], |
|
921 partialArgs = bindData[2], |
|
922 partialRightArgs = bindData[3], |
|
923 thisArg = bindData[4], |
|
924 arity = bindData[5]; |
|
925 |
|
926 var isBind = bitmask & 1, |
|
927 isBindKey = bitmask & 2, |
|
928 isCurry = bitmask & 4, |
|
929 isCurryBound = bitmask & 8, |
|
930 key = func; |
|
931 |
|
932 function bound() { |
|
933 var thisBinding = isBind ? thisArg : this; |
|
934 if (partialArgs) { |
|
935 var args = slice(partialArgs); |
|
936 push.apply(args, arguments); |
|
937 } |
|
938 if (partialRightArgs || isCurry) { |
|
939 args || (args = slice(arguments)); |
|
940 if (partialRightArgs) { |
|
941 push.apply(args, partialRightArgs); |
|
942 } |
|
943 if (isCurry && args.length < arity) { |
|
944 bitmask |= 16 & ~32; |
|
945 return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); |
|
946 } |
|
947 } |
|
948 args || (args = arguments); |
|
949 if (isBindKey) { |
|
950 func = thisBinding[key]; |
|
951 } |
|
952 if (this instanceof bound) { |
|
953 thisBinding = baseCreate(func.prototype); |
|
954 var result = func.apply(thisBinding, args); |
|
955 return isObject(result) ? result : thisBinding; |
|
956 } |
|
957 return func.apply(thisBinding, args); |
|
958 } |
|
959 setBindData(bound, bindData); |
|
960 return bound; |
|
961 } |
|
962 |
|
963 /** |
|
964 * The base implementation of `_.difference` that accepts a single array |
|
965 * of values to exclude. |
|
966 * |
|
967 * @private |
|
968 * @param {Array} array The array to process. |
|
969 * @param {Array} [values] The array of values to exclude. |
|
970 * @returns {Array} Returns a new array of filtered values. |
|
971 */ |
|
972 function baseDifference(array, values) { |
|
973 var index = -1, |
|
974 indexOf = getIndexOf(), |
|
975 length = array ? array.length : 0, |
|
976 isLarge = length >= largeArraySize && indexOf === baseIndexOf, |
|
977 result = []; |
|
978 |
|
979 if (isLarge) { |
|
980 var cache = createCache(values); |
|
981 if (cache) { |
|
982 indexOf = cacheIndexOf; |
|
983 values = cache; |
|
984 } else { |
|
985 isLarge = false; |
|
986 } |
|
987 } |
|
988 while (++index < length) { |
|
989 var value = array[index]; |
|
990 if (indexOf(values, value) < 0) { |
|
991 result.push(value); |
|
992 } |
|
993 } |
|
994 if (isLarge) { |
|
995 releaseObject(values); |
|
996 } |
|
997 return result; |
|
998 } |
|
999 |
|
1000 /** |
|
1001 * The base implementation of `_.flatten` without support for callback |
|
1002 * shorthands or `thisArg` binding. |
|
1003 * |
|
1004 * @private |
|
1005 * @param {Array} array The array to flatten. |
|
1006 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. |
|
1007 * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. |
|
1008 * @param {number} [fromIndex=0] The index to start from. |
|
1009 * @returns {Array} Returns a new flattened array. |
|
1010 */ |
|
1011 function baseFlatten(array, isShallow, isStrict, fromIndex) { |
|
1012 var index = (fromIndex || 0) - 1, |
|
1013 length = array ? array.length : 0, |
|
1014 result = []; |
|
1015 |
|
1016 while (++index < length) { |
|
1017 var value = array[index]; |
|
1018 |
|
1019 if (value && typeof value == 'object' && typeof value.length == 'number' |
|
1020 && (isArray(value) || isArguments(value))) { |
|
1021 // recursively flatten arrays (susceptible to call stack limits) |
|
1022 if (!isShallow) { |
|
1023 value = baseFlatten(value, isShallow, isStrict); |
|
1024 } |
|
1025 var valIndex = -1, |
|
1026 valLength = value.length, |
|
1027 resIndex = result.length; |
|
1028 |
|
1029 result.length += valLength; |
|
1030 while (++valIndex < valLength) { |
|
1031 result[resIndex++] = value[valIndex]; |
|
1032 } |
|
1033 } else if (!isStrict) { |
|
1034 result.push(value); |
|
1035 } |
|
1036 } |
|
1037 return result; |
|
1038 } |
|
1039 |
|
1040 /** |
|
1041 * The base implementation of `_.isEqual`, without support for `thisArg` binding, |
|
1042 * that allows partial "_.where" style comparisons. |
|
1043 * |
|
1044 * @private |
|
1045 * @param {*} a The value to compare. |
|
1046 * @param {*} b The other value to compare. |
|
1047 * @param {Function} [callback] The function to customize comparing values. |
|
1048 * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. |
|
1049 * @param {Array} [stackA=[]] Tracks traversed `a` objects. |
|
1050 * @param {Array} [stackB=[]] Tracks traversed `b` objects. |
|
1051 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
1052 */ |
|
1053 function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { |
|
1054 // used to indicate that when comparing objects, `a` has at least the properties of `b` |
|
1055 if (callback) { |
|
1056 var result = callback(a, b); |
|
1057 if (typeof result != 'undefined') { |
|
1058 return !!result; |
|
1059 } |
|
1060 } |
|
1061 // exit early for identical values |
|
1062 if (a === b) { |
|
1063 // treat `+0` vs. `-0` as not equal |
|
1064 return a !== 0 || (1 / a == 1 / b); |
|
1065 } |
|
1066 var type = typeof a, |
|
1067 otherType = typeof b; |
|
1068 |
|
1069 // exit early for unlike primitive values |
|
1070 if (a === a && |
|
1071 !(a && objectTypes[type]) && |
|
1072 !(b && objectTypes[otherType])) { |
|
1073 return false; |
|
1074 } |
|
1075 // exit early for `null` and `undefined` avoiding ES3's Function#call behavior |
|
1076 // http://es5.github.io/#x15.3.4.4 |
|
1077 if (a == null || b == null) { |
|
1078 return a === b; |
|
1079 } |
|
1080 // compare [[Class]] names |
|
1081 var className = toString.call(a), |
|
1082 otherClass = toString.call(b); |
|
1083 |
|
1084 if (className == argsClass) { |
|
1085 className = objectClass; |
|
1086 } |
|
1087 if (otherClass == argsClass) { |
|
1088 otherClass = objectClass; |
|
1089 } |
|
1090 if (className != otherClass) { |
|
1091 return false; |
|
1092 } |
|
1093 switch (className) { |
|
1094 case boolClass: |
|
1095 case dateClass: |
|
1096 // coerce dates and booleans to numbers, dates to milliseconds and booleans |
|
1097 // to `1` or `0` treating invalid dates coerced to `NaN` as not equal |
|
1098 return +a == +b; |
|
1099 |
|
1100 case numberClass: |
|
1101 // treat `NaN` vs. `NaN` as equal |
|
1102 return (a != +a) |
|
1103 ? b != +b |
|
1104 // but treat `+0` vs. `-0` as not equal |
|
1105 : (a == 0 ? (1 / a == 1 / b) : a == +b); |
|
1106 |
|
1107 case regexpClass: |
|
1108 case stringClass: |
|
1109 // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) |
|
1110 // treat string primitives and their corresponding object instances as equal |
|
1111 return a == String(b); |
|
1112 } |
|
1113 var isArr = className == arrayClass; |
|
1114 if (!isArr) { |
|
1115 // unwrap any `lodash` wrapped values |
|
1116 var aWrapped = hasOwnProperty.call(a, '__wrapped__'), |
|
1117 bWrapped = hasOwnProperty.call(b, '__wrapped__'); |
|
1118 |
|
1119 if (aWrapped || bWrapped) { |
|
1120 return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); |
|
1121 } |
|
1122 // exit for functions and DOM nodes |
|
1123 if (className != objectClass) { |
|
1124 return false; |
|
1125 } |
|
1126 // in older versions of Opera, `arguments` objects have `Array` constructors |
|
1127 var ctorA = a.constructor, |
|
1128 ctorB = b.constructor; |
|
1129 |
|
1130 // non `Object` object instances with different constructors are not equal |
|
1131 if (ctorA != ctorB && |
|
1132 !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && |
|
1133 ('constructor' in a && 'constructor' in b) |
|
1134 ) { |
|
1135 return false; |
|
1136 } |
|
1137 } |
|
1138 // assume cyclic structures are equal |
|
1139 // the algorithm for detecting cyclic structures is adapted from ES 5.1 |
|
1140 // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) |
|
1141 var initedStack = !stackA; |
|
1142 stackA || (stackA = getArray()); |
|
1143 stackB || (stackB = getArray()); |
|
1144 |
|
1145 var length = stackA.length; |
|
1146 while (length--) { |
|
1147 if (stackA[length] == a) { |
|
1148 return stackB[length] == b; |
|
1149 } |
|
1150 } |
|
1151 var size = 0; |
|
1152 result = true; |
|
1153 |
|
1154 // add `a` and `b` to the stack of traversed objects |
|
1155 stackA.push(a); |
|
1156 stackB.push(b); |
|
1157 |
|
1158 // recursively compare objects and arrays (susceptible to call stack limits) |
|
1159 if (isArr) { |
|
1160 // compare lengths to determine if a deep comparison is necessary |
|
1161 length = a.length; |
|
1162 size = b.length; |
|
1163 result = size == length; |
|
1164 |
|
1165 if (result || isWhere) { |
|
1166 // deep compare the contents, ignoring non-numeric properties |
|
1167 while (size--) { |
|
1168 var index = length, |
|
1169 value = b[size]; |
|
1170 |
|
1171 if (isWhere) { |
|
1172 while (index--) { |
|
1173 if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { |
|
1174 break; |
|
1175 } |
|
1176 } |
|
1177 } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { |
|
1178 break; |
|
1179 } |
|
1180 } |
|
1181 } |
|
1182 } |
|
1183 else { |
|
1184 // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` |
|
1185 // which, in this case, is more costly |
|
1186 forIn(b, function(value, key, b) { |
|
1187 if (hasOwnProperty.call(b, key)) { |
|
1188 // count the number of properties. |
|
1189 size++; |
|
1190 // deep compare each property value. |
|
1191 return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); |
|
1192 } |
|
1193 }); |
|
1194 |
|
1195 if (result && !isWhere) { |
|
1196 // ensure both objects have the same number of properties |
|
1197 forIn(a, function(value, key, a) { |
|
1198 if (hasOwnProperty.call(a, key)) { |
|
1199 // `size` will be `-1` if `a` has more properties than `b` |
|
1200 return (result = --size > -1); |
|
1201 } |
|
1202 }); |
|
1203 } |
|
1204 } |
|
1205 stackA.pop(); |
|
1206 stackB.pop(); |
|
1207 |
|
1208 if (initedStack) { |
|
1209 releaseArray(stackA); |
|
1210 releaseArray(stackB); |
|
1211 } |
|
1212 return result; |
|
1213 } |
|
1214 |
|
1215 /** |
|
1216 * The base implementation of `_.merge` without argument juggling or support |
|
1217 * for `thisArg` binding. |
|
1218 * |
|
1219 * @private |
|
1220 * @param {Object} object The destination object. |
|
1221 * @param {Object} source The source object. |
|
1222 * @param {Function} [callback] The function to customize merging properties. |
|
1223 * @param {Array} [stackA=[]] Tracks traversed source objects. |
|
1224 * @param {Array} [stackB=[]] Associates values with source counterparts. |
|
1225 */ |
|
1226 function baseMerge(object, source, callback, stackA, stackB) { |
|
1227 (isArray(source) ? forEach : forOwn)(source, function(source, key) { |
|
1228 var found, |
|
1229 isArr, |
|
1230 result = source, |
|
1231 value = object[key]; |
|
1232 |
|
1233 if (source && ((isArr = isArray(source)) || isPlainObject(source))) { |
|
1234 // avoid merging previously merged cyclic sources |
|
1235 var stackLength = stackA.length; |
|
1236 while (stackLength--) { |
|
1237 if ((found = stackA[stackLength] == source)) { |
|
1238 value = stackB[stackLength]; |
|
1239 break; |
|
1240 } |
|
1241 } |
|
1242 if (!found) { |
|
1243 var isShallow; |
|
1244 if (callback) { |
|
1245 result = callback(value, source); |
|
1246 if ((isShallow = typeof result != 'undefined')) { |
|
1247 value = result; |
|
1248 } |
|
1249 } |
|
1250 if (!isShallow) { |
|
1251 value = isArr |
|
1252 ? (isArray(value) ? value : []) |
|
1253 : (isPlainObject(value) ? value : {}); |
|
1254 } |
|
1255 // add `source` and associated `value` to the stack of traversed objects |
|
1256 stackA.push(source); |
|
1257 stackB.push(value); |
|
1258 |
|
1259 // recursively merge objects and arrays (susceptible to call stack limits) |
|
1260 if (!isShallow) { |
|
1261 baseMerge(value, source, callback, stackA, stackB); |
|
1262 } |
|
1263 } |
|
1264 } |
|
1265 else { |
|
1266 if (callback) { |
|
1267 result = callback(value, source); |
|
1268 if (typeof result == 'undefined') { |
|
1269 result = source; |
|
1270 } |
|
1271 } |
|
1272 if (typeof result != 'undefined') { |
|
1273 value = result; |
|
1274 } |
|
1275 } |
|
1276 object[key] = value; |
|
1277 }); |
|
1278 } |
|
1279 |
|
1280 /** |
|
1281 * The base implementation of `_.random` without argument juggling or support |
|
1282 * for returning floating-point numbers. |
|
1283 * |
|
1284 * @private |
|
1285 * @param {number} min The minimum possible value. |
|
1286 * @param {number} max The maximum possible value. |
|
1287 * @returns {number} Returns a random number. |
|
1288 */ |
|
1289 function baseRandom(min, max) { |
|
1290 return min + floor(nativeRandom() * (max - min + 1)); |
|
1291 } |
|
1292 |
|
1293 /** |
|
1294 * The base implementation of `_.uniq` without support for callback shorthands |
|
1295 * or `thisArg` binding. |
|
1296 * |
|
1297 * @private |
|
1298 * @param {Array} array The array to process. |
|
1299 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. |
|
1300 * @param {Function} [callback] The function called per iteration. |
|
1301 * @returns {Array} Returns a duplicate-value-free array. |
|
1302 */ |
|
1303 function baseUniq(array, isSorted, callback) { |
|
1304 var index = -1, |
|
1305 indexOf = getIndexOf(), |
|
1306 length = array ? array.length : 0, |
|
1307 result = []; |
|
1308 |
|
1309 var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, |
|
1310 seen = (callback || isLarge) ? getArray() : result; |
|
1311 |
|
1312 if (isLarge) { |
|
1313 var cache = createCache(seen); |
|
1314 indexOf = cacheIndexOf; |
|
1315 seen = cache; |
|
1316 } |
|
1317 while (++index < length) { |
|
1318 var value = array[index], |
|
1319 computed = callback ? callback(value, index, array) : value; |
|
1320 |
|
1321 if (isSorted |
|
1322 ? !index || seen[seen.length - 1] !== computed |
|
1323 : indexOf(seen, computed) < 0 |
|
1324 ) { |
|
1325 if (callback || isLarge) { |
|
1326 seen.push(computed); |
|
1327 } |
|
1328 result.push(value); |
|
1329 } |
|
1330 } |
|
1331 if (isLarge) { |
|
1332 releaseArray(seen.array); |
|
1333 releaseObject(seen); |
|
1334 } else if (callback) { |
|
1335 releaseArray(seen); |
|
1336 } |
|
1337 return result; |
|
1338 } |
|
1339 |
|
1340 /** |
|
1341 * Creates a function that aggregates a collection, creating an object composed |
|
1342 * of keys generated from the results of running each element of the collection |
|
1343 * through a callback. The given `setter` function sets the keys and values |
|
1344 * of the composed object. |
|
1345 * |
|
1346 * @private |
|
1347 * @param {Function} setter The setter function. |
|
1348 * @returns {Function} Returns the new aggregator function. |
|
1349 */ |
|
1350 function createAggregator(setter) { |
|
1351 return function(collection, callback, thisArg) { |
|
1352 var result = {}; |
|
1353 callback = lodash.createCallback(callback, thisArg, 3); |
|
1354 |
|
1355 var index = -1, |
|
1356 length = collection ? collection.length : 0; |
|
1357 |
|
1358 if (typeof length == 'number') { |
|
1359 while (++index < length) { |
|
1360 var value = collection[index]; |
|
1361 setter(result, value, callback(value, index, collection), collection); |
|
1362 } |
|
1363 } else { |
|
1364 forOwn(collection, function(value, key, collection) { |
|
1365 setter(result, value, callback(value, key, collection), collection); |
|
1366 }); |
|
1367 } |
|
1368 return result; |
|
1369 }; |
|
1370 } |
|
1371 |
|
1372 /** |
|
1373 * Creates a function that, when called, either curries or invokes `func` |
|
1374 * with an optional `this` binding and partially applied arguments. |
|
1375 * |
|
1376 * @private |
|
1377 * @param {Function|string} func The function or method name to reference. |
|
1378 * @param {number} bitmask The bitmask of method flags to compose. |
|
1379 * The bitmask may be composed of the following flags: |
|
1380 * 1 - `_.bind` |
|
1381 * 2 - `_.bindKey` |
|
1382 * 4 - `_.curry` |
|
1383 * 8 - `_.curry` (bound) |
|
1384 * 16 - `_.partial` |
|
1385 * 32 - `_.partialRight` |
|
1386 * @param {Array} [partialArgs] An array of arguments to prepend to those |
|
1387 * provided to the new function. |
|
1388 * @param {Array} [partialRightArgs] An array of arguments to append to those |
|
1389 * provided to the new function. |
|
1390 * @param {*} [thisArg] The `this` binding of `func`. |
|
1391 * @param {number} [arity] The arity of `func`. |
|
1392 * @returns {Function} Returns the new function. |
|
1393 */ |
|
1394 function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { |
|
1395 var isBind = bitmask & 1, |
|
1396 isBindKey = bitmask & 2, |
|
1397 isCurry = bitmask & 4, |
|
1398 isCurryBound = bitmask & 8, |
|
1399 isPartial = bitmask & 16, |
|
1400 isPartialRight = bitmask & 32; |
|
1401 |
|
1402 if (!isBindKey && !isFunction(func)) { |
|
1403 throw new TypeError; |
|
1404 } |
|
1405 if (isPartial && !partialArgs.length) { |
|
1406 bitmask &= ~16; |
|
1407 isPartial = partialArgs = false; |
|
1408 } |
|
1409 if (isPartialRight && !partialRightArgs.length) { |
|
1410 bitmask &= ~32; |
|
1411 isPartialRight = partialRightArgs = false; |
|
1412 } |
|
1413 var bindData = func && func.__bindData__; |
|
1414 if (bindData && bindData !== true) { |
|
1415 // clone `bindData` |
|
1416 bindData = slice(bindData); |
|
1417 if (bindData[2]) { |
|
1418 bindData[2] = slice(bindData[2]); |
|
1419 } |
|
1420 if (bindData[3]) { |
|
1421 bindData[3] = slice(bindData[3]); |
|
1422 } |
|
1423 // set `thisBinding` is not previously bound |
|
1424 if (isBind && !(bindData[1] & 1)) { |
|
1425 bindData[4] = thisArg; |
|
1426 } |
|
1427 // set if previously bound but not currently (subsequent curried functions) |
|
1428 if (!isBind && bindData[1] & 1) { |
|
1429 bitmask |= 8; |
|
1430 } |
|
1431 // set curried arity if not yet set |
|
1432 if (isCurry && !(bindData[1] & 4)) { |
|
1433 bindData[5] = arity; |
|
1434 } |
|
1435 // append partial left arguments |
|
1436 if (isPartial) { |
|
1437 push.apply(bindData[2] || (bindData[2] = []), partialArgs); |
|
1438 } |
|
1439 // append partial right arguments |
|
1440 if (isPartialRight) { |
|
1441 unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); |
|
1442 } |
|
1443 // merge flags |
|
1444 bindData[1] |= bitmask; |
|
1445 return createWrapper.apply(null, bindData); |
|
1446 } |
|
1447 // fast path for `_.bind` |
|
1448 var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; |
|
1449 return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); |
|
1450 } |
|
1451 |
|
1452 /** |
|
1453 * Used by `escape` to convert characters to HTML entities. |
|
1454 * |
|
1455 * @private |
|
1456 * @param {string} match The matched character to escape. |
|
1457 * @returns {string} Returns the escaped character. |
|
1458 */ |
|
1459 function escapeHtmlChar(match) { |
|
1460 return htmlEscapes[match]; |
|
1461 } |
|
1462 |
|
1463 /** |
|
1464 * Gets the appropriate "indexOf" function. If the `_.indexOf` method is |
|
1465 * customized, this method returns the custom method, otherwise it returns |
|
1466 * the `baseIndexOf` function. |
|
1467 * |
|
1468 * @private |
|
1469 * @returns {Function} Returns the "indexOf" function. |
|
1470 */ |
|
1471 function getIndexOf() { |
|
1472 var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; |
|
1473 return result; |
|
1474 } |
|
1475 |
|
1476 /** |
|
1477 * Checks if `value` is a native function. |
|
1478 * |
|
1479 * @private |
|
1480 * @param {*} value The value to check. |
|
1481 * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. |
|
1482 */ |
|
1483 function isNative(value) { |
|
1484 return typeof value == 'function' && reNative.test(value); |
|
1485 } |
|
1486 |
|
1487 /** |
|
1488 * Sets `this` binding data on a given function. |
|
1489 * |
|
1490 * @private |
|
1491 * @param {Function} func The function to set data on. |
|
1492 * @param {Array} value The data array to set. |
|
1493 */ |
|
1494 var setBindData = !defineProperty ? noop : function(func, value) { |
|
1495 descriptor.value = value; |
|
1496 defineProperty(func, '__bindData__', descriptor); |
|
1497 }; |
|
1498 |
|
1499 /** |
|
1500 * A fallback implementation of `isPlainObject` which checks if a given value |
|
1501 * is an object created by the `Object` constructor, assuming objects created |
|
1502 * by the `Object` constructor have no inherited enumerable properties and that |
|
1503 * there are no `Object.prototype` extensions. |
|
1504 * |
|
1505 * @private |
|
1506 * @param {*} value The value to check. |
|
1507 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
|
1508 */ |
|
1509 function shimIsPlainObject(value) { |
|
1510 var ctor, |
|
1511 result; |
|
1512 |
|
1513 // avoid non Object objects, `arguments` objects, and DOM elements |
|
1514 if (!(value && toString.call(value) == objectClass) || |
|
1515 (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) { |
|
1516 return false; |
|
1517 } |
|
1518 // In most environments an object's own properties are iterated before |
|
1519 // its inherited properties. If the last iterated property is an object's |
|
1520 // own property then there are no inherited enumerable properties. |
|
1521 forIn(value, function(value, key) { |
|
1522 result = key; |
|
1523 }); |
|
1524 return typeof result == 'undefined' || hasOwnProperty.call(value, result); |
|
1525 } |
|
1526 |
|
1527 /** |
|
1528 * Used by `unescape` to convert HTML entities to characters. |
|
1529 * |
|
1530 * @private |
|
1531 * @param {string} match The matched character to unescape. |
|
1532 * @returns {string} Returns the unescaped character. |
|
1533 */ |
|
1534 function unescapeHtmlChar(match) { |
|
1535 return htmlUnescapes[match]; |
|
1536 } |
|
1537 |
|
1538 /*--------------------------------------------------------------------------*/ |
|
1539 |
|
1540 /** |
|
1541 * Checks if `value` is an `arguments` object. |
|
1542 * |
|
1543 * @static |
|
1544 * @memberOf _ |
|
1545 * @category Objects |
|
1546 * @param {*} value The value to check. |
|
1547 * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. |
|
1548 * @example |
|
1549 * |
|
1550 * (function() { return _.isArguments(arguments); })(1, 2, 3); |
|
1551 * // => true |
|
1552 * |
|
1553 * _.isArguments([1, 2, 3]); |
|
1554 * // => false |
|
1555 */ |
|
1556 function isArguments(value) { |
|
1557 return value && typeof value == 'object' && typeof value.length == 'number' && |
|
1558 toString.call(value) == argsClass || false; |
|
1559 } |
|
1560 |
|
1561 /** |
|
1562 * Checks if `value` is an array. |
|
1563 * |
|
1564 * @static |
|
1565 * @memberOf _ |
|
1566 * @type Function |
|
1567 * @category Objects |
|
1568 * @param {*} value The value to check. |
|
1569 * @returns {boolean} Returns `true` if the `value` is an array, else `false`. |
|
1570 * @example |
|
1571 * |
|
1572 * (function() { return _.isArray(arguments); })(); |
|
1573 * // => false |
|
1574 * |
|
1575 * _.isArray([1, 2, 3]); |
|
1576 * // => true |
|
1577 */ |
|
1578 var isArray = nativeIsArray || function(value) { |
|
1579 return value && typeof value == 'object' && typeof value.length == 'number' && |
|
1580 toString.call(value) == arrayClass || false; |
|
1581 }; |
|
1582 |
|
1583 /** |
|
1584 * A fallback implementation of `Object.keys` which produces an array of the |
|
1585 * given object's own enumerable property names. |
|
1586 * |
|
1587 * @private |
|
1588 * @type Function |
|
1589 * @param {Object} object The object to inspect. |
|
1590 * @returns {Array} Returns an array of property names. |
|
1591 */ |
|
1592 var shimKeys = function(object) { |
|
1593 var index, iterable = object, result = []; |
|
1594 if (!iterable) return result; |
|
1595 if (!(objectTypes[typeof object])) return result; |
|
1596 for (index in iterable) { |
|
1597 if (hasOwnProperty.call(iterable, index)) { |
|
1598 result.push(index); |
|
1599 } |
|
1600 } |
|
1601 return result |
|
1602 }; |
|
1603 |
|
1604 /** |
|
1605 * Creates an array composed of the own enumerable property names of an object. |
|
1606 * |
|
1607 * @static |
|
1608 * @memberOf _ |
|
1609 * @category Objects |
|
1610 * @param {Object} object The object to inspect. |
|
1611 * @returns {Array} Returns an array of property names. |
|
1612 * @example |
|
1613 * |
|
1614 * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); |
|
1615 * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) |
|
1616 */ |
|
1617 var keys = !nativeKeys ? shimKeys : function(object) { |
|
1618 if (!isObject(object)) { |
|
1619 return []; |
|
1620 } |
|
1621 return nativeKeys(object); |
|
1622 }; |
|
1623 |
|
1624 /** |
|
1625 * Used to convert characters to HTML entities: |
|
1626 * |
|
1627 * Though the `>` character is escaped for symmetry, characters like `>` and `/` |
|
1628 * don't require escaping in HTML and have no special meaning unless they're part |
|
1629 * of a tag or an unquoted attribute value. |
|
1630 * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") |
|
1631 */ |
|
1632 var htmlEscapes = { |
|
1633 '&': '&', |
|
1634 '<': '<', |
|
1635 '>': '>', |
|
1636 '"': '"', |
|
1637 "'": ''' |
|
1638 }; |
|
1639 |
|
1640 /** Used to convert HTML entities to characters */ |
|
1641 var htmlUnescapes = invert(htmlEscapes); |
|
1642 |
|
1643 /** Used to match HTML entities and HTML characters */ |
|
1644 var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), |
|
1645 reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); |
|
1646 |
|
1647 /*--------------------------------------------------------------------------*/ |
|
1648 |
|
1649 /** |
|
1650 * Assigns own enumerable properties of source object(s) to the destination |
|
1651 * object. Subsequent sources will overwrite property assignments of previous |
|
1652 * sources. If a callback is provided it will be executed to produce the |
|
1653 * assigned values. The callback is bound to `thisArg` and invoked with two |
|
1654 * arguments; (objectValue, sourceValue). |
|
1655 * |
|
1656 * @static |
|
1657 * @memberOf _ |
|
1658 * @type Function |
|
1659 * @alias extend |
|
1660 * @category Objects |
|
1661 * @param {Object} object The destination object. |
|
1662 * @param {...Object} [source] The source objects. |
|
1663 * @param {Function} [callback] The function to customize assigning values. |
|
1664 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1665 * @returns {Object} Returns the destination object. |
|
1666 * @example |
|
1667 * |
|
1668 * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); |
|
1669 * // => { 'name': 'fred', 'employer': 'slate' } |
|
1670 * |
|
1671 * var defaults = _.partialRight(_.assign, function(a, b) { |
|
1672 * return typeof a == 'undefined' ? b : a; |
|
1673 * }); |
|
1674 * |
|
1675 * var object = { 'name': 'barney' }; |
|
1676 * defaults(object, { 'name': 'fred', 'employer': 'slate' }); |
|
1677 * // => { 'name': 'barney', 'employer': 'slate' } |
|
1678 */ |
|
1679 var assign = function(object, source, guard) { |
|
1680 var index, iterable = object, result = iterable; |
|
1681 if (!iterable) return result; |
|
1682 var args = arguments, |
|
1683 argsIndex = 0, |
|
1684 argsLength = typeof guard == 'number' ? 2 : args.length; |
|
1685 if (argsLength > 3 && typeof args[argsLength - 2] == 'function') { |
|
1686 var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2); |
|
1687 } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') { |
|
1688 callback = args[--argsLength]; |
|
1689 } |
|
1690 while (++argsIndex < argsLength) { |
|
1691 iterable = args[argsIndex]; |
|
1692 if (iterable && objectTypes[typeof iterable]) { |
|
1693 var ownIndex = -1, |
|
1694 ownProps = objectTypes[typeof iterable] && keys(iterable), |
|
1695 length = ownProps ? ownProps.length : 0; |
|
1696 |
|
1697 while (++ownIndex < length) { |
|
1698 index = ownProps[ownIndex]; |
|
1699 result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]; |
|
1700 } |
|
1701 } |
|
1702 } |
|
1703 return result |
|
1704 }; |
|
1705 |
|
1706 /** |
|
1707 * Creates a clone of `value`. If `isDeep` is `true` nested objects will also |
|
1708 * be cloned, otherwise they will be assigned by reference. If a callback |
|
1709 * is provided it will be executed to produce the cloned values. If the |
|
1710 * callback returns `undefined` cloning will be handled by the method instead. |
|
1711 * The callback is bound to `thisArg` and invoked with one argument; (value). |
|
1712 * |
|
1713 * @static |
|
1714 * @memberOf _ |
|
1715 * @category Objects |
|
1716 * @param {*} value The value to clone. |
|
1717 * @param {boolean} [isDeep=false] Specify a deep clone. |
|
1718 * @param {Function} [callback] The function to customize cloning values. |
|
1719 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1720 * @returns {*} Returns the cloned value. |
|
1721 * @example |
|
1722 * |
|
1723 * var characters = [ |
|
1724 * { 'name': 'barney', 'age': 36 }, |
|
1725 * { 'name': 'fred', 'age': 40 } |
|
1726 * ]; |
|
1727 * |
|
1728 * var shallow = _.clone(characters); |
|
1729 * shallow[0] === characters[0]; |
|
1730 * // => true |
|
1731 * |
|
1732 * var deep = _.clone(characters, true); |
|
1733 * deep[0] === characters[0]; |
|
1734 * // => false |
|
1735 * |
|
1736 * _.mixin({ |
|
1737 * 'clone': _.partialRight(_.clone, function(value) { |
|
1738 * return _.isElement(value) ? value.cloneNode(false) : undefined; |
|
1739 * }) |
|
1740 * }); |
|
1741 * |
|
1742 * var clone = _.clone(document.body); |
|
1743 * clone.childNodes.length; |
|
1744 * // => 0 |
|
1745 */ |
|
1746 function clone(value, isDeep, callback, thisArg) { |
|
1747 // allows working with "Collections" methods without using their `index` |
|
1748 // and `collection` arguments for `isDeep` and `callback` |
|
1749 if (typeof isDeep != 'boolean' && isDeep != null) { |
|
1750 thisArg = callback; |
|
1751 callback = isDeep; |
|
1752 isDeep = false; |
|
1753 } |
|
1754 return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); |
|
1755 } |
|
1756 |
|
1757 /** |
|
1758 * Creates a deep clone of `value`. If a callback is provided it will be |
|
1759 * executed to produce the cloned values. If the callback returns `undefined` |
|
1760 * cloning will be handled by the method instead. The callback is bound to |
|
1761 * `thisArg` and invoked with one argument; (value). |
|
1762 * |
|
1763 * Note: This method is loosely based on the structured clone algorithm. Functions |
|
1764 * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and |
|
1765 * objects created by constructors other than `Object` are cloned to plain `Object` objects. |
|
1766 * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. |
|
1767 * |
|
1768 * @static |
|
1769 * @memberOf _ |
|
1770 * @category Objects |
|
1771 * @param {*} value The value to deep clone. |
|
1772 * @param {Function} [callback] The function to customize cloning values. |
|
1773 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1774 * @returns {*} Returns the deep cloned value. |
|
1775 * @example |
|
1776 * |
|
1777 * var characters = [ |
|
1778 * { 'name': 'barney', 'age': 36 }, |
|
1779 * { 'name': 'fred', 'age': 40 } |
|
1780 * ]; |
|
1781 * |
|
1782 * var deep = _.cloneDeep(characters); |
|
1783 * deep[0] === characters[0]; |
|
1784 * // => false |
|
1785 * |
|
1786 * var view = { |
|
1787 * 'label': 'docs', |
|
1788 * 'node': element |
|
1789 * }; |
|
1790 * |
|
1791 * var clone = _.cloneDeep(view, function(value) { |
|
1792 * return _.isElement(value) ? value.cloneNode(true) : undefined; |
|
1793 * }); |
|
1794 * |
|
1795 * clone.node == view.node; |
|
1796 * // => false |
|
1797 */ |
|
1798 function cloneDeep(value, callback, thisArg) { |
|
1799 return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); |
|
1800 } |
|
1801 |
|
1802 /** |
|
1803 * Creates an object that inherits from the given `prototype` object. If a |
|
1804 * `properties` object is provided its own enumerable properties are assigned |
|
1805 * to the created object. |
|
1806 * |
|
1807 * @static |
|
1808 * @memberOf _ |
|
1809 * @category Objects |
|
1810 * @param {Object} prototype The object to inherit from. |
|
1811 * @param {Object} [properties] The properties to assign to the object. |
|
1812 * @returns {Object} Returns the new object. |
|
1813 * @example |
|
1814 * |
|
1815 * function Shape() { |
|
1816 * this.x = 0; |
|
1817 * this.y = 0; |
|
1818 * } |
|
1819 * |
|
1820 * function Circle() { |
|
1821 * Shape.call(this); |
|
1822 * } |
|
1823 * |
|
1824 * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); |
|
1825 * |
|
1826 * var circle = new Circle; |
|
1827 * circle instanceof Circle; |
|
1828 * // => true |
|
1829 * |
|
1830 * circle instanceof Shape; |
|
1831 * // => true |
|
1832 */ |
|
1833 function create(prototype, properties) { |
|
1834 var result = baseCreate(prototype); |
|
1835 return properties ? assign(result, properties) : result; |
|
1836 } |
|
1837 |
|
1838 /** |
|
1839 * Assigns own enumerable properties of source object(s) to the destination |
|
1840 * object for all destination properties that resolve to `undefined`. Once a |
|
1841 * property is set, additional defaults of the same property will be ignored. |
|
1842 * |
|
1843 * @static |
|
1844 * @memberOf _ |
|
1845 * @type Function |
|
1846 * @category Objects |
|
1847 * @param {Object} object The destination object. |
|
1848 * @param {...Object} [source] The source objects. |
|
1849 * @param- {Object} [guard] Allows working with `_.reduce` without using its |
|
1850 * `key` and `object` arguments as sources. |
|
1851 * @returns {Object} Returns the destination object. |
|
1852 * @example |
|
1853 * |
|
1854 * var object = { 'name': 'barney' }; |
|
1855 * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); |
|
1856 * // => { 'name': 'barney', 'employer': 'slate' } |
|
1857 */ |
|
1858 var defaults = function(object, source, guard) { |
|
1859 var index, iterable = object, result = iterable; |
|
1860 if (!iterable) return result; |
|
1861 var args = arguments, |
|
1862 argsIndex = 0, |
|
1863 argsLength = typeof guard == 'number' ? 2 : args.length; |
|
1864 while (++argsIndex < argsLength) { |
|
1865 iterable = args[argsIndex]; |
|
1866 if (iterable && objectTypes[typeof iterable]) { |
|
1867 var ownIndex = -1, |
|
1868 ownProps = objectTypes[typeof iterable] && keys(iterable), |
|
1869 length = ownProps ? ownProps.length : 0; |
|
1870 |
|
1871 while (++ownIndex < length) { |
|
1872 index = ownProps[ownIndex]; |
|
1873 if (typeof result[index] == 'undefined') result[index] = iterable[index]; |
|
1874 } |
|
1875 } |
|
1876 } |
|
1877 return result |
|
1878 }; |
|
1879 |
|
1880 /** |
|
1881 * This method is like `_.findIndex` except that it returns the key of the |
|
1882 * first element that passes the callback check, instead of the element itself. |
|
1883 * |
|
1884 * If a property name is provided for `callback` the created "_.pluck" style |
|
1885 * callback will return the property value of the given element. |
|
1886 * |
|
1887 * If an object is provided for `callback` the created "_.where" style callback |
|
1888 * will return `true` for elements that have the properties of the given object, |
|
1889 * else `false`. |
|
1890 * |
|
1891 * @static |
|
1892 * @memberOf _ |
|
1893 * @category Objects |
|
1894 * @param {Object} object The object to search. |
|
1895 * @param {Function|Object|string} [callback=identity] The function called per |
|
1896 * iteration. If a property name or object is provided it will be used to |
|
1897 * create a "_.pluck" or "_.where" style callback, respectively. |
|
1898 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1899 * @returns {string|undefined} Returns the key of the found element, else `undefined`. |
|
1900 * @example |
|
1901 * |
|
1902 * var characters = { |
|
1903 * 'barney': { 'age': 36, 'blocked': false }, |
|
1904 * 'fred': { 'age': 40, 'blocked': true }, |
|
1905 * 'pebbles': { 'age': 1, 'blocked': false } |
|
1906 * }; |
|
1907 * |
|
1908 * _.findKey(characters, function(chr) { |
|
1909 * return chr.age < 40; |
|
1910 * }); |
|
1911 * // => 'barney' (property order is not guaranteed across environments) |
|
1912 * |
|
1913 * // using "_.where" callback shorthand |
|
1914 * _.findKey(characters, { 'age': 1 }); |
|
1915 * // => 'pebbles' |
|
1916 * |
|
1917 * // using "_.pluck" callback shorthand |
|
1918 * _.findKey(characters, 'blocked'); |
|
1919 * // => 'fred' |
|
1920 */ |
|
1921 function findKey(object, callback, thisArg) { |
|
1922 var result; |
|
1923 callback = lodash.createCallback(callback, thisArg, 3); |
|
1924 forOwn(object, function(value, key, object) { |
|
1925 if (callback(value, key, object)) { |
|
1926 result = key; |
|
1927 return false; |
|
1928 } |
|
1929 }); |
|
1930 return result; |
|
1931 } |
|
1932 |
|
1933 /** |
|
1934 * This method is like `_.findKey` except that it iterates over elements |
|
1935 * of a `collection` in the opposite order. |
|
1936 * |
|
1937 * If a property name is provided for `callback` the created "_.pluck" style |
|
1938 * callback will return the property value of the given element. |
|
1939 * |
|
1940 * If an object is provided for `callback` the created "_.where" style callback |
|
1941 * will return `true` for elements that have the properties of the given object, |
|
1942 * else `false`. |
|
1943 * |
|
1944 * @static |
|
1945 * @memberOf _ |
|
1946 * @category Objects |
|
1947 * @param {Object} object The object to search. |
|
1948 * @param {Function|Object|string} [callback=identity] The function called per |
|
1949 * iteration. If a property name or object is provided it will be used to |
|
1950 * create a "_.pluck" or "_.where" style callback, respectively. |
|
1951 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1952 * @returns {string|undefined} Returns the key of the found element, else `undefined`. |
|
1953 * @example |
|
1954 * |
|
1955 * var characters = { |
|
1956 * 'barney': { 'age': 36, 'blocked': true }, |
|
1957 * 'fred': { 'age': 40, 'blocked': false }, |
|
1958 * 'pebbles': { 'age': 1, 'blocked': true } |
|
1959 * }; |
|
1960 * |
|
1961 * _.findLastKey(characters, function(chr) { |
|
1962 * return chr.age < 40; |
|
1963 * }); |
|
1964 * // => returns `pebbles`, assuming `_.findKey` returns `barney` |
|
1965 * |
|
1966 * // using "_.where" callback shorthand |
|
1967 * _.findLastKey(characters, { 'age': 40 }); |
|
1968 * // => 'fred' |
|
1969 * |
|
1970 * // using "_.pluck" callback shorthand |
|
1971 * _.findLastKey(characters, 'blocked'); |
|
1972 * // => 'pebbles' |
|
1973 */ |
|
1974 function findLastKey(object, callback, thisArg) { |
|
1975 var result; |
|
1976 callback = lodash.createCallback(callback, thisArg, 3); |
|
1977 forOwnRight(object, function(value, key, object) { |
|
1978 if (callback(value, key, object)) { |
|
1979 result = key; |
|
1980 return false; |
|
1981 } |
|
1982 }); |
|
1983 return result; |
|
1984 } |
|
1985 |
|
1986 /** |
|
1987 * Iterates over own and inherited enumerable properties of an object, |
|
1988 * executing the callback for each property. The callback is bound to `thisArg` |
|
1989 * and invoked with three arguments; (value, key, object). Callbacks may exit |
|
1990 * iteration early by explicitly returning `false`. |
|
1991 * |
|
1992 * @static |
|
1993 * @memberOf _ |
|
1994 * @type Function |
|
1995 * @category Objects |
|
1996 * @param {Object} object The object to iterate over. |
|
1997 * @param {Function} [callback=identity] The function called per iteration. |
|
1998 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1999 * @returns {Object} Returns `object`. |
|
2000 * @example |
|
2001 * |
|
2002 * function Shape() { |
|
2003 * this.x = 0; |
|
2004 * this.y = 0; |
|
2005 * } |
|
2006 * |
|
2007 * Shape.prototype.move = function(x, y) { |
|
2008 * this.x += x; |
|
2009 * this.y += y; |
|
2010 * }; |
|
2011 * |
|
2012 * _.forIn(new Shape, function(value, key) { |
|
2013 * console.log(key); |
|
2014 * }); |
|
2015 * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) |
|
2016 */ |
|
2017 var forIn = function(collection, callback, thisArg) { |
|
2018 var index, iterable = collection, result = iterable; |
|
2019 if (!iterable) return result; |
|
2020 if (!objectTypes[typeof iterable]) return result; |
|
2021 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); |
|
2022 for (index in iterable) { |
|
2023 if (callback(iterable[index], index, collection) === false) return result; |
|
2024 } |
|
2025 return result |
|
2026 }; |
|
2027 |
|
2028 /** |
|
2029 * This method is like `_.forIn` except that it iterates over elements |
|
2030 * of a `collection` in the opposite order. |
|
2031 * |
|
2032 * @static |
|
2033 * @memberOf _ |
|
2034 * @category Objects |
|
2035 * @param {Object} object The object to iterate over. |
|
2036 * @param {Function} [callback=identity] The function called per iteration. |
|
2037 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2038 * @returns {Object} Returns `object`. |
|
2039 * @example |
|
2040 * |
|
2041 * function Shape() { |
|
2042 * this.x = 0; |
|
2043 * this.y = 0; |
|
2044 * } |
|
2045 * |
|
2046 * Shape.prototype.move = function(x, y) { |
|
2047 * this.x += x; |
|
2048 * this.y += y; |
|
2049 * }; |
|
2050 * |
|
2051 * _.forInRight(new Shape, function(value, key) { |
|
2052 * console.log(key); |
|
2053 * }); |
|
2054 * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' |
|
2055 */ |
|
2056 function forInRight(object, callback, thisArg) { |
|
2057 var pairs = []; |
|
2058 |
|
2059 forIn(object, function(value, key) { |
|
2060 pairs.push(key, value); |
|
2061 }); |
|
2062 |
|
2063 var length = pairs.length; |
|
2064 callback = baseCreateCallback(callback, thisArg, 3); |
|
2065 while (length--) { |
|
2066 if (callback(pairs[length--], pairs[length], object) === false) { |
|
2067 break; |
|
2068 } |
|
2069 } |
|
2070 return object; |
|
2071 } |
|
2072 |
|
2073 /** |
|
2074 * Iterates over own enumerable properties of an object, executing the callback |
|
2075 * for each property. The callback is bound to `thisArg` and invoked with three |
|
2076 * arguments; (value, key, object). Callbacks may exit iteration early by |
|
2077 * explicitly returning `false`. |
|
2078 * |
|
2079 * @static |
|
2080 * @memberOf _ |
|
2081 * @type Function |
|
2082 * @category Objects |
|
2083 * @param {Object} object The object to iterate over. |
|
2084 * @param {Function} [callback=identity] The function called per iteration. |
|
2085 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2086 * @returns {Object} Returns `object`. |
|
2087 * @example |
|
2088 * |
|
2089 * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { |
|
2090 * console.log(key); |
|
2091 * }); |
|
2092 * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) |
|
2093 */ |
|
2094 var forOwn = function(collection, callback, thisArg) { |
|
2095 var index, iterable = collection, result = iterable; |
|
2096 if (!iterable) return result; |
|
2097 if (!objectTypes[typeof iterable]) return result; |
|
2098 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); |
|
2099 var ownIndex = -1, |
|
2100 ownProps = objectTypes[typeof iterable] && keys(iterable), |
|
2101 length = ownProps ? ownProps.length : 0; |
|
2102 |
|
2103 while (++ownIndex < length) { |
|
2104 index = ownProps[ownIndex]; |
|
2105 if (callback(iterable[index], index, collection) === false) return result; |
|
2106 } |
|
2107 return result |
|
2108 }; |
|
2109 |
|
2110 /** |
|
2111 * This method is like `_.forOwn` except that it iterates over elements |
|
2112 * of a `collection` in the opposite order. |
|
2113 * |
|
2114 * @static |
|
2115 * @memberOf _ |
|
2116 * @category Objects |
|
2117 * @param {Object} object The object to iterate over. |
|
2118 * @param {Function} [callback=identity] The function called per iteration. |
|
2119 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2120 * @returns {Object} Returns `object`. |
|
2121 * @example |
|
2122 * |
|
2123 * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { |
|
2124 * console.log(key); |
|
2125 * }); |
|
2126 * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' |
|
2127 */ |
|
2128 function forOwnRight(object, callback, thisArg) { |
|
2129 var props = keys(object), |
|
2130 length = props.length; |
|
2131 |
|
2132 callback = baseCreateCallback(callback, thisArg, 3); |
|
2133 while (length--) { |
|
2134 var key = props[length]; |
|
2135 if (callback(object[key], key, object) === false) { |
|
2136 break; |
|
2137 } |
|
2138 } |
|
2139 return object; |
|
2140 } |
|
2141 |
|
2142 /** |
|
2143 * Creates a sorted array of property names of all enumerable properties, |
|
2144 * own and inherited, of `object` that have function values. |
|
2145 * |
|
2146 * @static |
|
2147 * @memberOf _ |
|
2148 * @alias methods |
|
2149 * @category Objects |
|
2150 * @param {Object} object The object to inspect. |
|
2151 * @returns {Array} Returns an array of property names that have function values. |
|
2152 * @example |
|
2153 * |
|
2154 * _.functions(_); |
|
2155 * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] |
|
2156 */ |
|
2157 function functions(object) { |
|
2158 var result = []; |
|
2159 forIn(object, function(value, key) { |
|
2160 if (isFunction(value)) { |
|
2161 result.push(key); |
|
2162 } |
|
2163 }); |
|
2164 return result.sort(); |
|
2165 } |
|
2166 |
|
2167 /** |
|
2168 * Checks if the specified property name exists as a direct property of `object`, |
|
2169 * instead of an inherited property. |
|
2170 * |
|
2171 * @static |
|
2172 * @memberOf _ |
|
2173 * @category Objects |
|
2174 * @param {Object} object The object to inspect. |
|
2175 * @param {string} key The name of the property to check. |
|
2176 * @returns {boolean} Returns `true` if key is a direct property, else `false`. |
|
2177 * @example |
|
2178 * |
|
2179 * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); |
|
2180 * // => true |
|
2181 */ |
|
2182 function has(object, key) { |
|
2183 return object ? hasOwnProperty.call(object, key) : false; |
|
2184 } |
|
2185 |
|
2186 /** |
|
2187 * Creates an object composed of the inverted keys and values of the given object. |
|
2188 * |
|
2189 * @static |
|
2190 * @memberOf _ |
|
2191 * @category Objects |
|
2192 * @param {Object} object The object to invert. |
|
2193 * @returns {Object} Returns the created inverted object. |
|
2194 * @example |
|
2195 * |
|
2196 * _.invert({ 'first': 'fred', 'second': 'barney' }); |
|
2197 * // => { 'fred': 'first', 'barney': 'second' } |
|
2198 */ |
|
2199 function invert(object) { |
|
2200 var index = -1, |
|
2201 props = keys(object), |
|
2202 length = props.length, |
|
2203 result = {}; |
|
2204 |
|
2205 while (++index < length) { |
|
2206 var key = props[index]; |
|
2207 result[object[key]] = key; |
|
2208 } |
|
2209 return result; |
|
2210 } |
|
2211 |
|
2212 /** |
|
2213 * Checks if `value` is a boolean value. |
|
2214 * |
|
2215 * @static |
|
2216 * @memberOf _ |
|
2217 * @category Objects |
|
2218 * @param {*} value The value to check. |
|
2219 * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. |
|
2220 * @example |
|
2221 * |
|
2222 * _.isBoolean(null); |
|
2223 * // => false |
|
2224 */ |
|
2225 function isBoolean(value) { |
|
2226 return value === true || value === false || |
|
2227 value && typeof value == 'object' && toString.call(value) == boolClass || false; |
|
2228 } |
|
2229 |
|
2230 /** |
|
2231 * Checks if `value` is a date. |
|
2232 * |
|
2233 * @static |
|
2234 * @memberOf _ |
|
2235 * @category Objects |
|
2236 * @param {*} value The value to check. |
|
2237 * @returns {boolean} Returns `true` if the `value` is a date, else `false`. |
|
2238 * @example |
|
2239 * |
|
2240 * _.isDate(new Date); |
|
2241 * // => true |
|
2242 */ |
|
2243 function isDate(value) { |
|
2244 return value && typeof value == 'object' && toString.call(value) == dateClass || false; |
|
2245 } |
|
2246 |
|
2247 /** |
|
2248 * Checks if `value` is a DOM element. |
|
2249 * |
|
2250 * @static |
|
2251 * @memberOf _ |
|
2252 * @category Objects |
|
2253 * @param {*} value The value to check. |
|
2254 * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. |
|
2255 * @example |
|
2256 * |
|
2257 * _.isElement(document.body); |
|
2258 * // => true |
|
2259 */ |
|
2260 function isElement(value) { |
|
2261 return value && value.nodeType === 1 || false; |
|
2262 } |
|
2263 |
|
2264 /** |
|
2265 * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a |
|
2266 * length of `0` and objects with no own enumerable properties are considered |
|
2267 * "empty". |
|
2268 * |
|
2269 * @static |
|
2270 * @memberOf _ |
|
2271 * @category Objects |
|
2272 * @param {Array|Object|string} value The value to inspect. |
|
2273 * @returns {boolean} Returns `true` if the `value` is empty, else `false`. |
|
2274 * @example |
|
2275 * |
|
2276 * _.isEmpty([1, 2, 3]); |
|
2277 * // => false |
|
2278 * |
|
2279 * _.isEmpty({}); |
|
2280 * // => true |
|
2281 * |
|
2282 * _.isEmpty(''); |
|
2283 * // => true |
|
2284 */ |
|
2285 function isEmpty(value) { |
|
2286 var result = true; |
|
2287 if (!value) { |
|
2288 return result; |
|
2289 } |
|
2290 var className = toString.call(value), |
|
2291 length = value.length; |
|
2292 |
|
2293 if ((className == arrayClass || className == stringClass || className == argsClass ) || |
|
2294 (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { |
|
2295 return !length; |
|
2296 } |
|
2297 forOwn(value, function() { |
|
2298 return (result = false); |
|
2299 }); |
|
2300 return result; |
|
2301 } |
|
2302 |
|
2303 /** |
|
2304 * Performs a deep comparison between two values to determine if they are |
|
2305 * equivalent to each other. If a callback is provided it will be executed |
|
2306 * to compare values. If the callback returns `undefined` comparisons will |
|
2307 * be handled by the method instead. The callback is bound to `thisArg` and |
|
2308 * invoked with two arguments; (a, b). |
|
2309 * |
|
2310 * @static |
|
2311 * @memberOf _ |
|
2312 * @category Objects |
|
2313 * @param {*} a The value to compare. |
|
2314 * @param {*} b The other value to compare. |
|
2315 * @param {Function} [callback] The function to customize comparing values. |
|
2316 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2317 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
2318 * @example |
|
2319 * |
|
2320 * var object = { 'name': 'fred' }; |
|
2321 * var copy = { 'name': 'fred' }; |
|
2322 * |
|
2323 * object == copy; |
|
2324 * // => false |
|
2325 * |
|
2326 * _.isEqual(object, copy); |
|
2327 * // => true |
|
2328 * |
|
2329 * var words = ['hello', 'goodbye']; |
|
2330 * var otherWords = ['hi', 'goodbye']; |
|
2331 * |
|
2332 * _.isEqual(words, otherWords, function(a, b) { |
|
2333 * var reGreet = /^(?:hello|hi)$/i, |
|
2334 * aGreet = _.isString(a) && reGreet.test(a), |
|
2335 * bGreet = _.isString(b) && reGreet.test(b); |
|
2336 * |
|
2337 * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; |
|
2338 * }); |
|
2339 * // => true |
|
2340 */ |
|
2341 function isEqual(a, b, callback, thisArg) { |
|
2342 return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); |
|
2343 } |
|
2344 |
|
2345 /** |
|
2346 * Checks if `value` is, or can be coerced to, a finite number. |
|
2347 * |
|
2348 * Note: This is not the same as native `isFinite` which will return true for |
|
2349 * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. |
|
2350 * |
|
2351 * @static |
|
2352 * @memberOf _ |
|
2353 * @category Objects |
|
2354 * @param {*} value The value to check. |
|
2355 * @returns {boolean} Returns `true` if the `value` is finite, else `false`. |
|
2356 * @example |
|
2357 * |
|
2358 * _.isFinite(-101); |
|
2359 * // => true |
|
2360 * |
|
2361 * _.isFinite('10'); |
|
2362 * // => true |
|
2363 * |
|
2364 * _.isFinite(true); |
|
2365 * // => false |
|
2366 * |
|
2367 * _.isFinite(''); |
|
2368 * // => false |
|
2369 * |
|
2370 * _.isFinite(Infinity); |
|
2371 * // => false |
|
2372 */ |
|
2373 function isFinite(value) { |
|
2374 return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); |
|
2375 } |
|
2376 |
|
2377 /** |
|
2378 * Checks if `value` is a function. |
|
2379 * |
|
2380 * @static |
|
2381 * @memberOf _ |
|
2382 * @category Objects |
|
2383 * @param {*} value The value to check. |
|
2384 * @returns {boolean} Returns `true` if the `value` is a function, else `false`. |
|
2385 * @example |
|
2386 * |
|
2387 * _.isFunction(_); |
|
2388 * // => true |
|
2389 */ |
|
2390 function isFunction(value) { |
|
2391 return typeof value == 'function'; |
|
2392 } |
|
2393 |
|
2394 /** |
|
2395 * Checks if `value` is the language type of Object. |
|
2396 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) |
|
2397 * |
|
2398 * @static |
|
2399 * @memberOf _ |
|
2400 * @category Objects |
|
2401 * @param {*} value The value to check. |
|
2402 * @returns {boolean} Returns `true` if the `value` is an object, else `false`. |
|
2403 * @example |
|
2404 * |
|
2405 * _.isObject({}); |
|
2406 * // => true |
|
2407 * |
|
2408 * _.isObject([1, 2, 3]); |
|
2409 * // => true |
|
2410 * |
|
2411 * _.isObject(1); |
|
2412 * // => false |
|
2413 */ |
|
2414 function isObject(value) { |
|
2415 // check if the value is the ECMAScript language type of Object |
|
2416 // http://es5.github.io/#x8 |
|
2417 // and avoid a V8 bug |
|
2418 // http://code.google.com/p/v8/issues/detail?id=2291 |
|
2419 return !!(value && objectTypes[typeof value]); |
|
2420 } |
|
2421 |
|
2422 /** |
|
2423 * Checks if `value` is `NaN`. |
|
2424 * |
|
2425 * Note: This is not the same as native `isNaN` which will return `true` for |
|
2426 * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. |
|
2427 * |
|
2428 * @static |
|
2429 * @memberOf _ |
|
2430 * @category Objects |
|
2431 * @param {*} value The value to check. |
|
2432 * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. |
|
2433 * @example |
|
2434 * |
|
2435 * _.isNaN(NaN); |
|
2436 * // => true |
|
2437 * |
|
2438 * _.isNaN(new Number(NaN)); |
|
2439 * // => true |
|
2440 * |
|
2441 * isNaN(undefined); |
|
2442 * // => true |
|
2443 * |
|
2444 * _.isNaN(undefined); |
|
2445 * // => false |
|
2446 */ |
|
2447 function isNaN(value) { |
|
2448 // `NaN` as a primitive is the only value that is not equal to itself |
|
2449 // (perform the [[Class]] check first to avoid errors with some host objects in IE) |
|
2450 return isNumber(value) && value != +value; |
|
2451 } |
|
2452 |
|
2453 /** |
|
2454 * Checks if `value` is `null`. |
|
2455 * |
|
2456 * @static |
|
2457 * @memberOf _ |
|
2458 * @category Objects |
|
2459 * @param {*} value The value to check. |
|
2460 * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. |
|
2461 * @example |
|
2462 * |
|
2463 * _.isNull(null); |
|
2464 * // => true |
|
2465 * |
|
2466 * _.isNull(undefined); |
|
2467 * // => false |
|
2468 */ |
|
2469 function isNull(value) { |
|
2470 return value === null; |
|
2471 } |
|
2472 |
|
2473 /** |
|
2474 * Checks if `value` is a number. |
|
2475 * |
|
2476 * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. |
|
2477 * |
|
2478 * @static |
|
2479 * @memberOf _ |
|
2480 * @category Objects |
|
2481 * @param {*} value The value to check. |
|
2482 * @returns {boolean} Returns `true` if the `value` is a number, else `false`. |
|
2483 * @example |
|
2484 * |
|
2485 * _.isNumber(8.4 * 5); |
|
2486 * // => true |
|
2487 */ |
|
2488 function isNumber(value) { |
|
2489 return typeof value == 'number' || |
|
2490 value && typeof value == 'object' && toString.call(value) == numberClass || false; |
|
2491 } |
|
2492 |
|
2493 /** |
|
2494 * Checks if `value` is an object created by the `Object` constructor. |
|
2495 * |
|
2496 * @static |
|
2497 * @memberOf _ |
|
2498 * @category Objects |
|
2499 * @param {*} value The value to check. |
|
2500 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
|
2501 * @example |
|
2502 * |
|
2503 * function Shape() { |
|
2504 * this.x = 0; |
|
2505 * this.y = 0; |
|
2506 * } |
|
2507 * |
|
2508 * _.isPlainObject(new Shape); |
|
2509 * // => false |
|
2510 * |
|
2511 * _.isPlainObject([1, 2, 3]); |
|
2512 * // => false |
|
2513 * |
|
2514 * _.isPlainObject({ 'x': 0, 'y': 0 }); |
|
2515 * // => true |
|
2516 */ |
|
2517 var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { |
|
2518 if (!(value && toString.call(value) == objectClass)) { |
|
2519 return false; |
|
2520 } |
|
2521 var valueOf = value.valueOf, |
|
2522 objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); |
|
2523 |
|
2524 return objProto |
|
2525 ? (value == objProto || getPrototypeOf(value) == objProto) |
|
2526 : shimIsPlainObject(value); |
|
2527 }; |
|
2528 |
|
2529 /** |
|
2530 * Checks if `value` is a regular expression. |
|
2531 * |
|
2532 * @static |
|
2533 * @memberOf _ |
|
2534 * @category Objects |
|
2535 * @param {*} value The value to check. |
|
2536 * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. |
|
2537 * @example |
|
2538 * |
|
2539 * _.isRegExp(/fred/); |
|
2540 * // => true |
|
2541 */ |
|
2542 function isRegExp(value) { |
|
2543 return value && typeof value == 'object' && toString.call(value) == regexpClass || false; |
|
2544 } |
|
2545 |
|
2546 /** |
|
2547 * Checks if `value` is a string. |
|
2548 * |
|
2549 * @static |
|
2550 * @memberOf _ |
|
2551 * @category Objects |
|
2552 * @param {*} value The value to check. |
|
2553 * @returns {boolean} Returns `true` if the `value` is a string, else `false`. |
|
2554 * @example |
|
2555 * |
|
2556 * _.isString('fred'); |
|
2557 * // => true |
|
2558 */ |
|
2559 function isString(value) { |
|
2560 return typeof value == 'string' || |
|
2561 value && typeof value == 'object' && toString.call(value) == stringClass || false; |
|
2562 } |
|
2563 |
|
2564 /** |
|
2565 * Checks if `value` is `undefined`. |
|
2566 * |
|
2567 * @static |
|
2568 * @memberOf _ |
|
2569 * @category Objects |
|
2570 * @param {*} value The value to check. |
|
2571 * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. |
|
2572 * @example |
|
2573 * |
|
2574 * _.isUndefined(void 0); |
|
2575 * // => true |
|
2576 */ |
|
2577 function isUndefined(value) { |
|
2578 return typeof value == 'undefined'; |
|
2579 } |
|
2580 |
|
2581 /** |
|
2582 * Creates an object with the same keys as `object` and values generated by |
|
2583 * running each own enumerable property of `object` through the callback. |
|
2584 * The callback is bound to `thisArg` and invoked with three arguments; |
|
2585 * (value, key, object). |
|
2586 * |
|
2587 * If a property name is provided for `callback` the created "_.pluck" style |
|
2588 * callback will return the property value of the given element. |
|
2589 * |
|
2590 * If an object is provided for `callback` the created "_.where" style callback |
|
2591 * will return `true` for elements that have the properties of the given object, |
|
2592 * else `false`. |
|
2593 * |
|
2594 * @static |
|
2595 * @memberOf _ |
|
2596 * @category Objects |
|
2597 * @param {Object} object The object to iterate over. |
|
2598 * @param {Function|Object|string} [callback=identity] The function called |
|
2599 * per iteration. If a property name or object is provided it will be used |
|
2600 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
2601 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2602 * @returns {Array} Returns a new object with values of the results of each `callback` execution. |
|
2603 * @example |
|
2604 * |
|
2605 * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); |
|
2606 * // => { 'a': 3, 'b': 6, 'c': 9 } |
|
2607 * |
|
2608 * var characters = { |
|
2609 * 'fred': { 'name': 'fred', 'age': 40 }, |
|
2610 * 'pebbles': { 'name': 'pebbles', 'age': 1 } |
|
2611 * }; |
|
2612 * |
|
2613 * // using "_.pluck" callback shorthand |
|
2614 * _.mapValues(characters, 'age'); |
|
2615 * // => { 'fred': 40, 'pebbles': 1 } |
|
2616 */ |
|
2617 function mapValues(object, callback, thisArg) { |
|
2618 var result = {}; |
|
2619 callback = lodash.createCallback(callback, thisArg, 3); |
|
2620 |
|
2621 forOwn(object, function(value, key, object) { |
|
2622 result[key] = callback(value, key, object); |
|
2623 }); |
|
2624 return result; |
|
2625 } |
|
2626 |
|
2627 /** |
|
2628 * Recursively merges own enumerable properties of the source object(s), that |
|
2629 * don't resolve to `undefined` into the destination object. Subsequent sources |
|
2630 * will overwrite property assignments of previous sources. If a callback is |
|
2631 * provided it will be executed to produce the merged values of the destination |
|
2632 * and source properties. If the callback returns `undefined` merging will |
|
2633 * be handled by the method instead. The callback is bound to `thisArg` and |
|
2634 * invoked with two arguments; (objectValue, sourceValue). |
|
2635 * |
|
2636 * @static |
|
2637 * @memberOf _ |
|
2638 * @category Objects |
|
2639 * @param {Object} object The destination object. |
|
2640 * @param {...Object} [source] The source objects. |
|
2641 * @param {Function} [callback] The function to customize merging properties. |
|
2642 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2643 * @returns {Object} Returns the destination object. |
|
2644 * @example |
|
2645 * |
|
2646 * var names = { |
|
2647 * 'characters': [ |
|
2648 * { 'name': 'barney' }, |
|
2649 * { 'name': 'fred' } |
|
2650 * ] |
|
2651 * }; |
|
2652 * |
|
2653 * var ages = { |
|
2654 * 'characters': [ |
|
2655 * { 'age': 36 }, |
|
2656 * { 'age': 40 } |
|
2657 * ] |
|
2658 * }; |
|
2659 * |
|
2660 * _.merge(names, ages); |
|
2661 * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } |
|
2662 * |
|
2663 * var food = { |
|
2664 * 'fruits': ['apple'], |
|
2665 * 'vegetables': ['beet'] |
|
2666 * }; |
|
2667 * |
|
2668 * var otherFood = { |
|
2669 * 'fruits': ['banana'], |
|
2670 * 'vegetables': ['carrot'] |
|
2671 * }; |
|
2672 * |
|
2673 * _.merge(food, otherFood, function(a, b) { |
|
2674 * return _.isArray(a) ? a.concat(b) : undefined; |
|
2675 * }); |
|
2676 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } |
|
2677 */ |
|
2678 function merge(object) { |
|
2679 var args = arguments, |
|
2680 length = 2; |
|
2681 |
|
2682 if (!isObject(object)) { |
|
2683 return object; |
|
2684 } |
|
2685 // allows working with `_.reduce` and `_.reduceRight` without using |
|
2686 // their `index` and `collection` arguments |
|
2687 if (typeof args[2] != 'number') { |
|
2688 length = args.length; |
|
2689 } |
|
2690 if (length > 3 && typeof args[length - 2] == 'function') { |
|
2691 var callback = baseCreateCallback(args[--length - 1], args[length--], 2); |
|
2692 } else if (length > 2 && typeof args[length - 1] == 'function') { |
|
2693 callback = args[--length]; |
|
2694 } |
|
2695 var sources = slice(arguments, 1, length), |
|
2696 index = -1, |
|
2697 stackA = getArray(), |
|
2698 stackB = getArray(); |
|
2699 |
|
2700 while (++index < length) { |
|
2701 baseMerge(object, sources[index], callback, stackA, stackB); |
|
2702 } |
|
2703 releaseArray(stackA); |
|
2704 releaseArray(stackB); |
|
2705 return object; |
|
2706 } |
|
2707 |
|
2708 /** |
|
2709 * Creates a shallow clone of `object` excluding the specified properties. |
|
2710 * Property names may be specified as individual arguments or as arrays of |
|
2711 * property names. If a callback is provided it will be executed for each |
|
2712 * property of `object` omitting the properties the callback returns truey |
|
2713 * for. The callback is bound to `thisArg` and invoked with three arguments; |
|
2714 * (value, key, object). |
|
2715 * |
|
2716 * @static |
|
2717 * @memberOf _ |
|
2718 * @category Objects |
|
2719 * @param {Object} object The source object. |
|
2720 * @param {Function|...string|string[]} [callback] The properties to omit or the |
|
2721 * function called per iteration. |
|
2722 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2723 * @returns {Object} Returns an object without the omitted properties. |
|
2724 * @example |
|
2725 * |
|
2726 * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); |
|
2727 * // => { 'name': 'fred' } |
|
2728 * |
|
2729 * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { |
|
2730 * return typeof value == 'number'; |
|
2731 * }); |
|
2732 * // => { 'name': 'fred' } |
|
2733 */ |
|
2734 function omit(object, callback, thisArg) { |
|
2735 var result = {}; |
|
2736 if (typeof callback != 'function') { |
|
2737 var props = []; |
|
2738 forIn(object, function(value, key) { |
|
2739 props.push(key); |
|
2740 }); |
|
2741 props = baseDifference(props, baseFlatten(arguments, true, false, 1)); |
|
2742 |
|
2743 var index = -1, |
|
2744 length = props.length; |
|
2745 |
|
2746 while (++index < length) { |
|
2747 var key = props[index]; |
|
2748 result[key] = object[key]; |
|
2749 } |
|
2750 } else { |
|
2751 callback = lodash.createCallback(callback, thisArg, 3); |
|
2752 forIn(object, function(value, key, object) { |
|
2753 if (!callback(value, key, object)) { |
|
2754 result[key] = value; |
|
2755 } |
|
2756 }); |
|
2757 } |
|
2758 return result; |
|
2759 } |
|
2760 |
|
2761 /** |
|
2762 * Creates a two dimensional array of an object's key-value pairs, |
|
2763 * i.e. `[[key1, value1], [key2, value2]]`. |
|
2764 * |
|
2765 * @static |
|
2766 * @memberOf _ |
|
2767 * @category Objects |
|
2768 * @param {Object} object The object to inspect. |
|
2769 * @returns {Array} Returns new array of key-value pairs. |
|
2770 * @example |
|
2771 * |
|
2772 * _.pairs({ 'barney': 36, 'fred': 40 }); |
|
2773 * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) |
|
2774 */ |
|
2775 function pairs(object) { |
|
2776 var index = -1, |
|
2777 props = keys(object), |
|
2778 length = props.length, |
|
2779 result = Array(length); |
|
2780 |
|
2781 while (++index < length) { |
|
2782 var key = props[index]; |
|
2783 result[index] = [key, object[key]]; |
|
2784 } |
|
2785 return result; |
|
2786 } |
|
2787 |
|
2788 /** |
|
2789 * Creates a shallow clone of `object` composed of the specified properties. |
|
2790 * Property names may be specified as individual arguments or as arrays of |
|
2791 * property names. If a callback is provided it will be executed for each |
|
2792 * property of `object` picking the properties the callback returns truey |
|
2793 * for. The callback is bound to `thisArg` and invoked with three arguments; |
|
2794 * (value, key, object). |
|
2795 * |
|
2796 * @static |
|
2797 * @memberOf _ |
|
2798 * @category Objects |
|
2799 * @param {Object} object The source object. |
|
2800 * @param {Function|...string|string[]} [callback] The function called per |
|
2801 * iteration or property names to pick, specified as individual property |
|
2802 * names or arrays of property names. |
|
2803 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2804 * @returns {Object} Returns an object composed of the picked properties. |
|
2805 * @example |
|
2806 * |
|
2807 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); |
|
2808 * // => { 'name': 'fred' } |
|
2809 * |
|
2810 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { |
|
2811 * return key.charAt(0) != '_'; |
|
2812 * }); |
|
2813 * // => { 'name': 'fred' } |
|
2814 */ |
|
2815 function pick(object, callback, thisArg) { |
|
2816 var result = {}; |
|
2817 if (typeof callback != 'function') { |
|
2818 var index = -1, |
|
2819 props = baseFlatten(arguments, true, false, 1), |
|
2820 length = isObject(object) ? props.length : 0; |
|
2821 |
|
2822 while (++index < length) { |
|
2823 var key = props[index]; |
|
2824 if (key in object) { |
|
2825 result[key] = object[key]; |
|
2826 } |
|
2827 } |
|
2828 } else { |
|
2829 callback = lodash.createCallback(callback, thisArg, 3); |
|
2830 forIn(object, function(value, key, object) { |
|
2831 if (callback(value, key, object)) { |
|
2832 result[key] = value; |
|
2833 } |
|
2834 }); |
|
2835 } |
|
2836 return result; |
|
2837 } |
|
2838 |
|
2839 /** |
|
2840 * An alternative to `_.reduce` this method transforms `object` to a new |
|
2841 * `accumulator` object which is the result of running each of its own |
|
2842 * enumerable properties through a callback, with each callback execution |
|
2843 * potentially mutating the `accumulator` object. The callback is bound to |
|
2844 * `thisArg` and invoked with four arguments; (accumulator, value, key, object). |
|
2845 * Callbacks may exit iteration early by explicitly returning `false`. |
|
2846 * |
|
2847 * @static |
|
2848 * @memberOf _ |
|
2849 * @category Objects |
|
2850 * @param {Array|Object} object The object to iterate over. |
|
2851 * @param {Function} [callback=identity] The function called per iteration. |
|
2852 * @param {*} [accumulator] The custom accumulator value. |
|
2853 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2854 * @returns {*} Returns the accumulated value. |
|
2855 * @example |
|
2856 * |
|
2857 * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { |
|
2858 * num *= num; |
|
2859 * if (num % 2) { |
|
2860 * return result.push(num) < 3; |
|
2861 * } |
|
2862 * }); |
|
2863 * // => [1, 9, 25] |
|
2864 * |
|
2865 * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { |
|
2866 * result[key] = num * 3; |
|
2867 * }); |
|
2868 * // => { 'a': 3, 'b': 6, 'c': 9 } |
|
2869 */ |
|
2870 function transform(object, callback, accumulator, thisArg) { |
|
2871 var isArr = isArray(object); |
|
2872 if (accumulator == null) { |
|
2873 if (isArr) { |
|
2874 accumulator = []; |
|
2875 } else { |
|
2876 var ctor = object && object.constructor, |
|
2877 proto = ctor && ctor.prototype; |
|
2878 |
|
2879 accumulator = baseCreate(proto); |
|
2880 } |
|
2881 } |
|
2882 if (callback) { |
|
2883 callback = lodash.createCallback(callback, thisArg, 4); |
|
2884 (isArr ? forEach : forOwn)(object, function(value, index, object) { |
|
2885 return callback(accumulator, value, index, object); |
|
2886 }); |
|
2887 } |
|
2888 return accumulator; |
|
2889 } |
|
2890 |
|
2891 /** |
|
2892 * Creates an array composed of the own enumerable property values of `object`. |
|
2893 * |
|
2894 * @static |
|
2895 * @memberOf _ |
|
2896 * @category Objects |
|
2897 * @param {Object} object The object to inspect. |
|
2898 * @returns {Array} Returns an array of property values. |
|
2899 * @example |
|
2900 * |
|
2901 * _.values({ 'one': 1, 'two': 2, 'three': 3 }); |
|
2902 * // => [1, 2, 3] (property order is not guaranteed across environments) |
|
2903 */ |
|
2904 function values(object) { |
|
2905 var index = -1, |
|
2906 props = keys(object), |
|
2907 length = props.length, |
|
2908 result = Array(length); |
|
2909 |
|
2910 while (++index < length) { |
|
2911 result[index] = object[props[index]]; |
|
2912 } |
|
2913 return result; |
|
2914 } |
|
2915 |
|
2916 /*--------------------------------------------------------------------------*/ |
|
2917 |
|
2918 /** |
|
2919 * Creates an array of elements from the specified indexes, or keys, of the |
|
2920 * `collection`. Indexes may be specified as individual arguments or as arrays |
|
2921 * of indexes. |
|
2922 * |
|
2923 * @static |
|
2924 * @memberOf _ |
|
2925 * @category Collections |
|
2926 * @param {Array|Object|string} collection The collection to iterate over. |
|
2927 * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` |
|
2928 * to retrieve, specified as individual indexes or arrays of indexes. |
|
2929 * @returns {Array} Returns a new array of elements corresponding to the |
|
2930 * provided indexes. |
|
2931 * @example |
|
2932 * |
|
2933 * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); |
|
2934 * // => ['a', 'c', 'e'] |
|
2935 * |
|
2936 * _.at(['fred', 'barney', 'pebbles'], 0, 2); |
|
2937 * // => ['fred', 'pebbles'] |
|
2938 */ |
|
2939 function at(collection) { |
|
2940 var args = arguments, |
|
2941 index = -1, |
|
2942 props = baseFlatten(args, true, false, 1), |
|
2943 length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, |
|
2944 result = Array(length); |
|
2945 |
|
2946 while(++index < length) { |
|
2947 result[index] = collection[props[index]]; |
|
2948 } |
|
2949 return result; |
|
2950 } |
|
2951 |
|
2952 /** |
|
2953 * Checks if a given value is present in a collection using strict equality |
|
2954 * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the |
|
2955 * offset from the end of the collection. |
|
2956 * |
|
2957 * @static |
|
2958 * @memberOf _ |
|
2959 * @alias include |
|
2960 * @category Collections |
|
2961 * @param {Array|Object|string} collection The collection to iterate over. |
|
2962 * @param {*} target The value to check for. |
|
2963 * @param {number} [fromIndex=0] The index to search from. |
|
2964 * @returns {boolean} Returns `true` if the `target` element is found, else `false`. |
|
2965 * @example |
|
2966 * |
|
2967 * _.contains([1, 2, 3], 1); |
|
2968 * // => true |
|
2969 * |
|
2970 * _.contains([1, 2, 3], 1, 2); |
|
2971 * // => false |
|
2972 * |
|
2973 * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); |
|
2974 * // => true |
|
2975 * |
|
2976 * _.contains('pebbles', 'eb'); |
|
2977 * // => true |
|
2978 */ |
|
2979 function contains(collection, target, fromIndex) { |
|
2980 var index = -1, |
|
2981 indexOf = getIndexOf(), |
|
2982 length = collection ? collection.length : 0, |
|
2983 result = false; |
|
2984 |
|
2985 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; |
|
2986 if (isArray(collection)) { |
|
2987 result = indexOf(collection, target, fromIndex) > -1; |
|
2988 } else if (typeof length == 'number') { |
|
2989 result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; |
|
2990 } else { |
|
2991 forOwn(collection, function(value) { |
|
2992 if (++index >= fromIndex) { |
|
2993 return !(result = value === target); |
|
2994 } |
|
2995 }); |
|
2996 } |
|
2997 return result; |
|
2998 } |
|
2999 |
|
3000 /** |
|
3001 * Creates an object composed of keys generated from the results of running |
|
3002 * each element of `collection` through the callback. The corresponding value |
|
3003 * of each key is the number of times the key was returned by the callback. |
|
3004 * The callback is bound to `thisArg` and invoked with three arguments; |
|
3005 * (value, index|key, collection). |
|
3006 * |
|
3007 * If a property name is provided for `callback` the created "_.pluck" style |
|
3008 * callback will return the property value of the given element. |
|
3009 * |
|
3010 * If an object is provided for `callback` the created "_.where" style callback |
|
3011 * will return `true` for elements that have the properties of the given object, |
|
3012 * else `false`. |
|
3013 * |
|
3014 * @static |
|
3015 * @memberOf _ |
|
3016 * @category Collections |
|
3017 * @param {Array|Object|string} collection The collection to iterate over. |
|
3018 * @param {Function|Object|string} [callback=identity] The function called |
|
3019 * per iteration. If a property name or object is provided it will be used |
|
3020 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3021 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3022 * @returns {Object} Returns the composed aggregate object. |
|
3023 * @example |
|
3024 * |
|
3025 * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); |
|
3026 * // => { '4': 1, '6': 2 } |
|
3027 * |
|
3028 * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); |
|
3029 * // => { '4': 1, '6': 2 } |
|
3030 * |
|
3031 * _.countBy(['one', 'two', 'three'], 'length'); |
|
3032 * // => { '3': 2, '5': 1 } |
|
3033 */ |
|
3034 var countBy = createAggregator(function(result, value, key) { |
|
3035 (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); |
|
3036 }); |
|
3037 |
|
3038 /** |
|
3039 * Checks if the given callback returns truey value for **all** elements of |
|
3040 * a collection. The callback is bound to `thisArg` and invoked with three |
|
3041 * arguments; (value, index|key, collection). |
|
3042 * |
|
3043 * If a property name is provided for `callback` the created "_.pluck" style |
|
3044 * callback will return the property value of the given element. |
|
3045 * |
|
3046 * If an object is provided for `callback` the created "_.where" style callback |
|
3047 * will return `true` for elements that have the properties of the given object, |
|
3048 * else `false`. |
|
3049 * |
|
3050 * @static |
|
3051 * @memberOf _ |
|
3052 * @alias all |
|
3053 * @category Collections |
|
3054 * @param {Array|Object|string} collection The collection to iterate over. |
|
3055 * @param {Function|Object|string} [callback=identity] The function called |
|
3056 * per iteration. If a property name or object is provided it will be used |
|
3057 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3058 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3059 * @returns {boolean} Returns `true` if all elements passed the callback check, |
|
3060 * else `false`. |
|
3061 * @example |
|
3062 * |
|
3063 * _.every([true, 1, null, 'yes']); |
|
3064 * // => false |
|
3065 * |
|
3066 * var characters = [ |
|
3067 * { 'name': 'barney', 'age': 36 }, |
|
3068 * { 'name': 'fred', 'age': 40 } |
|
3069 * ]; |
|
3070 * |
|
3071 * // using "_.pluck" callback shorthand |
|
3072 * _.every(characters, 'age'); |
|
3073 * // => true |
|
3074 * |
|
3075 * // using "_.where" callback shorthand |
|
3076 * _.every(characters, { 'age': 36 }); |
|
3077 * // => false |
|
3078 */ |
|
3079 function every(collection, callback, thisArg) { |
|
3080 var result = true; |
|
3081 callback = lodash.createCallback(callback, thisArg, 3); |
|
3082 |
|
3083 var index = -1, |
|
3084 length = collection ? collection.length : 0; |
|
3085 |
|
3086 if (typeof length == 'number') { |
|
3087 while (++index < length) { |
|
3088 if (!(result = !!callback(collection[index], index, collection))) { |
|
3089 break; |
|
3090 } |
|
3091 } |
|
3092 } else { |
|
3093 forOwn(collection, function(value, index, collection) { |
|
3094 return (result = !!callback(value, index, collection)); |
|
3095 }); |
|
3096 } |
|
3097 return result; |
|
3098 } |
|
3099 |
|
3100 /** |
|
3101 * Iterates over elements of a collection, returning an array of all elements |
|
3102 * the callback returns truey for. The callback is bound to `thisArg` and |
|
3103 * invoked with three arguments; (value, index|key, collection). |
|
3104 * |
|
3105 * If a property name is provided for `callback` the created "_.pluck" style |
|
3106 * callback will return the property value of the given element. |
|
3107 * |
|
3108 * If an object is provided for `callback` the created "_.where" style callback |
|
3109 * will return `true` for elements that have the properties of the given object, |
|
3110 * else `false`. |
|
3111 * |
|
3112 * @static |
|
3113 * @memberOf _ |
|
3114 * @alias select |
|
3115 * @category Collections |
|
3116 * @param {Array|Object|string} collection The collection to iterate over. |
|
3117 * @param {Function|Object|string} [callback=identity] The function called |
|
3118 * per iteration. If a property name or object is provided it will be used |
|
3119 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3120 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3121 * @returns {Array} Returns a new array of elements that passed the callback check. |
|
3122 * @example |
|
3123 * |
|
3124 * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); |
|
3125 * // => [2, 4, 6] |
|
3126 * |
|
3127 * var characters = [ |
|
3128 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
3129 * { 'name': 'fred', 'age': 40, 'blocked': true } |
|
3130 * ]; |
|
3131 * |
|
3132 * // using "_.pluck" callback shorthand |
|
3133 * _.filter(characters, 'blocked'); |
|
3134 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] |
|
3135 * |
|
3136 * // using "_.where" callback shorthand |
|
3137 * _.filter(characters, { 'age': 36 }); |
|
3138 * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] |
|
3139 */ |
|
3140 function filter(collection, callback, thisArg) { |
|
3141 var result = []; |
|
3142 callback = lodash.createCallback(callback, thisArg, 3); |
|
3143 |
|
3144 var index = -1, |
|
3145 length = collection ? collection.length : 0; |
|
3146 |
|
3147 if (typeof length == 'number') { |
|
3148 while (++index < length) { |
|
3149 var value = collection[index]; |
|
3150 if (callback(value, index, collection)) { |
|
3151 result.push(value); |
|
3152 } |
|
3153 } |
|
3154 } else { |
|
3155 forOwn(collection, function(value, index, collection) { |
|
3156 if (callback(value, index, collection)) { |
|
3157 result.push(value); |
|
3158 } |
|
3159 }); |
|
3160 } |
|
3161 return result; |
|
3162 } |
|
3163 |
|
3164 /** |
|
3165 * Iterates over elements of a collection, returning the first element that |
|
3166 * the callback returns truey for. The callback is bound to `thisArg` and |
|
3167 * invoked with three arguments; (value, index|key, collection). |
|
3168 * |
|
3169 * If a property name is provided for `callback` the created "_.pluck" style |
|
3170 * callback will return the property value of the given element. |
|
3171 * |
|
3172 * If an object is provided for `callback` the created "_.where" style callback |
|
3173 * will return `true` for elements that have the properties of the given object, |
|
3174 * else `false`. |
|
3175 * |
|
3176 * @static |
|
3177 * @memberOf _ |
|
3178 * @alias detect, findWhere |
|
3179 * @category Collections |
|
3180 * @param {Array|Object|string} collection The collection to iterate over. |
|
3181 * @param {Function|Object|string} [callback=identity] The function called |
|
3182 * per iteration. If a property name or object is provided it will be used |
|
3183 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3184 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3185 * @returns {*} Returns the found element, else `undefined`. |
|
3186 * @example |
|
3187 * |
|
3188 * var characters = [ |
|
3189 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
3190 * { 'name': 'fred', 'age': 40, 'blocked': true }, |
|
3191 * { 'name': 'pebbles', 'age': 1, 'blocked': false } |
|
3192 * ]; |
|
3193 * |
|
3194 * _.find(characters, function(chr) { |
|
3195 * return chr.age < 40; |
|
3196 * }); |
|
3197 * // => { 'name': 'barney', 'age': 36, 'blocked': false } |
|
3198 * |
|
3199 * // using "_.where" callback shorthand |
|
3200 * _.find(characters, { 'age': 1 }); |
|
3201 * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } |
|
3202 * |
|
3203 * // using "_.pluck" callback shorthand |
|
3204 * _.find(characters, 'blocked'); |
|
3205 * // => { 'name': 'fred', 'age': 40, 'blocked': true } |
|
3206 */ |
|
3207 function find(collection, callback, thisArg) { |
|
3208 callback = lodash.createCallback(callback, thisArg, 3); |
|
3209 |
|
3210 var index = -1, |
|
3211 length = collection ? collection.length : 0; |
|
3212 |
|
3213 if (typeof length == 'number') { |
|
3214 while (++index < length) { |
|
3215 var value = collection[index]; |
|
3216 if (callback(value, index, collection)) { |
|
3217 return value; |
|
3218 } |
|
3219 } |
|
3220 } else { |
|
3221 var result; |
|
3222 forOwn(collection, function(value, index, collection) { |
|
3223 if (callback(value, index, collection)) { |
|
3224 result = value; |
|
3225 return false; |
|
3226 } |
|
3227 }); |
|
3228 return result; |
|
3229 } |
|
3230 } |
|
3231 |
|
3232 /** |
|
3233 * This method is like `_.find` except that it iterates over elements |
|
3234 * of a `collection` from right to left. |
|
3235 * |
|
3236 * @static |
|
3237 * @memberOf _ |
|
3238 * @category Collections |
|
3239 * @param {Array|Object|string} collection The collection to iterate over. |
|
3240 * @param {Function|Object|string} [callback=identity] The function called |
|
3241 * per iteration. If a property name or object is provided it will be used |
|
3242 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3243 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3244 * @returns {*} Returns the found element, else `undefined`. |
|
3245 * @example |
|
3246 * |
|
3247 * _.findLast([1, 2, 3, 4], function(num) { |
|
3248 * return num % 2 == 1; |
|
3249 * }); |
|
3250 * // => 3 |
|
3251 */ |
|
3252 function findLast(collection, callback, thisArg) { |
|
3253 var result; |
|
3254 callback = lodash.createCallback(callback, thisArg, 3); |
|
3255 forEachRight(collection, function(value, index, collection) { |
|
3256 if (callback(value, index, collection)) { |
|
3257 result = value; |
|
3258 return false; |
|
3259 } |
|
3260 }); |
|
3261 return result; |
|
3262 } |
|
3263 |
|
3264 /** |
|
3265 * Iterates over elements of a collection, executing the callback for each |
|
3266 * element. The callback is bound to `thisArg` and invoked with three arguments; |
|
3267 * (value, index|key, collection). Callbacks may exit iteration early by |
|
3268 * explicitly returning `false`. |
|
3269 * |
|
3270 * Note: As with other "Collections" methods, objects with a `length` property |
|
3271 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` |
|
3272 * may be used for object iteration. |
|
3273 * |
|
3274 * @static |
|
3275 * @memberOf _ |
|
3276 * @alias each |
|
3277 * @category Collections |
|
3278 * @param {Array|Object|string} collection The collection to iterate over. |
|
3279 * @param {Function} [callback=identity] The function called per iteration. |
|
3280 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3281 * @returns {Array|Object|string} Returns `collection`. |
|
3282 * @example |
|
3283 * |
|
3284 * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); |
|
3285 * // => logs each number and returns '1,2,3' |
|
3286 * |
|
3287 * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); |
|
3288 * // => logs each number and returns the object (property order is not guaranteed across environments) |
|
3289 */ |
|
3290 function forEach(collection, callback, thisArg) { |
|
3291 var index = -1, |
|
3292 length = collection ? collection.length : 0; |
|
3293 |
|
3294 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); |
|
3295 if (typeof length == 'number') { |
|
3296 while (++index < length) { |
|
3297 if (callback(collection[index], index, collection) === false) { |
|
3298 break; |
|
3299 } |
|
3300 } |
|
3301 } else { |
|
3302 forOwn(collection, callback); |
|
3303 } |
|
3304 return collection; |
|
3305 } |
|
3306 |
|
3307 /** |
|
3308 * This method is like `_.forEach` except that it iterates over elements |
|
3309 * of a `collection` from right to left. |
|
3310 * |
|
3311 * @static |
|
3312 * @memberOf _ |
|
3313 * @alias eachRight |
|
3314 * @category Collections |
|
3315 * @param {Array|Object|string} collection The collection to iterate over. |
|
3316 * @param {Function} [callback=identity] The function called per iteration. |
|
3317 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3318 * @returns {Array|Object|string} Returns `collection`. |
|
3319 * @example |
|
3320 * |
|
3321 * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); |
|
3322 * // => logs each number from right to left and returns '3,2,1' |
|
3323 */ |
|
3324 function forEachRight(collection, callback, thisArg) { |
|
3325 var length = collection ? collection.length : 0; |
|
3326 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); |
|
3327 if (typeof length == 'number') { |
|
3328 while (length--) { |
|
3329 if (callback(collection[length], length, collection) === false) { |
|
3330 break; |
|
3331 } |
|
3332 } |
|
3333 } else { |
|
3334 var props = keys(collection); |
|
3335 length = props.length; |
|
3336 forOwn(collection, function(value, key, collection) { |
|
3337 key = props ? props[--length] : --length; |
|
3338 return callback(collection[key], key, collection); |
|
3339 }); |
|
3340 } |
|
3341 return collection; |
|
3342 } |
|
3343 |
|
3344 /** |
|
3345 * Creates an object composed of keys generated from the results of running |
|
3346 * each element of a collection through the callback. The corresponding value |
|
3347 * of each key is an array of the elements responsible for generating the key. |
|
3348 * The callback is bound to `thisArg` and invoked with three arguments; |
|
3349 * (value, index|key, collection). |
|
3350 * |
|
3351 * If a property name is provided for `callback` the created "_.pluck" style |
|
3352 * callback will return the property value of the given element. |
|
3353 * |
|
3354 * If an object is provided for `callback` the created "_.where" style callback |
|
3355 * will return `true` for elements that have the properties of the given object, |
|
3356 * else `false` |
|
3357 * |
|
3358 * @static |
|
3359 * @memberOf _ |
|
3360 * @category Collections |
|
3361 * @param {Array|Object|string} collection The collection to iterate over. |
|
3362 * @param {Function|Object|string} [callback=identity] The function called |
|
3363 * per iteration. If a property name or object is provided it will be used |
|
3364 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3365 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3366 * @returns {Object} Returns the composed aggregate object. |
|
3367 * @example |
|
3368 * |
|
3369 * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); |
|
3370 * // => { '4': [4.2], '6': [6.1, 6.4] } |
|
3371 * |
|
3372 * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); |
|
3373 * // => { '4': [4.2], '6': [6.1, 6.4] } |
|
3374 * |
|
3375 * // using "_.pluck" callback shorthand |
|
3376 * _.groupBy(['one', 'two', 'three'], 'length'); |
|
3377 * // => { '3': ['one', 'two'], '5': ['three'] } |
|
3378 */ |
|
3379 var groupBy = createAggregator(function(result, value, key) { |
|
3380 (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); |
|
3381 }); |
|
3382 |
|
3383 /** |
|
3384 * Creates an object composed of keys generated from the results of running |
|
3385 * each element of the collection through the given callback. The corresponding |
|
3386 * value of each key is the last element responsible for generating the key. |
|
3387 * The callback is bound to `thisArg` and invoked with three arguments; |
|
3388 * (value, index|key, collection). |
|
3389 * |
|
3390 * If a property name is provided for `callback` the created "_.pluck" style |
|
3391 * callback will return the property value of the given element. |
|
3392 * |
|
3393 * If an object is provided for `callback` the created "_.where" style callback |
|
3394 * will return `true` for elements that have the properties of the given object, |
|
3395 * else `false`. |
|
3396 * |
|
3397 * @static |
|
3398 * @memberOf _ |
|
3399 * @category Collections |
|
3400 * @param {Array|Object|string} collection The collection to iterate over. |
|
3401 * @param {Function|Object|string} [callback=identity] The function called |
|
3402 * per iteration. If a property name or object is provided it will be used |
|
3403 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3404 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3405 * @returns {Object} Returns the composed aggregate object. |
|
3406 * @example |
|
3407 * |
|
3408 * var keys = [ |
|
3409 * { 'dir': 'left', 'code': 97 }, |
|
3410 * { 'dir': 'right', 'code': 100 } |
|
3411 * ]; |
|
3412 * |
|
3413 * _.indexBy(keys, 'dir'); |
|
3414 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } |
|
3415 * |
|
3416 * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); |
|
3417 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
|
3418 * |
|
3419 * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); |
|
3420 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
|
3421 */ |
|
3422 var indexBy = createAggregator(function(result, value, key) { |
|
3423 result[key] = value; |
|
3424 }); |
|
3425 |
|
3426 /** |
|
3427 * Invokes the method named by `methodName` on each element in the `collection` |
|
3428 * returning an array of the results of each invoked method. Additional arguments |
|
3429 * will be provided to each invoked method. If `methodName` is a function it |
|
3430 * will be invoked for, and `this` bound to, each element in the `collection`. |
|
3431 * |
|
3432 * @static |
|
3433 * @memberOf _ |
|
3434 * @category Collections |
|
3435 * @param {Array|Object|string} collection The collection to iterate over. |
|
3436 * @param {Function|string} methodName The name of the method to invoke or |
|
3437 * the function invoked per iteration. |
|
3438 * @param {...*} [arg] Arguments to invoke the method with. |
|
3439 * @returns {Array} Returns a new array of the results of each invoked method. |
|
3440 * @example |
|
3441 * |
|
3442 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); |
|
3443 * // => [[1, 5, 7], [1, 2, 3]] |
|
3444 * |
|
3445 * _.invoke([123, 456], String.prototype.split, ''); |
|
3446 * // => [['1', '2', '3'], ['4', '5', '6']] |
|
3447 */ |
|
3448 function invoke(collection, methodName) { |
|
3449 var args = slice(arguments, 2), |
|
3450 index = -1, |
|
3451 isFunc = typeof methodName == 'function', |
|
3452 length = collection ? collection.length : 0, |
|
3453 result = Array(typeof length == 'number' ? length : 0); |
|
3454 |
|
3455 forEach(collection, function(value) { |
|
3456 result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); |
|
3457 }); |
|
3458 return result; |
|
3459 } |
|
3460 |
|
3461 /** |
|
3462 * Creates an array of values by running each element in the collection |
|
3463 * through the callback. The callback is bound to `thisArg` and invoked with |
|
3464 * three arguments; (value, index|key, collection). |
|
3465 * |
|
3466 * If a property name is provided for `callback` the created "_.pluck" style |
|
3467 * callback will return the property value of the given element. |
|
3468 * |
|
3469 * If an object is provided for `callback` the created "_.where" style callback |
|
3470 * will return `true` for elements that have the properties of the given object, |
|
3471 * else `false`. |
|
3472 * |
|
3473 * @static |
|
3474 * @memberOf _ |
|
3475 * @alias collect |
|
3476 * @category Collections |
|
3477 * @param {Array|Object|string} collection The collection to iterate over. |
|
3478 * @param {Function|Object|string} [callback=identity] The function called |
|
3479 * per iteration. If a property name or object is provided it will be used |
|
3480 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3481 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3482 * @returns {Array} Returns a new array of the results of each `callback` execution. |
|
3483 * @example |
|
3484 * |
|
3485 * _.map([1, 2, 3], function(num) { return num * 3; }); |
|
3486 * // => [3, 6, 9] |
|
3487 * |
|
3488 * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); |
|
3489 * // => [3, 6, 9] (property order is not guaranteed across environments) |
|
3490 * |
|
3491 * var characters = [ |
|
3492 * { 'name': 'barney', 'age': 36 }, |
|
3493 * { 'name': 'fred', 'age': 40 } |
|
3494 * ]; |
|
3495 * |
|
3496 * // using "_.pluck" callback shorthand |
|
3497 * _.map(characters, 'name'); |
|
3498 * // => ['barney', 'fred'] |
|
3499 */ |
|
3500 function map(collection, callback, thisArg) { |
|
3501 var index = -1, |
|
3502 length = collection ? collection.length : 0; |
|
3503 |
|
3504 callback = lodash.createCallback(callback, thisArg, 3); |
|
3505 if (typeof length == 'number') { |
|
3506 var result = Array(length); |
|
3507 while (++index < length) { |
|
3508 result[index] = callback(collection[index], index, collection); |
|
3509 } |
|
3510 } else { |
|
3511 result = []; |
|
3512 forOwn(collection, function(value, key, collection) { |
|
3513 result[++index] = callback(value, key, collection); |
|
3514 }); |
|
3515 } |
|
3516 return result; |
|
3517 } |
|
3518 |
|
3519 /** |
|
3520 * Retrieves the maximum value of a collection. If the collection is empty or |
|
3521 * falsey `-Infinity` is returned. If a callback is provided it will be executed |
|
3522 * for each value in the collection to generate the criterion by which the value |
|
3523 * is ranked. The callback is bound to `thisArg` and invoked with three |
|
3524 * arguments; (value, index, collection). |
|
3525 * |
|
3526 * If a property name is provided for `callback` the created "_.pluck" style |
|
3527 * callback will return the property value of the given element. |
|
3528 * |
|
3529 * If an object is provided for `callback` the created "_.where" style callback |
|
3530 * will return `true` for elements that have the properties of the given object, |
|
3531 * else `false`. |
|
3532 * |
|
3533 * @static |
|
3534 * @memberOf _ |
|
3535 * @category Collections |
|
3536 * @param {Array|Object|string} collection The collection to iterate over. |
|
3537 * @param {Function|Object|string} [callback=identity] The function called |
|
3538 * per iteration. If a property name or object is provided it will be used |
|
3539 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3540 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3541 * @returns {*} Returns the maximum value. |
|
3542 * @example |
|
3543 * |
|
3544 * _.max([4, 2, 8, 6]); |
|
3545 * // => 8 |
|
3546 * |
|
3547 * var characters = [ |
|
3548 * { 'name': 'barney', 'age': 36 }, |
|
3549 * { 'name': 'fred', 'age': 40 } |
|
3550 * ]; |
|
3551 * |
|
3552 * _.max(characters, function(chr) { return chr.age; }); |
|
3553 * // => { 'name': 'fred', 'age': 40 }; |
|
3554 * |
|
3555 * // using "_.pluck" callback shorthand |
|
3556 * _.max(characters, 'age'); |
|
3557 * // => { 'name': 'fred', 'age': 40 }; |
|
3558 */ |
|
3559 function max(collection, callback, thisArg) { |
|
3560 var computed = -Infinity, |
|
3561 result = computed; |
|
3562 |
|
3563 // allows working with functions like `_.map` without using |
|
3564 // their `index` argument as a callback |
|
3565 if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { |
|
3566 callback = null; |
|
3567 } |
|
3568 if (callback == null && isArray(collection)) { |
|
3569 var index = -1, |
|
3570 length = collection.length; |
|
3571 |
|
3572 while (++index < length) { |
|
3573 var value = collection[index]; |
|
3574 if (value > result) { |
|
3575 result = value; |
|
3576 } |
|
3577 } |
|
3578 } else { |
|
3579 callback = (callback == null && isString(collection)) |
|
3580 ? charAtCallback |
|
3581 : lodash.createCallback(callback, thisArg, 3); |
|
3582 |
|
3583 forEach(collection, function(value, index, collection) { |
|
3584 var current = callback(value, index, collection); |
|
3585 if (current > computed) { |
|
3586 computed = current; |
|
3587 result = value; |
|
3588 } |
|
3589 }); |
|
3590 } |
|
3591 return result; |
|
3592 } |
|
3593 |
|
3594 /** |
|
3595 * Retrieves the minimum value of a collection. If the collection is empty or |
|
3596 * falsey `Infinity` is returned. If a callback is provided it will be executed |
|
3597 * for each value in the collection to generate the criterion by which the value |
|
3598 * is ranked. The callback is bound to `thisArg` and invoked with three |
|
3599 * arguments; (value, index, collection). |
|
3600 * |
|
3601 * If a property name is provided for `callback` the created "_.pluck" style |
|
3602 * callback will return the property value of the given element. |
|
3603 * |
|
3604 * If an object is provided for `callback` the created "_.where" style callback |
|
3605 * will return `true` for elements that have the properties of the given object, |
|
3606 * else `false`. |
|
3607 * |
|
3608 * @static |
|
3609 * @memberOf _ |
|
3610 * @category Collections |
|
3611 * @param {Array|Object|string} collection The collection to iterate over. |
|
3612 * @param {Function|Object|string} [callback=identity] The function called |
|
3613 * per iteration. If a property name or object is provided it will be used |
|
3614 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3615 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3616 * @returns {*} Returns the minimum value. |
|
3617 * @example |
|
3618 * |
|
3619 * _.min([4, 2, 8, 6]); |
|
3620 * // => 2 |
|
3621 * |
|
3622 * var characters = [ |
|
3623 * { 'name': 'barney', 'age': 36 }, |
|
3624 * { 'name': 'fred', 'age': 40 } |
|
3625 * ]; |
|
3626 * |
|
3627 * _.min(characters, function(chr) { return chr.age; }); |
|
3628 * // => { 'name': 'barney', 'age': 36 }; |
|
3629 * |
|
3630 * // using "_.pluck" callback shorthand |
|
3631 * _.min(characters, 'age'); |
|
3632 * // => { 'name': 'barney', 'age': 36 }; |
|
3633 */ |
|
3634 function min(collection, callback, thisArg) { |
|
3635 var computed = Infinity, |
|
3636 result = computed; |
|
3637 |
|
3638 // allows working with functions like `_.map` without using |
|
3639 // their `index` argument as a callback |
|
3640 if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { |
|
3641 callback = null; |
|
3642 } |
|
3643 if (callback == null && isArray(collection)) { |
|
3644 var index = -1, |
|
3645 length = collection.length; |
|
3646 |
|
3647 while (++index < length) { |
|
3648 var value = collection[index]; |
|
3649 if (value < result) { |
|
3650 result = value; |
|
3651 } |
|
3652 } |
|
3653 } else { |
|
3654 callback = (callback == null && isString(collection)) |
|
3655 ? charAtCallback |
|
3656 : lodash.createCallback(callback, thisArg, 3); |
|
3657 |
|
3658 forEach(collection, function(value, index, collection) { |
|
3659 var current = callback(value, index, collection); |
|
3660 if (current < computed) { |
|
3661 computed = current; |
|
3662 result = value; |
|
3663 } |
|
3664 }); |
|
3665 } |
|
3666 return result; |
|
3667 } |
|
3668 |
|
3669 /** |
|
3670 * Retrieves the value of a specified property from all elements in the collection. |
|
3671 * |
|
3672 * @static |
|
3673 * @memberOf _ |
|
3674 * @type Function |
|
3675 * @category Collections |
|
3676 * @param {Array|Object|string} collection The collection to iterate over. |
|
3677 * @param {string} property The name of the property to pluck. |
|
3678 * @returns {Array} Returns a new array of property values. |
|
3679 * @example |
|
3680 * |
|
3681 * var characters = [ |
|
3682 * { 'name': 'barney', 'age': 36 }, |
|
3683 * { 'name': 'fred', 'age': 40 } |
|
3684 * ]; |
|
3685 * |
|
3686 * _.pluck(characters, 'name'); |
|
3687 * // => ['barney', 'fred'] |
|
3688 */ |
|
3689 var pluck = map; |
|
3690 |
|
3691 /** |
|
3692 * Reduces a collection to a value which is the accumulated result of running |
|
3693 * each element in the collection through the callback, where each successive |
|
3694 * callback execution consumes the return value of the previous execution. If |
|
3695 * `accumulator` is not provided the first element of the collection will be |
|
3696 * used as the initial `accumulator` value. The callback is bound to `thisArg` |
|
3697 * and invoked with four arguments; (accumulator, value, index|key, collection). |
|
3698 * |
|
3699 * @static |
|
3700 * @memberOf _ |
|
3701 * @alias foldl, inject |
|
3702 * @category Collections |
|
3703 * @param {Array|Object|string} collection The collection to iterate over. |
|
3704 * @param {Function} [callback=identity] The function called per iteration. |
|
3705 * @param {*} [accumulator] Initial value of the accumulator. |
|
3706 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3707 * @returns {*} Returns the accumulated value. |
|
3708 * @example |
|
3709 * |
|
3710 * var sum = _.reduce([1, 2, 3], function(sum, num) { |
|
3711 * return sum + num; |
|
3712 * }); |
|
3713 * // => 6 |
|
3714 * |
|
3715 * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { |
|
3716 * result[key] = num * 3; |
|
3717 * return result; |
|
3718 * }, {}); |
|
3719 * // => { 'a': 3, 'b': 6, 'c': 9 } |
|
3720 */ |
|
3721 function reduce(collection, callback, accumulator, thisArg) { |
|
3722 if (!collection) return accumulator; |
|
3723 var noaccum = arguments.length < 3; |
|
3724 callback = lodash.createCallback(callback, thisArg, 4); |
|
3725 |
|
3726 var index = -1, |
|
3727 length = collection.length; |
|
3728 |
|
3729 if (typeof length == 'number') { |
|
3730 if (noaccum) { |
|
3731 accumulator = collection[++index]; |
|
3732 } |
|
3733 while (++index < length) { |
|
3734 accumulator = callback(accumulator, collection[index], index, collection); |
|
3735 } |
|
3736 } else { |
|
3737 forOwn(collection, function(value, index, collection) { |
|
3738 accumulator = noaccum |
|
3739 ? (noaccum = false, value) |
|
3740 : callback(accumulator, value, index, collection) |
|
3741 }); |
|
3742 } |
|
3743 return accumulator; |
|
3744 } |
|
3745 |
|
3746 /** |
|
3747 * This method is like `_.reduce` except that it iterates over elements |
|
3748 * of a `collection` from right to left. |
|
3749 * |
|
3750 * @static |
|
3751 * @memberOf _ |
|
3752 * @alias foldr |
|
3753 * @category Collections |
|
3754 * @param {Array|Object|string} collection The collection to iterate over. |
|
3755 * @param {Function} [callback=identity] The function called per iteration. |
|
3756 * @param {*} [accumulator] Initial value of the accumulator. |
|
3757 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3758 * @returns {*} Returns the accumulated value. |
|
3759 * @example |
|
3760 * |
|
3761 * var list = [[0, 1], [2, 3], [4, 5]]; |
|
3762 * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); |
|
3763 * // => [4, 5, 2, 3, 0, 1] |
|
3764 */ |
|
3765 function reduceRight(collection, callback, accumulator, thisArg) { |
|
3766 var noaccum = arguments.length < 3; |
|
3767 callback = lodash.createCallback(callback, thisArg, 4); |
|
3768 forEachRight(collection, function(value, index, collection) { |
|
3769 accumulator = noaccum |
|
3770 ? (noaccum = false, value) |
|
3771 : callback(accumulator, value, index, collection); |
|
3772 }); |
|
3773 return accumulator; |
|
3774 } |
|
3775 |
|
3776 /** |
|
3777 * The opposite of `_.filter` this method returns the elements of a |
|
3778 * collection that the callback does **not** return truey for. |
|
3779 * |
|
3780 * If a property name is provided for `callback` the created "_.pluck" style |
|
3781 * callback will return the property value of the given element. |
|
3782 * |
|
3783 * If an object is provided for `callback` the created "_.where" style callback |
|
3784 * will return `true` for elements that have the properties of the given object, |
|
3785 * else `false`. |
|
3786 * |
|
3787 * @static |
|
3788 * @memberOf _ |
|
3789 * @category Collections |
|
3790 * @param {Array|Object|string} collection The collection to iterate over. |
|
3791 * @param {Function|Object|string} [callback=identity] The function called |
|
3792 * per iteration. If a property name or object is provided it will be used |
|
3793 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3794 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3795 * @returns {Array} Returns a new array of elements that failed the callback check. |
|
3796 * @example |
|
3797 * |
|
3798 * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); |
|
3799 * // => [1, 3, 5] |
|
3800 * |
|
3801 * var characters = [ |
|
3802 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
3803 * { 'name': 'fred', 'age': 40, 'blocked': true } |
|
3804 * ]; |
|
3805 * |
|
3806 * // using "_.pluck" callback shorthand |
|
3807 * _.reject(characters, 'blocked'); |
|
3808 * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] |
|
3809 * |
|
3810 * // using "_.where" callback shorthand |
|
3811 * _.reject(characters, { 'age': 36 }); |
|
3812 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] |
|
3813 */ |
|
3814 function reject(collection, callback, thisArg) { |
|
3815 callback = lodash.createCallback(callback, thisArg, 3); |
|
3816 return filter(collection, function(value, index, collection) { |
|
3817 return !callback(value, index, collection); |
|
3818 }); |
|
3819 } |
|
3820 |
|
3821 /** |
|
3822 * Retrieves a random element or `n` random elements from a collection. |
|
3823 * |
|
3824 * @static |
|
3825 * @memberOf _ |
|
3826 * @category Collections |
|
3827 * @param {Array|Object|string} collection The collection to sample. |
|
3828 * @param {number} [n] The number of elements to sample. |
|
3829 * @param- {Object} [guard] Allows working with functions like `_.map` |
|
3830 * without using their `index` arguments as `n`. |
|
3831 * @returns {Array} Returns the random sample(s) of `collection`. |
|
3832 * @example |
|
3833 * |
|
3834 * _.sample([1, 2, 3, 4]); |
|
3835 * // => 2 |
|
3836 * |
|
3837 * _.sample([1, 2, 3, 4], 2); |
|
3838 * // => [3, 1] |
|
3839 */ |
|
3840 function sample(collection, n, guard) { |
|
3841 if (collection && typeof collection.length != 'number') { |
|
3842 collection = values(collection); |
|
3843 } |
|
3844 if (n == null || guard) { |
|
3845 return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; |
|
3846 } |
|
3847 var result = shuffle(collection); |
|
3848 result.length = nativeMin(nativeMax(0, n), result.length); |
|
3849 return result; |
|
3850 } |
|
3851 |
|
3852 /** |
|
3853 * Creates an array of shuffled values, using a version of the Fisher-Yates |
|
3854 * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. |
|
3855 * |
|
3856 * @static |
|
3857 * @memberOf _ |
|
3858 * @category Collections |
|
3859 * @param {Array|Object|string} collection The collection to shuffle. |
|
3860 * @returns {Array} Returns a new shuffled collection. |
|
3861 * @example |
|
3862 * |
|
3863 * _.shuffle([1, 2, 3, 4, 5, 6]); |
|
3864 * // => [4, 1, 6, 3, 5, 2] |
|
3865 */ |
|
3866 function shuffle(collection) { |
|
3867 var index = -1, |
|
3868 length = collection ? collection.length : 0, |
|
3869 result = Array(typeof length == 'number' ? length : 0); |
|
3870 |
|
3871 forEach(collection, function(value) { |
|
3872 var rand = baseRandom(0, ++index); |
|
3873 result[index] = result[rand]; |
|
3874 result[rand] = value; |
|
3875 }); |
|
3876 return result; |
|
3877 } |
|
3878 |
|
3879 /** |
|
3880 * Gets the size of the `collection` by returning `collection.length` for arrays |
|
3881 * and array-like objects or the number of own enumerable properties for objects. |
|
3882 * |
|
3883 * @static |
|
3884 * @memberOf _ |
|
3885 * @category Collections |
|
3886 * @param {Array|Object|string} collection The collection to inspect. |
|
3887 * @returns {number} Returns `collection.length` or number of own enumerable properties. |
|
3888 * @example |
|
3889 * |
|
3890 * _.size([1, 2]); |
|
3891 * // => 2 |
|
3892 * |
|
3893 * _.size({ 'one': 1, 'two': 2, 'three': 3 }); |
|
3894 * // => 3 |
|
3895 * |
|
3896 * _.size('pebbles'); |
|
3897 * // => 7 |
|
3898 */ |
|
3899 function size(collection) { |
|
3900 var length = collection ? collection.length : 0; |
|
3901 return typeof length == 'number' ? length : keys(collection).length; |
|
3902 } |
|
3903 |
|
3904 /** |
|
3905 * Checks if the callback returns a truey value for **any** element of a |
|
3906 * collection. The function returns as soon as it finds a passing value and |
|
3907 * does not iterate over the entire collection. The callback is bound to |
|
3908 * `thisArg` and invoked with three arguments; (value, index|key, collection). |
|
3909 * |
|
3910 * If a property name is provided for `callback` the created "_.pluck" style |
|
3911 * callback will return the property value of the given element. |
|
3912 * |
|
3913 * If an object is provided for `callback` the created "_.where" style callback |
|
3914 * will return `true` for elements that have the properties of the given object, |
|
3915 * else `false`. |
|
3916 * |
|
3917 * @static |
|
3918 * @memberOf _ |
|
3919 * @alias any |
|
3920 * @category Collections |
|
3921 * @param {Array|Object|string} collection The collection to iterate over. |
|
3922 * @param {Function|Object|string} [callback=identity] The function called |
|
3923 * per iteration. If a property name or object is provided it will be used |
|
3924 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3925 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3926 * @returns {boolean} Returns `true` if any element passed the callback check, |
|
3927 * else `false`. |
|
3928 * @example |
|
3929 * |
|
3930 * _.some([null, 0, 'yes', false], Boolean); |
|
3931 * // => true |
|
3932 * |
|
3933 * var characters = [ |
|
3934 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
3935 * { 'name': 'fred', 'age': 40, 'blocked': true } |
|
3936 * ]; |
|
3937 * |
|
3938 * // using "_.pluck" callback shorthand |
|
3939 * _.some(characters, 'blocked'); |
|
3940 * // => true |
|
3941 * |
|
3942 * // using "_.where" callback shorthand |
|
3943 * _.some(characters, { 'age': 1 }); |
|
3944 * // => false |
|
3945 */ |
|
3946 function some(collection, callback, thisArg) { |
|
3947 var result; |
|
3948 callback = lodash.createCallback(callback, thisArg, 3); |
|
3949 |
|
3950 var index = -1, |
|
3951 length = collection ? collection.length : 0; |
|
3952 |
|
3953 if (typeof length == 'number') { |
|
3954 while (++index < length) { |
|
3955 if ((result = callback(collection[index], index, collection))) { |
|
3956 break; |
|
3957 } |
|
3958 } |
|
3959 } else { |
|
3960 forOwn(collection, function(value, index, collection) { |
|
3961 return !(result = callback(value, index, collection)); |
|
3962 }); |
|
3963 } |
|
3964 return !!result; |
|
3965 } |
|
3966 |
|
3967 /** |
|
3968 * Creates an array of elements, sorted in ascending order by the results of |
|
3969 * running each element in a collection through the callback. This method |
|
3970 * performs a stable sort, that is, it will preserve the original sort order |
|
3971 * of equal elements. The callback is bound to `thisArg` and invoked with |
|
3972 * three arguments; (value, index|key, collection). |
|
3973 * |
|
3974 * If a property name is provided for `callback` the created "_.pluck" style |
|
3975 * callback will return the property value of the given element. |
|
3976 * |
|
3977 * If an array of property names is provided for `callback` the collection |
|
3978 * will be sorted by each property value. |
|
3979 * |
|
3980 * If an object is provided for `callback` the created "_.where" style callback |
|
3981 * will return `true` for elements that have the properties of the given object, |
|
3982 * else `false`. |
|
3983 * |
|
3984 * @static |
|
3985 * @memberOf _ |
|
3986 * @category Collections |
|
3987 * @param {Array|Object|string} collection The collection to iterate over. |
|
3988 * @param {Array|Function|Object|string} [callback=identity] The function called |
|
3989 * per iteration. If a property name or object is provided it will be used |
|
3990 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3991 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3992 * @returns {Array} Returns a new array of sorted elements. |
|
3993 * @example |
|
3994 * |
|
3995 * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); |
|
3996 * // => [3, 1, 2] |
|
3997 * |
|
3998 * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); |
|
3999 * // => [3, 1, 2] |
|
4000 * |
|
4001 * var characters = [ |
|
4002 * { 'name': 'barney', 'age': 36 }, |
|
4003 * { 'name': 'fred', 'age': 40 }, |
|
4004 * { 'name': 'barney', 'age': 26 }, |
|
4005 * { 'name': 'fred', 'age': 30 } |
|
4006 * ]; |
|
4007 * |
|
4008 * // using "_.pluck" callback shorthand |
|
4009 * _.map(_.sortBy(characters, 'age'), _.values); |
|
4010 * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] |
|
4011 * |
|
4012 * // sorting by multiple properties |
|
4013 * _.map(_.sortBy(characters, ['name', 'age']), _.values); |
|
4014 * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] |
|
4015 */ |
|
4016 function sortBy(collection, callback, thisArg) { |
|
4017 var index = -1, |
|
4018 isArr = isArray(callback), |
|
4019 length = collection ? collection.length : 0, |
|
4020 result = Array(typeof length == 'number' ? length : 0); |
|
4021 |
|
4022 if (!isArr) { |
|
4023 callback = lodash.createCallback(callback, thisArg, 3); |
|
4024 } |
|
4025 forEach(collection, function(value, key, collection) { |
|
4026 var object = result[++index] = getObject(); |
|
4027 if (isArr) { |
|
4028 object.criteria = map(callback, function(key) { return value[key]; }); |
|
4029 } else { |
|
4030 (object.criteria = getArray())[0] = callback(value, key, collection); |
|
4031 } |
|
4032 object.index = index; |
|
4033 object.value = value; |
|
4034 }); |
|
4035 |
|
4036 length = result.length; |
|
4037 result.sort(compareAscending); |
|
4038 while (length--) { |
|
4039 var object = result[length]; |
|
4040 result[length] = object.value; |
|
4041 if (!isArr) { |
|
4042 releaseArray(object.criteria); |
|
4043 } |
|
4044 releaseObject(object); |
|
4045 } |
|
4046 return result; |
|
4047 } |
|
4048 |
|
4049 /** |
|
4050 * Converts the `collection` to an array. |
|
4051 * |
|
4052 * @static |
|
4053 * @memberOf _ |
|
4054 * @category Collections |
|
4055 * @param {Array|Object|string} collection The collection to convert. |
|
4056 * @returns {Array} Returns the new converted array. |
|
4057 * @example |
|
4058 * |
|
4059 * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); |
|
4060 * // => [2, 3, 4] |
|
4061 */ |
|
4062 function toArray(collection) { |
|
4063 if (collection && typeof collection.length == 'number') { |
|
4064 return slice(collection); |
|
4065 } |
|
4066 return values(collection); |
|
4067 } |
|
4068 |
|
4069 /** |
|
4070 * Performs a deep comparison of each element in a `collection` to the given |
|
4071 * `properties` object, returning an array of all elements that have equivalent |
|
4072 * property values. |
|
4073 * |
|
4074 * @static |
|
4075 * @memberOf _ |
|
4076 * @type Function |
|
4077 * @category Collections |
|
4078 * @param {Array|Object|string} collection The collection to iterate over. |
|
4079 * @param {Object} props The object of property values to filter by. |
|
4080 * @returns {Array} Returns a new array of elements that have the given properties. |
|
4081 * @example |
|
4082 * |
|
4083 * var characters = [ |
|
4084 * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, |
|
4085 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } |
|
4086 * ]; |
|
4087 * |
|
4088 * _.where(characters, { 'age': 36 }); |
|
4089 * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] |
|
4090 * |
|
4091 * _.where(characters, { 'pets': ['dino'] }); |
|
4092 * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] |
|
4093 */ |
|
4094 var where = filter; |
|
4095 |
|
4096 /*--------------------------------------------------------------------------*/ |
|
4097 |
|
4098 /** |
|
4099 * Creates an array with all falsey values removed. The values `false`, `null`, |
|
4100 * `0`, `""`, `undefined`, and `NaN` are all falsey. |
|
4101 * |
|
4102 * @static |
|
4103 * @memberOf _ |
|
4104 * @category Arrays |
|
4105 * @param {Array} array The array to compact. |
|
4106 * @returns {Array} Returns a new array of filtered values. |
|
4107 * @example |
|
4108 * |
|
4109 * _.compact([0, 1, false, 2, '', 3]); |
|
4110 * // => [1, 2, 3] |
|
4111 */ |
|
4112 function compact(array) { |
|
4113 var index = -1, |
|
4114 length = array ? array.length : 0, |
|
4115 result = []; |
|
4116 |
|
4117 while (++index < length) { |
|
4118 var value = array[index]; |
|
4119 if (value) { |
|
4120 result.push(value); |
|
4121 } |
|
4122 } |
|
4123 return result; |
|
4124 } |
|
4125 |
|
4126 /** |
|
4127 * Creates an array excluding all values of the provided arrays using strict |
|
4128 * equality for comparisons, i.e. `===`. |
|
4129 * |
|
4130 * @static |
|
4131 * @memberOf _ |
|
4132 * @category Arrays |
|
4133 * @param {Array} array The array to process. |
|
4134 * @param {...Array} [values] The arrays of values to exclude. |
|
4135 * @returns {Array} Returns a new array of filtered values. |
|
4136 * @example |
|
4137 * |
|
4138 * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); |
|
4139 * // => [1, 3, 4] |
|
4140 */ |
|
4141 function difference(array) { |
|
4142 return baseDifference(array, baseFlatten(arguments, true, true, 1)); |
|
4143 } |
|
4144 |
|
4145 /** |
|
4146 * This method is like `_.find` except that it returns the index of the first |
|
4147 * element that passes the callback check, instead of the element itself. |
|
4148 * |
|
4149 * If a property name is provided for `callback` the created "_.pluck" style |
|
4150 * callback will return the property value of the given element. |
|
4151 * |
|
4152 * If an object is provided for `callback` the created "_.where" style callback |
|
4153 * will return `true` for elements that have the properties of the given object, |
|
4154 * else `false`. |
|
4155 * |
|
4156 * @static |
|
4157 * @memberOf _ |
|
4158 * @category Arrays |
|
4159 * @param {Array} array The array to search. |
|
4160 * @param {Function|Object|string} [callback=identity] The function called |
|
4161 * per iteration. If a property name or object is provided it will be used |
|
4162 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
4163 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4164 * @returns {number} Returns the index of the found element, else `-1`. |
|
4165 * @example |
|
4166 * |
|
4167 * var characters = [ |
|
4168 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
4169 * { 'name': 'fred', 'age': 40, 'blocked': true }, |
|
4170 * { 'name': 'pebbles', 'age': 1, 'blocked': false } |
|
4171 * ]; |
|
4172 * |
|
4173 * _.findIndex(characters, function(chr) { |
|
4174 * return chr.age < 20; |
|
4175 * }); |
|
4176 * // => 2 |
|
4177 * |
|
4178 * // using "_.where" callback shorthand |
|
4179 * _.findIndex(characters, { 'age': 36 }); |
|
4180 * // => 0 |
|
4181 * |
|
4182 * // using "_.pluck" callback shorthand |
|
4183 * _.findIndex(characters, 'blocked'); |
|
4184 * // => 1 |
|
4185 */ |
|
4186 function findIndex(array, callback, thisArg) { |
|
4187 var index = -1, |
|
4188 length = array ? array.length : 0; |
|
4189 |
|
4190 callback = lodash.createCallback(callback, thisArg, 3); |
|
4191 while (++index < length) { |
|
4192 if (callback(array[index], index, array)) { |
|
4193 return index; |
|
4194 } |
|
4195 } |
|
4196 return -1; |
|
4197 } |
|
4198 |
|
4199 /** |
|
4200 * This method is like `_.findIndex` except that it iterates over elements |
|
4201 * of a `collection` from right to left. |
|
4202 * |
|
4203 * If a property name is provided for `callback` the created "_.pluck" style |
|
4204 * callback will return the property value of the given element. |
|
4205 * |
|
4206 * If an object is provided for `callback` the created "_.where" style callback |
|
4207 * will return `true` for elements that have the properties of the given object, |
|
4208 * else `false`. |
|
4209 * |
|
4210 * @static |
|
4211 * @memberOf _ |
|
4212 * @category Arrays |
|
4213 * @param {Array} array The array to search. |
|
4214 * @param {Function|Object|string} [callback=identity] The function called |
|
4215 * per iteration. If a property name or object is provided it will be used |
|
4216 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
4217 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4218 * @returns {number} Returns the index of the found element, else `-1`. |
|
4219 * @example |
|
4220 * |
|
4221 * var characters = [ |
|
4222 * { 'name': 'barney', 'age': 36, 'blocked': true }, |
|
4223 * { 'name': 'fred', 'age': 40, 'blocked': false }, |
|
4224 * { 'name': 'pebbles', 'age': 1, 'blocked': true } |
|
4225 * ]; |
|
4226 * |
|
4227 * _.findLastIndex(characters, function(chr) { |
|
4228 * return chr.age > 30; |
|
4229 * }); |
|
4230 * // => 1 |
|
4231 * |
|
4232 * // using "_.where" callback shorthand |
|
4233 * _.findLastIndex(characters, { 'age': 36 }); |
|
4234 * // => 0 |
|
4235 * |
|
4236 * // using "_.pluck" callback shorthand |
|
4237 * _.findLastIndex(characters, 'blocked'); |
|
4238 * // => 2 |
|
4239 */ |
|
4240 function findLastIndex(array, callback, thisArg) { |
|
4241 var length = array ? array.length : 0; |
|
4242 callback = lodash.createCallback(callback, thisArg, 3); |
|
4243 while (length--) { |
|
4244 if (callback(array[length], length, array)) { |
|
4245 return length; |
|
4246 } |
|
4247 } |
|
4248 return -1; |
|
4249 } |
|
4250 |
|
4251 /** |
|
4252 * Gets the first element or first `n` elements of an array. If a callback |
|
4253 * is provided elements at the beginning of the array are returned as long |
|
4254 * as the callback returns truey. The callback is bound to `thisArg` and |
|
4255 * invoked with three arguments; (value, index, array). |
|
4256 * |
|
4257 * If a property name is provided for `callback` the created "_.pluck" style |
|
4258 * callback will return the property value of the given element. |
|
4259 * |
|
4260 * If an object is provided for `callback` the created "_.where" style callback |
|
4261 * will return `true` for elements that have the properties of the given object, |
|
4262 * else `false`. |
|
4263 * |
|
4264 * @static |
|
4265 * @memberOf _ |
|
4266 * @alias head, take |
|
4267 * @category Arrays |
|
4268 * @param {Array} array The array to query. |
|
4269 * @param {Function|Object|number|string} [callback] The function called |
|
4270 * per element or the number of elements to return. If a property name or |
|
4271 * object is provided it will be used to create a "_.pluck" or "_.where" |
|
4272 * style callback, respectively. |
|
4273 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4274 * @returns {*} Returns the first element(s) of `array`. |
|
4275 * @example |
|
4276 * |
|
4277 * _.first([1, 2, 3]); |
|
4278 * // => 1 |
|
4279 * |
|
4280 * _.first([1, 2, 3], 2); |
|
4281 * // => [1, 2] |
|
4282 * |
|
4283 * _.first([1, 2, 3], function(num) { |
|
4284 * return num < 3; |
|
4285 * }); |
|
4286 * // => [1, 2] |
|
4287 * |
|
4288 * var characters = [ |
|
4289 * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, |
|
4290 * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, |
|
4291 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } |
|
4292 * ]; |
|
4293 * |
|
4294 * // using "_.pluck" callback shorthand |
|
4295 * _.first(characters, 'blocked'); |
|
4296 * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] |
|
4297 * |
|
4298 * // using "_.where" callback shorthand |
|
4299 * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); |
|
4300 * // => ['barney', 'fred'] |
|
4301 */ |
|
4302 function first(array, callback, thisArg) { |
|
4303 var n = 0, |
|
4304 length = array ? array.length : 0; |
|
4305 |
|
4306 if (typeof callback != 'number' && callback != null) { |
|
4307 var index = -1; |
|
4308 callback = lodash.createCallback(callback, thisArg, 3); |
|
4309 while (++index < length && callback(array[index], index, array)) { |
|
4310 n++; |
|
4311 } |
|
4312 } else { |
|
4313 n = callback; |
|
4314 if (n == null || thisArg) { |
|
4315 return array ? array[0] : undefined; |
|
4316 } |
|
4317 } |
|
4318 return slice(array, 0, nativeMin(nativeMax(0, n), length)); |
|
4319 } |
|
4320 |
|
4321 /** |
|
4322 * Flattens a nested array (the nesting can be to any depth). If `isShallow` |
|
4323 * is truey, the array will only be flattened a single level. If a callback |
|
4324 * is provided each element of the array is passed through the callback before |
|
4325 * flattening. The callback is bound to `thisArg` and invoked with three |
|
4326 * arguments; (value, index, array). |
|
4327 * |
|
4328 * If a property name is provided for `callback` the created "_.pluck" style |
|
4329 * callback will return the property value of the given element. |
|
4330 * |
|
4331 * If an object is provided for `callback` the created "_.where" style callback |
|
4332 * will return `true` for elements that have the properties of the given object, |
|
4333 * else `false`. |
|
4334 * |
|
4335 * @static |
|
4336 * @memberOf _ |
|
4337 * @category Arrays |
|
4338 * @param {Array} array The array to flatten. |
|
4339 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. |
|
4340 * @param {Function|Object|string} [callback=identity] The function called |
|
4341 * per iteration. If a property name or object is provided it will be used |
|
4342 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
4343 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4344 * @returns {Array} Returns a new flattened array. |
|
4345 * @example |
|
4346 * |
|
4347 * _.flatten([1, [2], [3, [[4]]]]); |
|
4348 * // => [1, 2, 3, 4]; |
|
4349 * |
|
4350 * _.flatten([1, [2], [3, [[4]]]], true); |
|
4351 * // => [1, 2, 3, [[4]]]; |
|
4352 * |
|
4353 * var characters = [ |
|
4354 * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, |
|
4355 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } |
|
4356 * ]; |
|
4357 * |
|
4358 * // using "_.pluck" callback shorthand |
|
4359 * _.flatten(characters, 'pets'); |
|
4360 * // => ['hoppy', 'baby puss', 'dino'] |
|
4361 */ |
|
4362 function flatten(array, isShallow, callback, thisArg) { |
|
4363 // juggle arguments |
|
4364 if (typeof isShallow != 'boolean' && isShallow != null) { |
|
4365 thisArg = callback; |
|
4366 callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; |
|
4367 isShallow = false; |
|
4368 } |
|
4369 if (callback != null) { |
|
4370 array = map(array, callback, thisArg); |
|
4371 } |
|
4372 return baseFlatten(array, isShallow); |
|
4373 } |
|
4374 |
|
4375 /** |
|
4376 * Gets the index at which the first occurrence of `value` is found using |
|
4377 * strict equality for comparisons, i.e. `===`. If the array is already sorted |
|
4378 * providing `true` for `fromIndex` will run a faster binary search. |
|
4379 * |
|
4380 * @static |
|
4381 * @memberOf _ |
|
4382 * @category Arrays |
|
4383 * @param {Array} array The array to search. |
|
4384 * @param {*} value The value to search for. |
|
4385 * @param {boolean|number} [fromIndex=0] The index to search from or `true` |
|
4386 * to perform a binary search on a sorted array. |
|
4387 * @returns {number} Returns the index of the matched value or `-1`. |
|
4388 * @example |
|
4389 * |
|
4390 * _.indexOf([1, 2, 3, 1, 2, 3], 2); |
|
4391 * // => 1 |
|
4392 * |
|
4393 * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); |
|
4394 * // => 4 |
|
4395 * |
|
4396 * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); |
|
4397 * // => 2 |
|
4398 */ |
|
4399 function indexOf(array, value, fromIndex) { |
|
4400 if (typeof fromIndex == 'number') { |
|
4401 var length = array ? array.length : 0; |
|
4402 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); |
|
4403 } else if (fromIndex) { |
|
4404 var index = sortedIndex(array, value); |
|
4405 return array[index] === value ? index : -1; |
|
4406 } |
|
4407 return baseIndexOf(array, value, fromIndex); |
|
4408 } |
|
4409 |
|
4410 /** |
|
4411 * Gets all but the last element or last `n` elements of an array. If a |
|
4412 * callback is provided elements at the end of the array are excluded from |
|
4413 * the result as long as the callback returns truey. The callback is bound |
|
4414 * to `thisArg` and invoked with three arguments; (value, index, array). |
|
4415 * |
|
4416 * If a property name is provided for `callback` the created "_.pluck" style |
|
4417 * callback will return the property value of the given element. |
|
4418 * |
|
4419 * If an object is provided for `callback` the created "_.where" style callback |
|
4420 * will return `true` for elements that have the properties of the given object, |
|
4421 * else `false`. |
|
4422 * |
|
4423 * @static |
|
4424 * @memberOf _ |
|
4425 * @category Arrays |
|
4426 * @param {Array} array The array to query. |
|
4427 * @param {Function|Object|number|string} [callback=1] The function called |
|
4428 * per element or the number of elements to exclude. If a property name or |
|
4429 * object is provided it will be used to create a "_.pluck" or "_.where" |
|
4430 * style callback, respectively. |
|
4431 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4432 * @returns {Array} Returns a slice of `array`. |
|
4433 * @example |
|
4434 * |
|
4435 * _.initial([1, 2, 3]); |
|
4436 * // => [1, 2] |
|
4437 * |
|
4438 * _.initial([1, 2, 3], 2); |
|
4439 * // => [1] |
|
4440 * |
|
4441 * _.initial([1, 2, 3], function(num) { |
|
4442 * return num > 1; |
|
4443 * }); |
|
4444 * // => [1] |
|
4445 * |
|
4446 * var characters = [ |
|
4447 * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, |
|
4448 * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, |
|
4449 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } |
|
4450 * ]; |
|
4451 * |
|
4452 * // using "_.pluck" callback shorthand |
|
4453 * _.initial(characters, 'blocked'); |
|
4454 * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] |
|
4455 * |
|
4456 * // using "_.where" callback shorthand |
|
4457 * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); |
|
4458 * // => ['barney', 'fred'] |
|
4459 */ |
|
4460 function initial(array, callback, thisArg) { |
|
4461 var n = 0, |
|
4462 length = array ? array.length : 0; |
|
4463 |
|
4464 if (typeof callback != 'number' && callback != null) { |
|
4465 var index = length; |
|
4466 callback = lodash.createCallback(callback, thisArg, 3); |
|
4467 while (index-- && callback(array[index], index, array)) { |
|
4468 n++; |
|
4469 } |
|
4470 } else { |
|
4471 n = (callback == null || thisArg) ? 1 : callback || n; |
|
4472 } |
|
4473 return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); |
|
4474 } |
|
4475 |
|
4476 /** |
|
4477 * Creates an array of unique values present in all provided arrays using |
|
4478 * strict equality for comparisons, i.e. `===`. |
|
4479 * |
|
4480 * @static |
|
4481 * @memberOf _ |
|
4482 * @category Arrays |
|
4483 * @param {...Array} [array] The arrays to inspect. |
|
4484 * @returns {Array} Returns an array of shared values. |
|
4485 * @example |
|
4486 * |
|
4487 * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); |
|
4488 * // => [1, 2] |
|
4489 */ |
|
4490 function intersection() { |
|
4491 var args = [], |
|
4492 argsIndex = -1, |
|
4493 argsLength = arguments.length, |
|
4494 caches = getArray(), |
|
4495 indexOf = getIndexOf(), |
|
4496 trustIndexOf = indexOf === baseIndexOf, |
|
4497 seen = getArray(); |
|
4498 |
|
4499 while (++argsIndex < argsLength) { |
|
4500 var value = arguments[argsIndex]; |
|
4501 if (isArray(value) || isArguments(value)) { |
|
4502 args.push(value); |
|
4503 caches.push(trustIndexOf && value.length >= largeArraySize && |
|
4504 createCache(argsIndex ? args[argsIndex] : seen)); |
|
4505 } |
|
4506 } |
|
4507 var array = args[0], |
|
4508 index = -1, |
|
4509 length = array ? array.length : 0, |
|
4510 result = []; |
|
4511 |
|
4512 outer: |
|
4513 while (++index < length) { |
|
4514 var cache = caches[0]; |
|
4515 value = array[index]; |
|
4516 |
|
4517 if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { |
|
4518 argsIndex = argsLength; |
|
4519 (cache || seen).push(value); |
|
4520 while (--argsIndex) { |
|
4521 cache = caches[argsIndex]; |
|
4522 if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { |
|
4523 continue outer; |
|
4524 } |
|
4525 } |
|
4526 result.push(value); |
|
4527 } |
|
4528 } |
|
4529 while (argsLength--) { |
|
4530 cache = caches[argsLength]; |
|
4531 if (cache) { |
|
4532 releaseObject(cache); |
|
4533 } |
|
4534 } |
|
4535 releaseArray(caches); |
|
4536 releaseArray(seen); |
|
4537 return result; |
|
4538 } |
|
4539 |
|
4540 /** |
|
4541 * Gets the last element or last `n` elements of an array. If a callback is |
|
4542 * provided elements at the end of the array are returned as long as the |
|
4543 * callback returns truey. The callback is bound to `thisArg` and invoked |
|
4544 * with three arguments; (value, index, array). |
|
4545 * |
|
4546 * If a property name is provided for `callback` the created "_.pluck" style |
|
4547 * callback will return the property value of the given element. |
|
4548 * |
|
4549 * If an object is provided for `callback` the created "_.where" style callback |
|
4550 * will return `true` for elements that have the properties of the given object, |
|
4551 * else `false`. |
|
4552 * |
|
4553 * @static |
|
4554 * @memberOf _ |
|
4555 * @category Arrays |
|
4556 * @param {Array} array The array to query. |
|
4557 * @param {Function|Object|number|string} [callback] The function called |
|
4558 * per element or the number of elements to return. If a property name or |
|
4559 * object is provided it will be used to create a "_.pluck" or "_.where" |
|
4560 * style callback, respectively. |
|
4561 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4562 * @returns {*} Returns the last element(s) of `array`. |
|
4563 * @example |
|
4564 * |
|
4565 * _.last([1, 2, 3]); |
|
4566 * // => 3 |
|
4567 * |
|
4568 * _.last([1, 2, 3], 2); |
|
4569 * // => [2, 3] |
|
4570 * |
|
4571 * _.last([1, 2, 3], function(num) { |
|
4572 * return num > 1; |
|
4573 * }); |
|
4574 * // => [2, 3] |
|
4575 * |
|
4576 * var characters = [ |
|
4577 * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, |
|
4578 * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, |
|
4579 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } |
|
4580 * ]; |
|
4581 * |
|
4582 * // using "_.pluck" callback shorthand |
|
4583 * _.pluck(_.last(characters, 'blocked'), 'name'); |
|
4584 * // => ['fred', 'pebbles'] |
|
4585 * |
|
4586 * // using "_.where" callback shorthand |
|
4587 * _.last(characters, { 'employer': 'na' }); |
|
4588 * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] |
|
4589 */ |
|
4590 function last(array, callback, thisArg) { |
|
4591 var n = 0, |
|
4592 length = array ? array.length : 0; |
|
4593 |
|
4594 if (typeof callback != 'number' && callback != null) { |
|
4595 var index = length; |
|
4596 callback = lodash.createCallback(callback, thisArg, 3); |
|
4597 while (index-- && callback(array[index], index, array)) { |
|
4598 n++; |
|
4599 } |
|
4600 } else { |
|
4601 n = callback; |
|
4602 if (n == null || thisArg) { |
|
4603 return array ? array[length - 1] : undefined; |
|
4604 } |
|
4605 } |
|
4606 return slice(array, nativeMax(0, length - n)); |
|
4607 } |
|
4608 |
|
4609 /** |
|
4610 * Gets the index at which the last occurrence of `value` is found using strict |
|
4611 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used |
|
4612 * as the offset from the end of the collection. |
|
4613 * |
|
4614 * If a property name is provided for `callback` the created "_.pluck" style |
|
4615 * callback will return the property value of the given element. |
|
4616 * |
|
4617 * If an object is provided for `callback` the created "_.where" style callback |
|
4618 * will return `true` for elements that have the properties of the given object, |
|
4619 * else `false`. |
|
4620 * |
|
4621 * @static |
|
4622 * @memberOf _ |
|
4623 * @category Arrays |
|
4624 * @param {Array} array The array to search. |
|
4625 * @param {*} value The value to search for. |
|
4626 * @param {number} [fromIndex=array.length-1] The index to search from. |
|
4627 * @returns {number} Returns the index of the matched value or `-1`. |
|
4628 * @example |
|
4629 * |
|
4630 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); |
|
4631 * // => 4 |
|
4632 * |
|
4633 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); |
|
4634 * // => 1 |
|
4635 */ |
|
4636 function lastIndexOf(array, value, fromIndex) { |
|
4637 var index = array ? array.length : 0; |
|
4638 if (typeof fromIndex == 'number') { |
|
4639 index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; |
|
4640 } |
|
4641 while (index--) { |
|
4642 if (array[index] === value) { |
|
4643 return index; |
|
4644 } |
|
4645 } |
|
4646 return -1; |
|
4647 } |
|
4648 |
|
4649 /** |
|
4650 * Removes all provided values from the given array using strict equality for |
|
4651 * comparisons, i.e. `===`. |
|
4652 * |
|
4653 * @static |
|
4654 * @memberOf _ |
|
4655 * @category Arrays |
|
4656 * @param {Array} array The array to modify. |
|
4657 * @param {...*} [value] The values to remove. |
|
4658 * @returns {Array} Returns `array`. |
|
4659 * @example |
|
4660 * |
|
4661 * var array = [1, 2, 3, 1, 2, 3]; |
|
4662 * _.pull(array, 2, 3); |
|
4663 * console.log(array); |
|
4664 * // => [1, 1] |
|
4665 */ |
|
4666 function pull(array) { |
|
4667 var args = arguments, |
|
4668 argsIndex = 0, |
|
4669 argsLength = args.length, |
|
4670 length = array ? array.length : 0; |
|
4671 |
|
4672 while (++argsIndex < argsLength) { |
|
4673 var index = -1, |
|
4674 value = args[argsIndex]; |
|
4675 while (++index < length) { |
|
4676 if (array[index] === value) { |
|
4677 splice.call(array, index--, 1); |
|
4678 length--; |
|
4679 } |
|
4680 } |
|
4681 } |
|
4682 return array; |
|
4683 } |
|
4684 |
|
4685 /** |
|
4686 * Creates an array of numbers (positive and/or negative) progressing from |
|
4687 * `start` up to but not including `end`. If `start` is less than `stop` a |
|
4688 * zero-length range is created unless a negative `step` is specified. |
|
4689 * |
|
4690 * @static |
|
4691 * @memberOf _ |
|
4692 * @category Arrays |
|
4693 * @param {number} [start=0] The start of the range. |
|
4694 * @param {number} end The end of the range. |
|
4695 * @param {number} [step=1] The value to increment or decrement by. |
|
4696 * @returns {Array} Returns a new range array. |
|
4697 * @example |
|
4698 * |
|
4699 * _.range(4); |
|
4700 * // => [0, 1, 2, 3] |
|
4701 * |
|
4702 * _.range(1, 5); |
|
4703 * // => [1, 2, 3, 4] |
|
4704 * |
|
4705 * _.range(0, 20, 5); |
|
4706 * // => [0, 5, 10, 15] |
|
4707 * |
|
4708 * _.range(0, -4, -1); |
|
4709 * // => [0, -1, -2, -3] |
|
4710 * |
|
4711 * _.range(1, 4, 0); |
|
4712 * // => [1, 1, 1] |
|
4713 * |
|
4714 * _.range(0); |
|
4715 * // => [] |
|
4716 */ |
|
4717 function range(start, end, step) { |
|
4718 start = +start || 0; |
|
4719 step = typeof step == 'number' ? step : (+step || 1); |
|
4720 |
|
4721 if (end == null) { |
|
4722 end = start; |
|
4723 start = 0; |
|
4724 } |
|
4725 // use `Array(length)` so engines like Chakra and V8 avoid slower modes |
|
4726 // http://youtu.be/XAqIpGU8ZZk#t=17m25s |
|
4727 var index = -1, |
|
4728 length = nativeMax(0, ceil((end - start) / (step || 1))), |
|
4729 result = Array(length); |
|
4730 |
|
4731 while (++index < length) { |
|
4732 result[index] = start; |
|
4733 start += step; |
|
4734 } |
|
4735 return result; |
|
4736 } |
|
4737 |
|
4738 /** |
|
4739 * Removes all elements from an array that the callback returns truey for |
|
4740 * and returns an array of removed elements. The callback is bound to `thisArg` |
|
4741 * and invoked with three arguments; (value, index, array). |
|
4742 * |
|
4743 * If a property name is provided for `callback` the created "_.pluck" style |
|
4744 * callback will return the property value of the given element. |
|
4745 * |
|
4746 * If an object is provided for `callback` the created "_.where" style callback |
|
4747 * will return `true` for elements that have the properties of the given object, |
|
4748 * else `false`. |
|
4749 * |
|
4750 * @static |
|
4751 * @memberOf _ |
|
4752 * @category Arrays |
|
4753 * @param {Array} array The array to modify. |
|
4754 * @param {Function|Object|string} [callback=identity] The function called |
|
4755 * per iteration. If a property name or object is provided it will be used |
|
4756 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
4757 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4758 * @returns {Array} Returns a new array of removed elements. |
|
4759 * @example |
|
4760 * |
|
4761 * var array = [1, 2, 3, 4, 5, 6]; |
|
4762 * var evens = _.remove(array, function(num) { return num % 2 == 0; }); |
|
4763 * |
|
4764 * console.log(array); |
|
4765 * // => [1, 3, 5] |
|
4766 * |
|
4767 * console.log(evens); |
|
4768 * // => [2, 4, 6] |
|
4769 */ |
|
4770 function remove(array, callback, thisArg) { |
|
4771 var index = -1, |
|
4772 length = array ? array.length : 0, |
|
4773 result = []; |
|
4774 |
|
4775 callback = lodash.createCallback(callback, thisArg, 3); |
|
4776 while (++index < length) { |
|
4777 var value = array[index]; |
|
4778 if (callback(value, index, array)) { |
|
4779 result.push(value); |
|
4780 splice.call(array, index--, 1); |
|
4781 length--; |
|
4782 } |
|
4783 } |
|
4784 return result; |
|
4785 } |
|
4786 |
|
4787 /** |
|
4788 * The opposite of `_.initial` this method gets all but the first element or |
|
4789 * first `n` elements of an array. If a callback function is provided elements |
|
4790 * at the beginning of the array are excluded from the result as long as the |
|
4791 * callback returns truey. The callback is bound to `thisArg` and invoked |
|
4792 * with three arguments; (value, index, array). |
|
4793 * |
|
4794 * If a property name is provided for `callback` the created "_.pluck" style |
|
4795 * callback will return the property value of the given element. |
|
4796 * |
|
4797 * If an object is provided for `callback` the created "_.where" style callback |
|
4798 * will return `true` for elements that have the properties of the given object, |
|
4799 * else `false`. |
|
4800 * |
|
4801 * @static |
|
4802 * @memberOf _ |
|
4803 * @alias drop, tail |
|
4804 * @category Arrays |
|
4805 * @param {Array} array The array to query. |
|
4806 * @param {Function|Object|number|string} [callback=1] The function called |
|
4807 * per element or the number of elements to exclude. If a property name or |
|
4808 * object is provided it will be used to create a "_.pluck" or "_.where" |
|
4809 * style callback, respectively. |
|
4810 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4811 * @returns {Array} Returns a slice of `array`. |
|
4812 * @example |
|
4813 * |
|
4814 * _.rest([1, 2, 3]); |
|
4815 * // => [2, 3] |
|
4816 * |
|
4817 * _.rest([1, 2, 3], 2); |
|
4818 * // => [3] |
|
4819 * |
|
4820 * _.rest([1, 2, 3], function(num) { |
|
4821 * return num < 3; |
|
4822 * }); |
|
4823 * // => [3] |
|
4824 * |
|
4825 * var characters = [ |
|
4826 * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, |
|
4827 * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, |
|
4828 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } |
|
4829 * ]; |
|
4830 * |
|
4831 * // using "_.pluck" callback shorthand |
|
4832 * _.pluck(_.rest(characters, 'blocked'), 'name'); |
|
4833 * // => ['fred', 'pebbles'] |
|
4834 * |
|
4835 * // using "_.where" callback shorthand |
|
4836 * _.rest(characters, { 'employer': 'slate' }); |
|
4837 * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] |
|
4838 */ |
|
4839 function rest(array, callback, thisArg) { |
|
4840 if (typeof callback != 'number' && callback != null) { |
|
4841 var n = 0, |
|
4842 index = -1, |
|
4843 length = array ? array.length : 0; |
|
4844 |
|
4845 callback = lodash.createCallback(callback, thisArg, 3); |
|
4846 while (++index < length && callback(array[index], index, array)) { |
|
4847 n++; |
|
4848 } |
|
4849 } else { |
|
4850 n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); |
|
4851 } |
|
4852 return slice(array, n); |
|
4853 } |
|
4854 |
|
4855 /** |
|
4856 * Uses a binary search to determine the smallest index at which a value |
|
4857 * should be inserted into a given sorted array in order to maintain the sort |
|
4858 * order of the array. If a callback is provided it will be executed for |
|
4859 * `value` and each element of `array` to compute their sort ranking. The |
|
4860 * callback is bound to `thisArg` and invoked with one argument; (value). |
|
4861 * |
|
4862 * If a property name is provided for `callback` the created "_.pluck" style |
|
4863 * callback will return the property value of the given element. |
|
4864 * |
|
4865 * If an object is provided for `callback` the created "_.where" style callback |
|
4866 * will return `true` for elements that have the properties of the given object, |
|
4867 * else `false`. |
|
4868 * |
|
4869 * @static |
|
4870 * @memberOf _ |
|
4871 * @category Arrays |
|
4872 * @param {Array} array The array to inspect. |
|
4873 * @param {*} value The value to evaluate. |
|
4874 * @param {Function|Object|string} [callback=identity] The function called |
|
4875 * per iteration. If a property name or object is provided it will be used |
|
4876 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
4877 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4878 * @returns {number} Returns the index at which `value` should be inserted |
|
4879 * into `array`. |
|
4880 * @example |
|
4881 * |
|
4882 * _.sortedIndex([20, 30, 50], 40); |
|
4883 * // => 2 |
|
4884 * |
|
4885 * // using "_.pluck" callback shorthand |
|
4886 * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); |
|
4887 * // => 2 |
|
4888 * |
|
4889 * var dict = { |
|
4890 * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } |
|
4891 * }; |
|
4892 * |
|
4893 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { |
|
4894 * return dict.wordToNumber[word]; |
|
4895 * }); |
|
4896 * // => 2 |
|
4897 * |
|
4898 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { |
|
4899 * return this.wordToNumber[word]; |
|
4900 * }, dict); |
|
4901 * // => 2 |
|
4902 */ |
|
4903 function sortedIndex(array, value, callback, thisArg) { |
|
4904 var low = 0, |
|
4905 high = array ? array.length : low; |
|
4906 |
|
4907 // explicitly reference `identity` for better inlining in Firefox |
|
4908 callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; |
|
4909 value = callback(value); |
|
4910 |
|
4911 while (low < high) { |
|
4912 var mid = (low + high) >>> 1; |
|
4913 (callback(array[mid]) < value) |
|
4914 ? low = mid + 1 |
|
4915 : high = mid; |
|
4916 } |
|
4917 return low; |
|
4918 } |
|
4919 |
|
4920 /** |
|
4921 * Creates an array of unique values, in order, of the provided arrays using |
|
4922 * strict equality for comparisons, i.e. `===`. |
|
4923 * |
|
4924 * @static |
|
4925 * @memberOf _ |
|
4926 * @category Arrays |
|
4927 * @param {...Array} [array] The arrays to inspect. |
|
4928 * @returns {Array} Returns an array of combined values. |
|
4929 * @example |
|
4930 * |
|
4931 * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); |
|
4932 * // => [1, 2, 3, 5, 4] |
|
4933 */ |
|
4934 function union() { |
|
4935 return baseUniq(baseFlatten(arguments, true, true)); |
|
4936 } |
|
4937 |
|
4938 /** |
|
4939 * Creates a duplicate-value-free version of an array using strict equality |
|
4940 * for comparisons, i.e. `===`. If the array is sorted, providing |
|
4941 * `true` for `isSorted` will use a faster algorithm. If a callback is provided |
|
4942 * each element of `array` is passed through the callback before uniqueness |
|
4943 * is computed. The callback is bound to `thisArg` and invoked with three |
|
4944 * arguments; (value, index, array). |
|
4945 * |
|
4946 * If a property name is provided for `callback` the created "_.pluck" style |
|
4947 * callback will return the property value of the given element. |
|
4948 * |
|
4949 * If an object is provided for `callback` the created "_.where" style callback |
|
4950 * will return `true` for elements that have the properties of the given object, |
|
4951 * else `false`. |
|
4952 * |
|
4953 * @static |
|
4954 * @memberOf _ |
|
4955 * @alias unique |
|
4956 * @category Arrays |
|
4957 * @param {Array} array The array to process. |
|
4958 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. |
|
4959 * @param {Function|Object|string} [callback=identity] The function called |
|
4960 * per iteration. If a property name or object is provided it will be used |
|
4961 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
4962 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4963 * @returns {Array} Returns a duplicate-value-free array. |
|
4964 * @example |
|
4965 * |
|
4966 * _.uniq([1, 2, 1, 3, 1]); |
|
4967 * // => [1, 2, 3] |
|
4968 * |
|
4969 * _.uniq([1, 1, 2, 2, 3], true); |
|
4970 * // => [1, 2, 3] |
|
4971 * |
|
4972 * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); |
|
4973 * // => ['A', 'b', 'C'] |
|
4974 * |
|
4975 * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); |
|
4976 * // => [1, 2.5, 3] |
|
4977 * |
|
4978 * // using "_.pluck" callback shorthand |
|
4979 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); |
|
4980 * // => [{ 'x': 1 }, { 'x': 2 }] |
|
4981 */ |
|
4982 function uniq(array, isSorted, callback, thisArg) { |
|
4983 // juggle arguments |
|
4984 if (typeof isSorted != 'boolean' && isSorted != null) { |
|
4985 thisArg = callback; |
|
4986 callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; |
|
4987 isSorted = false; |
|
4988 } |
|
4989 if (callback != null) { |
|
4990 callback = lodash.createCallback(callback, thisArg, 3); |
|
4991 } |
|
4992 return baseUniq(array, isSorted, callback); |
|
4993 } |
|
4994 |
|
4995 /** |
|
4996 * Creates an array excluding all provided values using strict equality for |
|
4997 * comparisons, i.e. `===`. |
|
4998 * |
|
4999 * @static |
|
5000 * @memberOf _ |
|
5001 * @category Arrays |
|
5002 * @param {Array} array The array to filter. |
|
5003 * @param {...*} [value] The values to exclude. |
|
5004 * @returns {Array} Returns a new array of filtered values. |
|
5005 * @example |
|
5006 * |
|
5007 * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); |
|
5008 * // => [2, 3, 4] |
|
5009 */ |
|
5010 function without(array) { |
|
5011 return baseDifference(array, slice(arguments, 1)); |
|
5012 } |
|
5013 |
|
5014 /** |
|
5015 * Creates an array that is the symmetric difference of the provided arrays. |
|
5016 * See http://en.wikipedia.org/wiki/Symmetric_difference. |
|
5017 * |
|
5018 * @static |
|
5019 * @memberOf _ |
|
5020 * @category Arrays |
|
5021 * @param {...Array} [array] The arrays to inspect. |
|
5022 * @returns {Array} Returns an array of values. |
|
5023 * @example |
|
5024 * |
|
5025 * _.xor([1, 2, 3], [5, 2, 1, 4]); |
|
5026 * // => [3, 5, 4] |
|
5027 * |
|
5028 * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); |
|
5029 * // => [1, 4, 5] |
|
5030 */ |
|
5031 function xor() { |
|
5032 var index = -1, |
|
5033 length = arguments.length; |
|
5034 |
|
5035 while (++index < length) { |
|
5036 var array = arguments[index]; |
|
5037 if (isArray(array) || isArguments(array)) { |
|
5038 var result = result |
|
5039 ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) |
|
5040 : array; |
|
5041 } |
|
5042 } |
|
5043 return result || []; |
|
5044 } |
|
5045 |
|
5046 /** |
|
5047 * Creates an array of grouped elements, the first of which contains the first |
|
5048 * elements of the given arrays, the second of which contains the second |
|
5049 * elements of the given arrays, and so on. |
|
5050 * |
|
5051 * @static |
|
5052 * @memberOf _ |
|
5053 * @alias unzip |
|
5054 * @category Arrays |
|
5055 * @param {...Array} [array] Arrays to process. |
|
5056 * @returns {Array} Returns a new array of grouped elements. |
|
5057 * @example |
|
5058 * |
|
5059 * _.zip(['fred', 'barney'], [30, 40], [true, false]); |
|
5060 * // => [['fred', 30, true], ['barney', 40, false]] |
|
5061 */ |
|
5062 function zip() { |
|
5063 var array = arguments.length > 1 ? arguments : arguments[0], |
|
5064 index = -1, |
|
5065 length = array ? max(pluck(array, 'length')) : 0, |
|
5066 result = Array(length < 0 ? 0 : length); |
|
5067 |
|
5068 while (++index < length) { |
|
5069 result[index] = pluck(array, index); |
|
5070 } |
|
5071 return result; |
|
5072 } |
|
5073 |
|
5074 /** |
|
5075 * Creates an object composed from arrays of `keys` and `values`. Provide |
|
5076 * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` |
|
5077 * or two arrays, one of `keys` and one of corresponding `values`. |
|
5078 * |
|
5079 * @static |
|
5080 * @memberOf _ |
|
5081 * @alias object |
|
5082 * @category Arrays |
|
5083 * @param {Array} keys The array of keys. |
|
5084 * @param {Array} [values=[]] The array of values. |
|
5085 * @returns {Object} Returns an object composed of the given keys and |
|
5086 * corresponding values. |
|
5087 * @example |
|
5088 * |
|
5089 * _.zipObject(['fred', 'barney'], [30, 40]); |
|
5090 * // => { 'fred': 30, 'barney': 40 } |
|
5091 */ |
|
5092 function zipObject(keys, values) { |
|
5093 var index = -1, |
|
5094 length = keys ? keys.length : 0, |
|
5095 result = {}; |
|
5096 |
|
5097 if (!values && length && !isArray(keys[0])) { |
|
5098 values = []; |
|
5099 } |
|
5100 while (++index < length) { |
|
5101 var key = keys[index]; |
|
5102 if (values) { |
|
5103 result[key] = values[index]; |
|
5104 } else if (key) { |
|
5105 result[key[0]] = key[1]; |
|
5106 } |
|
5107 } |
|
5108 return result; |
|
5109 } |
|
5110 |
|
5111 /*--------------------------------------------------------------------------*/ |
|
5112 |
|
5113 /** |
|
5114 * Creates a function that executes `func`, with the `this` binding and |
|
5115 * arguments of the created function, only after being called `n` times. |
|
5116 * |
|
5117 * @static |
|
5118 * @memberOf _ |
|
5119 * @category Functions |
|
5120 * @param {number} n The number of times the function must be called before |
|
5121 * `func` is executed. |
|
5122 * @param {Function} func The function to restrict. |
|
5123 * @returns {Function} Returns the new restricted function. |
|
5124 * @example |
|
5125 * |
|
5126 * var saves = ['profile', 'settings']; |
|
5127 * |
|
5128 * var done = _.after(saves.length, function() { |
|
5129 * console.log('Done saving!'); |
|
5130 * }); |
|
5131 * |
|
5132 * _.forEach(saves, function(type) { |
|
5133 * asyncSave({ 'type': type, 'complete': done }); |
|
5134 * }); |
|
5135 * // => logs 'Done saving!', after all saves have completed |
|
5136 */ |
|
5137 function after(n, func) { |
|
5138 if (!isFunction(func)) { |
|
5139 throw new TypeError; |
|
5140 } |
|
5141 return function() { |
|
5142 if (--n < 1) { |
|
5143 return func.apply(this, arguments); |
|
5144 } |
|
5145 }; |
|
5146 } |
|
5147 |
|
5148 /** |
|
5149 * Creates a function that, when called, invokes `func` with the `this` |
|
5150 * binding of `thisArg` and prepends any additional `bind` arguments to those |
|
5151 * provided to the bound function. |
|
5152 * |
|
5153 * @static |
|
5154 * @memberOf _ |
|
5155 * @category Functions |
|
5156 * @param {Function} func The function to bind. |
|
5157 * @param {*} [thisArg] The `this` binding of `func`. |
|
5158 * @param {...*} [arg] Arguments to be partially applied. |
|
5159 * @returns {Function} Returns the new bound function. |
|
5160 * @example |
|
5161 * |
|
5162 * var func = function(greeting) { |
|
5163 * return greeting + ' ' + this.name; |
|
5164 * }; |
|
5165 * |
|
5166 * func = _.bind(func, { 'name': 'fred' }, 'hi'); |
|
5167 * func(); |
|
5168 * // => 'hi fred' |
|
5169 */ |
|
5170 function bind(func, thisArg) { |
|
5171 return arguments.length > 2 |
|
5172 ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) |
|
5173 : createWrapper(func, 1, null, null, thisArg); |
|
5174 } |
|
5175 |
|
5176 /** |
|
5177 * Binds methods of an object to the object itself, overwriting the existing |
|
5178 * method. Method names may be specified as individual arguments or as arrays |
|
5179 * of method names. If no method names are provided all the function properties |
|
5180 * of `object` will be bound. |
|
5181 * |
|
5182 * @static |
|
5183 * @memberOf _ |
|
5184 * @category Functions |
|
5185 * @param {Object} object The object to bind and assign the bound methods to. |
|
5186 * @param {...string} [methodName] The object method names to |
|
5187 * bind, specified as individual method names or arrays of method names. |
|
5188 * @returns {Object} Returns `object`. |
|
5189 * @example |
|
5190 * |
|
5191 * var view = { |
|
5192 * 'label': 'docs', |
|
5193 * 'onClick': function() { console.log('clicked ' + this.label); } |
|
5194 * }; |
|
5195 * |
|
5196 * _.bindAll(view); |
|
5197 * jQuery('#docs').on('click', view.onClick); |
|
5198 * // => logs 'clicked docs', when the button is clicked |
|
5199 */ |
|
5200 function bindAll(object) { |
|
5201 var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), |
|
5202 index = -1, |
|
5203 length = funcs.length; |
|
5204 |
|
5205 while (++index < length) { |
|
5206 var key = funcs[index]; |
|
5207 object[key] = createWrapper(object[key], 1, null, null, object); |
|
5208 } |
|
5209 return object; |
|
5210 } |
|
5211 |
|
5212 /** |
|
5213 * Creates a function that, when called, invokes the method at `object[key]` |
|
5214 * and prepends any additional `bindKey` arguments to those provided to the bound |
|
5215 * function. This method differs from `_.bind` by allowing bound functions to |
|
5216 * reference methods that will be redefined or don't yet exist. |
|
5217 * See http://michaux.ca/articles/lazy-function-definition-pattern. |
|
5218 * |
|
5219 * @static |
|
5220 * @memberOf _ |
|
5221 * @category Functions |
|
5222 * @param {Object} object The object the method belongs to. |
|
5223 * @param {string} key The key of the method. |
|
5224 * @param {...*} [arg] Arguments to be partially applied. |
|
5225 * @returns {Function} Returns the new bound function. |
|
5226 * @example |
|
5227 * |
|
5228 * var object = { |
|
5229 * 'name': 'fred', |
|
5230 * 'greet': function(greeting) { |
|
5231 * return greeting + ' ' + this.name; |
|
5232 * } |
|
5233 * }; |
|
5234 * |
|
5235 * var func = _.bindKey(object, 'greet', 'hi'); |
|
5236 * func(); |
|
5237 * // => 'hi fred' |
|
5238 * |
|
5239 * object.greet = function(greeting) { |
|
5240 * return greeting + 'ya ' + this.name + '!'; |
|
5241 * }; |
|
5242 * |
|
5243 * func(); |
|
5244 * // => 'hiya fred!' |
|
5245 */ |
|
5246 function bindKey(object, key) { |
|
5247 return arguments.length > 2 |
|
5248 ? createWrapper(key, 19, slice(arguments, 2), null, object) |
|
5249 : createWrapper(key, 3, null, null, object); |
|
5250 } |
|
5251 |
|
5252 /** |
|
5253 * Creates a function that is the composition of the provided functions, |
|
5254 * where each function consumes the return value of the function that follows. |
|
5255 * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. |
|
5256 * Each function is executed with the `this` binding of the composed function. |
|
5257 * |
|
5258 * @static |
|
5259 * @memberOf _ |
|
5260 * @category Functions |
|
5261 * @param {...Function} [func] Functions to compose. |
|
5262 * @returns {Function} Returns the new composed function. |
|
5263 * @example |
|
5264 * |
|
5265 * var realNameMap = { |
|
5266 * 'pebbles': 'penelope' |
|
5267 * }; |
|
5268 * |
|
5269 * var format = function(name) { |
|
5270 * name = realNameMap[name.toLowerCase()] || name; |
|
5271 * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); |
|
5272 * }; |
|
5273 * |
|
5274 * var greet = function(formatted) { |
|
5275 * return 'Hiya ' + formatted + '!'; |
|
5276 * }; |
|
5277 * |
|
5278 * var welcome = _.compose(greet, format); |
|
5279 * welcome('pebbles'); |
|
5280 * // => 'Hiya Penelope!' |
|
5281 */ |
|
5282 function compose() { |
|
5283 var funcs = arguments, |
|
5284 length = funcs.length; |
|
5285 |
|
5286 while (length--) { |
|
5287 if (!isFunction(funcs[length])) { |
|
5288 throw new TypeError; |
|
5289 } |
|
5290 } |
|
5291 return function() { |
|
5292 var args = arguments, |
|
5293 length = funcs.length; |
|
5294 |
|
5295 while (length--) { |
|
5296 args = [funcs[length].apply(this, args)]; |
|
5297 } |
|
5298 return args[0]; |
|
5299 }; |
|
5300 } |
|
5301 |
|
5302 /** |
|
5303 * Creates a function which accepts one or more arguments of `func` that when |
|
5304 * invoked either executes `func` returning its result, if all `func` arguments |
|
5305 * have been provided, or returns a function that accepts one or more of the |
|
5306 * remaining `func` arguments, and so on. The arity of `func` can be specified |
|
5307 * if `func.length` is not sufficient. |
|
5308 * |
|
5309 * @static |
|
5310 * @memberOf _ |
|
5311 * @category Functions |
|
5312 * @param {Function} func The function to curry. |
|
5313 * @param {number} [arity=func.length] The arity of `func`. |
|
5314 * @returns {Function} Returns the new curried function. |
|
5315 * @example |
|
5316 * |
|
5317 * var curried = _.curry(function(a, b, c) { |
|
5318 * console.log(a + b + c); |
|
5319 * }); |
|
5320 * |
|
5321 * curried(1)(2)(3); |
|
5322 * // => 6 |
|
5323 * |
|
5324 * curried(1, 2)(3); |
|
5325 * // => 6 |
|
5326 * |
|
5327 * curried(1, 2, 3); |
|
5328 * // => 6 |
|
5329 */ |
|
5330 function curry(func, arity) { |
|
5331 arity = typeof arity == 'number' ? arity : (+arity || func.length); |
|
5332 return createWrapper(func, 4, null, null, null, arity); |
|
5333 } |
|
5334 |
|
5335 /** |
|
5336 * Creates a function that will delay the execution of `func` until after |
|
5337 * `wait` milliseconds have elapsed since the last time it was invoked. |
|
5338 * Provide an options object to indicate that `func` should be invoked on |
|
5339 * the leading and/or trailing edge of the `wait` timeout. Subsequent calls |
|
5340 * to the debounced function will return the result of the last `func` call. |
|
5341 * |
|
5342 * Note: If `leading` and `trailing` options are `true` `func` will be called |
|
5343 * on the trailing edge of the timeout only if the the debounced function is |
|
5344 * invoked more than once during the `wait` timeout. |
|
5345 * |
|
5346 * @static |
|
5347 * @memberOf _ |
|
5348 * @category Functions |
|
5349 * @param {Function} func The function to debounce. |
|
5350 * @param {number} wait The number of milliseconds to delay. |
|
5351 * @param {Object} [options] The options object. |
|
5352 * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. |
|
5353 * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. |
|
5354 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. |
|
5355 * @returns {Function} Returns the new debounced function. |
|
5356 * @example |
|
5357 * |
|
5358 * // avoid costly calculations while the window size is in flux |
|
5359 * var lazyLayout = _.debounce(calculateLayout, 150); |
|
5360 * jQuery(window).on('resize', lazyLayout); |
|
5361 * |
|
5362 * // execute `sendMail` when the click event is fired, debouncing subsequent calls |
|
5363 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { |
|
5364 * 'leading': true, |
|
5365 * 'trailing': false |
|
5366 * }); |
|
5367 * |
|
5368 * // ensure `batchLog` is executed once after 1 second of debounced calls |
|
5369 * var source = new EventSource('/stream'); |
|
5370 * source.addEventListener('message', _.debounce(batchLog, 250, { |
|
5371 * 'maxWait': 1000 |
|
5372 * }, false); |
|
5373 */ |
|
5374 function debounce(func, wait, options) { |
|
5375 var args, |
|
5376 maxTimeoutId, |
|
5377 result, |
|
5378 stamp, |
|
5379 thisArg, |
|
5380 timeoutId, |
|
5381 trailingCall, |
|
5382 lastCalled = 0, |
|
5383 maxWait = false, |
|
5384 trailing = true; |
|
5385 |
|
5386 if (!isFunction(func)) { |
|
5387 throw new TypeError; |
|
5388 } |
|
5389 wait = nativeMax(0, wait) || 0; |
|
5390 if (options === true) { |
|
5391 var leading = true; |
|
5392 trailing = false; |
|
5393 } else if (isObject(options)) { |
|
5394 leading = options.leading; |
|
5395 maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); |
|
5396 trailing = 'trailing' in options ? options.trailing : trailing; |
|
5397 } |
|
5398 var delayed = function() { |
|
5399 var remaining = wait - (now() - stamp); |
|
5400 if (remaining <= 0) { |
|
5401 if (maxTimeoutId) { |
|
5402 clearTimeout(maxTimeoutId); |
|
5403 } |
|
5404 var isCalled = trailingCall; |
|
5405 maxTimeoutId = timeoutId = trailingCall = undefined; |
|
5406 if (isCalled) { |
|
5407 lastCalled = now(); |
|
5408 result = func.apply(thisArg, args); |
|
5409 if (!timeoutId && !maxTimeoutId) { |
|
5410 args = thisArg = null; |
|
5411 } |
|
5412 } |
|
5413 } else { |
|
5414 timeoutId = setTimeout(delayed, remaining); |
|
5415 } |
|
5416 }; |
|
5417 |
|
5418 var maxDelayed = function() { |
|
5419 if (timeoutId) { |
|
5420 clearTimeout(timeoutId); |
|
5421 } |
|
5422 maxTimeoutId = timeoutId = trailingCall = undefined; |
|
5423 if (trailing || (maxWait !== wait)) { |
|
5424 lastCalled = now(); |
|
5425 result = func.apply(thisArg, args); |
|
5426 if (!timeoutId && !maxTimeoutId) { |
|
5427 args = thisArg = null; |
|
5428 } |
|
5429 } |
|
5430 }; |
|
5431 |
|
5432 return function() { |
|
5433 args = arguments; |
|
5434 stamp = now(); |
|
5435 thisArg = this; |
|
5436 trailingCall = trailing && (timeoutId || !leading); |
|
5437 |
|
5438 if (maxWait === false) { |
|
5439 var leadingCall = leading && !timeoutId; |
|
5440 } else { |
|
5441 if (!maxTimeoutId && !leading) { |
|
5442 lastCalled = stamp; |
|
5443 } |
|
5444 var remaining = maxWait - (stamp - lastCalled), |
|
5445 isCalled = remaining <= 0; |
|
5446 |
|
5447 if (isCalled) { |
|
5448 if (maxTimeoutId) { |
|
5449 maxTimeoutId = clearTimeout(maxTimeoutId); |
|
5450 } |
|
5451 lastCalled = stamp; |
|
5452 result = func.apply(thisArg, args); |
|
5453 } |
|
5454 else if (!maxTimeoutId) { |
|
5455 maxTimeoutId = setTimeout(maxDelayed, remaining); |
|
5456 } |
|
5457 } |
|
5458 if (isCalled && timeoutId) { |
|
5459 timeoutId = clearTimeout(timeoutId); |
|
5460 } |
|
5461 else if (!timeoutId && wait !== maxWait) { |
|
5462 timeoutId = setTimeout(delayed, wait); |
|
5463 } |
|
5464 if (leadingCall) { |
|
5465 isCalled = true; |
|
5466 result = func.apply(thisArg, args); |
|
5467 } |
|
5468 if (isCalled && !timeoutId && !maxTimeoutId) { |
|
5469 args = thisArg = null; |
|
5470 } |
|
5471 return result; |
|
5472 }; |
|
5473 } |
|
5474 |
|
5475 /** |
|
5476 * Defers executing the `func` function until the current call stack has cleared. |
|
5477 * Additional arguments will be provided to `func` when it is invoked. |
|
5478 * |
|
5479 * @static |
|
5480 * @memberOf _ |
|
5481 * @category Functions |
|
5482 * @param {Function} func The function to defer. |
|
5483 * @param {...*} [arg] Arguments to invoke the function with. |
|
5484 * @returns {number} Returns the timer id. |
|
5485 * @example |
|
5486 * |
|
5487 * _.defer(function(text) { console.log(text); }, 'deferred'); |
|
5488 * // logs 'deferred' after one or more milliseconds |
|
5489 */ |
|
5490 function defer(func) { |
|
5491 if (!isFunction(func)) { |
|
5492 throw new TypeError; |
|
5493 } |
|
5494 var args = slice(arguments, 1); |
|
5495 return setTimeout(function() { func.apply(undefined, args); }, 1); |
|
5496 } |
|
5497 |
|
5498 /** |
|
5499 * Executes the `func` function after `wait` milliseconds. Additional arguments |
|
5500 * will be provided to `func` when it is invoked. |
|
5501 * |
|
5502 * @static |
|
5503 * @memberOf _ |
|
5504 * @category Functions |
|
5505 * @param {Function} func The function to delay. |
|
5506 * @param {number} wait The number of milliseconds to delay execution. |
|
5507 * @param {...*} [arg] Arguments to invoke the function with. |
|
5508 * @returns {number} Returns the timer id. |
|
5509 * @example |
|
5510 * |
|
5511 * _.delay(function(text) { console.log(text); }, 1000, 'later'); |
|
5512 * // => logs 'later' after one second |
|
5513 */ |
|
5514 function delay(func, wait) { |
|
5515 if (!isFunction(func)) { |
|
5516 throw new TypeError; |
|
5517 } |
|
5518 var args = slice(arguments, 2); |
|
5519 return setTimeout(function() { func.apply(undefined, args); }, wait); |
|
5520 } |
|
5521 |
|
5522 /** |
|
5523 * Creates a function that memoizes the result of `func`. If `resolver` is |
|
5524 * provided it will be used to determine the cache key for storing the result |
|
5525 * based on the arguments provided to the memoized function. By default, the |
|
5526 * first argument provided to the memoized function is used as the cache key. |
|
5527 * The `func` is executed with the `this` binding of the memoized function. |
|
5528 * The result cache is exposed as the `cache` property on the memoized function. |
|
5529 * |
|
5530 * @static |
|
5531 * @memberOf _ |
|
5532 * @category Functions |
|
5533 * @param {Function} func The function to have its output memoized. |
|
5534 * @param {Function} [resolver] A function used to resolve the cache key. |
|
5535 * @returns {Function} Returns the new memoizing function. |
|
5536 * @example |
|
5537 * |
|
5538 * var fibonacci = _.memoize(function(n) { |
|
5539 * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); |
|
5540 * }); |
|
5541 * |
|
5542 * fibonacci(9) |
|
5543 * // => 34 |
|
5544 * |
|
5545 * var data = { |
|
5546 * 'fred': { 'name': 'fred', 'age': 40 }, |
|
5547 * 'pebbles': { 'name': 'pebbles', 'age': 1 } |
|
5548 * }; |
|
5549 * |
|
5550 * // modifying the result cache |
|
5551 * var get = _.memoize(function(name) { return data[name]; }, _.identity); |
|
5552 * get('pebbles'); |
|
5553 * // => { 'name': 'pebbles', 'age': 1 } |
|
5554 * |
|
5555 * get.cache.pebbles.name = 'penelope'; |
|
5556 * get('pebbles'); |
|
5557 * // => { 'name': 'penelope', 'age': 1 } |
|
5558 */ |
|
5559 function memoize(func, resolver) { |
|
5560 if (!isFunction(func)) { |
|
5561 throw new TypeError; |
|
5562 } |
|
5563 var memoized = function() { |
|
5564 var cache = memoized.cache, |
|
5565 key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; |
|
5566 |
|
5567 return hasOwnProperty.call(cache, key) |
|
5568 ? cache[key] |
|
5569 : (cache[key] = func.apply(this, arguments)); |
|
5570 } |
|
5571 memoized.cache = {}; |
|
5572 return memoized; |
|
5573 } |
|
5574 |
|
5575 /** |
|
5576 * Creates a function that is restricted to execute `func` once. Repeat calls to |
|
5577 * the function will return the value of the first call. The `func` is executed |
|
5578 * with the `this` binding of the created function. |
|
5579 * |
|
5580 * @static |
|
5581 * @memberOf _ |
|
5582 * @category Functions |
|
5583 * @param {Function} func The function to restrict. |
|
5584 * @returns {Function} Returns the new restricted function. |
|
5585 * @example |
|
5586 * |
|
5587 * var initialize = _.once(createApplication); |
|
5588 * initialize(); |
|
5589 * initialize(); |
|
5590 * // `initialize` executes `createApplication` once |
|
5591 */ |
|
5592 function once(func) { |
|
5593 var ran, |
|
5594 result; |
|
5595 |
|
5596 if (!isFunction(func)) { |
|
5597 throw new TypeError; |
|
5598 } |
|
5599 return function() { |
|
5600 if (ran) { |
|
5601 return result; |
|
5602 } |
|
5603 ran = true; |
|
5604 result = func.apply(this, arguments); |
|
5605 |
|
5606 // clear the `func` variable so the function may be garbage collected |
|
5607 func = null; |
|
5608 return result; |
|
5609 }; |
|
5610 } |
|
5611 |
|
5612 /** |
|
5613 * Creates a function that, when called, invokes `func` with any additional |
|
5614 * `partial` arguments prepended to those provided to the new function. This |
|
5615 * method is similar to `_.bind` except it does **not** alter the `this` binding. |
|
5616 * |
|
5617 * @static |
|
5618 * @memberOf _ |
|
5619 * @category Functions |
|
5620 * @param {Function} func The function to partially apply arguments to. |
|
5621 * @param {...*} [arg] Arguments to be partially applied. |
|
5622 * @returns {Function} Returns the new partially applied function. |
|
5623 * @example |
|
5624 * |
|
5625 * var greet = function(greeting, name) { return greeting + ' ' + name; }; |
|
5626 * var hi = _.partial(greet, 'hi'); |
|
5627 * hi('fred'); |
|
5628 * // => 'hi fred' |
|
5629 */ |
|
5630 function partial(func) { |
|
5631 return createWrapper(func, 16, slice(arguments, 1)); |
|
5632 } |
|
5633 |
|
5634 /** |
|
5635 * This method is like `_.partial` except that `partial` arguments are |
|
5636 * appended to those provided to the new function. |
|
5637 * |
|
5638 * @static |
|
5639 * @memberOf _ |
|
5640 * @category Functions |
|
5641 * @param {Function} func The function to partially apply arguments to. |
|
5642 * @param {...*} [arg] Arguments to be partially applied. |
|
5643 * @returns {Function} Returns the new partially applied function. |
|
5644 * @example |
|
5645 * |
|
5646 * var defaultsDeep = _.partialRight(_.merge, _.defaults); |
|
5647 * |
|
5648 * var options = { |
|
5649 * 'variable': 'data', |
|
5650 * 'imports': { 'jq': $ } |
|
5651 * }; |
|
5652 * |
|
5653 * defaultsDeep(options, _.templateSettings); |
|
5654 * |
|
5655 * options.variable |
|
5656 * // => 'data' |
|
5657 * |
|
5658 * options.imports |
|
5659 * // => { '_': _, 'jq': $ } |
|
5660 */ |
|
5661 function partialRight(func) { |
|
5662 return createWrapper(func, 32, null, slice(arguments, 1)); |
|
5663 } |
|
5664 |
|
5665 /** |
|
5666 * Creates a function that, when executed, will only call the `func` function |
|
5667 * at most once per every `wait` milliseconds. Provide an options object to |
|
5668 * indicate that `func` should be invoked on the leading and/or trailing edge |
|
5669 * of the `wait` timeout. Subsequent calls to the throttled function will |
|
5670 * return the result of the last `func` call. |
|
5671 * |
|
5672 * Note: If `leading` and `trailing` options are `true` `func` will be called |
|
5673 * on the trailing edge of the timeout only if the the throttled function is |
|
5674 * invoked more than once during the `wait` timeout. |
|
5675 * |
|
5676 * @static |
|
5677 * @memberOf _ |
|
5678 * @category Functions |
|
5679 * @param {Function} func The function to throttle. |
|
5680 * @param {number} wait The number of milliseconds to throttle executions to. |
|
5681 * @param {Object} [options] The options object. |
|
5682 * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. |
|
5683 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. |
|
5684 * @returns {Function} Returns the new throttled function. |
|
5685 * @example |
|
5686 * |
|
5687 * // avoid excessively updating the position while scrolling |
|
5688 * var throttled = _.throttle(updatePosition, 100); |
|
5689 * jQuery(window).on('scroll', throttled); |
|
5690 * |
|
5691 * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes |
|
5692 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { |
|
5693 * 'trailing': false |
|
5694 * })); |
|
5695 */ |
|
5696 function throttle(func, wait, options) { |
|
5697 var leading = true, |
|
5698 trailing = true; |
|
5699 |
|
5700 if (!isFunction(func)) { |
|
5701 throw new TypeError; |
|
5702 } |
|
5703 if (options === false) { |
|
5704 leading = false; |
|
5705 } else if (isObject(options)) { |
|
5706 leading = 'leading' in options ? options.leading : leading; |
|
5707 trailing = 'trailing' in options ? options.trailing : trailing; |
|
5708 } |
|
5709 debounceOptions.leading = leading; |
|
5710 debounceOptions.maxWait = wait; |
|
5711 debounceOptions.trailing = trailing; |
|
5712 |
|
5713 return debounce(func, wait, debounceOptions); |
|
5714 } |
|
5715 |
|
5716 /** |
|
5717 * Creates a function that provides `value` to the wrapper function as its |
|
5718 * first argument. Additional arguments provided to the function are appended |
|
5719 * to those provided to the wrapper function. The wrapper is executed with |
|
5720 * the `this` binding of the created function. |
|
5721 * |
|
5722 * @static |
|
5723 * @memberOf _ |
|
5724 * @category Functions |
|
5725 * @param {*} value The value to wrap. |
|
5726 * @param {Function} wrapper The wrapper function. |
|
5727 * @returns {Function} Returns the new function. |
|
5728 * @example |
|
5729 * |
|
5730 * var p = _.wrap(_.escape, function(func, text) { |
|
5731 * return '<p>' + func(text) + '</p>'; |
|
5732 * }); |
|
5733 * |
|
5734 * p('Fred, Wilma, & Pebbles'); |
|
5735 * // => '<p>Fred, Wilma, & Pebbles</p>' |
|
5736 */ |
|
5737 function wrap(value, wrapper) { |
|
5738 return createWrapper(wrapper, 16, [value]); |
|
5739 } |
|
5740 |
|
5741 /*--------------------------------------------------------------------------*/ |
|
5742 |
|
5743 /** |
|
5744 * Creates a function that returns `value`. |
|
5745 * |
|
5746 * @static |
|
5747 * @memberOf _ |
|
5748 * @category Utilities |
|
5749 * @param {*} value The value to return from the new function. |
|
5750 * @returns {Function} Returns the new function. |
|
5751 * @example |
|
5752 * |
|
5753 * var object = { 'name': 'fred' }; |
|
5754 * var getter = _.constant(object); |
|
5755 * getter() === object; |
|
5756 * // => true |
|
5757 */ |
|
5758 function constant(value) { |
|
5759 return function() { |
|
5760 return value; |
|
5761 }; |
|
5762 } |
|
5763 |
|
5764 /** |
|
5765 * Produces a callback bound to an optional `thisArg`. If `func` is a property |
|
5766 * name the created callback will return the property value for a given element. |
|
5767 * If `func` is an object the created callback will return `true` for elements |
|
5768 * that contain the equivalent object properties, otherwise it will return `false`. |
|
5769 * |
|
5770 * @static |
|
5771 * @memberOf _ |
|
5772 * @category Utilities |
|
5773 * @param {*} [func=identity] The value to convert to a callback. |
|
5774 * @param {*} [thisArg] The `this` binding of the created callback. |
|
5775 * @param {number} [argCount] The number of arguments the callback accepts. |
|
5776 * @returns {Function} Returns a callback function. |
|
5777 * @example |
|
5778 * |
|
5779 * var characters = [ |
|
5780 * { 'name': 'barney', 'age': 36 }, |
|
5781 * { 'name': 'fred', 'age': 40 } |
|
5782 * ]; |
|
5783 * |
|
5784 * // wrap to create custom callback shorthands |
|
5785 * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { |
|
5786 * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); |
|
5787 * return !match ? func(callback, thisArg) : function(object) { |
|
5788 * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; |
|
5789 * }; |
|
5790 * }); |
|
5791 * |
|
5792 * _.filter(characters, 'age__gt38'); |
|
5793 * // => [{ 'name': 'fred', 'age': 40 }] |
|
5794 */ |
|
5795 function createCallback(func, thisArg, argCount) { |
|
5796 var type = typeof func; |
|
5797 if (func == null || type == 'function') { |
|
5798 return baseCreateCallback(func, thisArg, argCount); |
|
5799 } |
|
5800 // handle "_.pluck" style callback shorthands |
|
5801 if (type != 'object') { |
|
5802 return property(func); |
|
5803 } |
|
5804 var props = keys(func), |
|
5805 key = props[0], |
|
5806 a = func[key]; |
|
5807 |
|
5808 // handle "_.where" style callback shorthands |
|
5809 if (props.length == 1 && a === a && !isObject(a)) { |
|
5810 // fast path the common case of providing an object with a single |
|
5811 // property containing a primitive value |
|
5812 return function(object) { |
|
5813 var b = object[key]; |
|
5814 return a === b && (a !== 0 || (1 / a == 1 / b)); |
|
5815 }; |
|
5816 } |
|
5817 return function(object) { |
|
5818 var length = props.length, |
|
5819 result = false; |
|
5820 |
|
5821 while (length--) { |
|
5822 if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { |
|
5823 break; |
|
5824 } |
|
5825 } |
|
5826 return result; |
|
5827 }; |
|
5828 } |
|
5829 |
|
5830 /** |
|
5831 * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their |
|
5832 * corresponding HTML entities. |
|
5833 * |
|
5834 * @static |
|
5835 * @memberOf _ |
|
5836 * @category Utilities |
|
5837 * @param {string} string The string to escape. |
|
5838 * @returns {string} Returns the escaped string. |
|
5839 * @example |
|
5840 * |
|
5841 * _.escape('Fred, Wilma, & Pebbles'); |
|
5842 * // => 'Fred, Wilma, & Pebbles' |
|
5843 */ |
|
5844 function escape(string) { |
|
5845 return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); |
|
5846 } |
|
5847 |
|
5848 /** |
|
5849 * This method returns the first argument provided to it. |
|
5850 * |
|
5851 * @static |
|
5852 * @memberOf _ |
|
5853 * @category Utilities |
|
5854 * @param {*} value Any value. |
|
5855 * @returns {*} Returns `value`. |
|
5856 * @example |
|
5857 * |
|
5858 * var object = { 'name': 'fred' }; |
|
5859 * _.identity(object) === object; |
|
5860 * // => true |
|
5861 */ |
|
5862 function identity(value) { |
|
5863 return value; |
|
5864 } |
|
5865 |
|
5866 /** |
|
5867 * Adds function properties of a source object to the destination object. |
|
5868 * If `object` is a function methods will be added to its prototype as well. |
|
5869 * |
|
5870 * @static |
|
5871 * @memberOf _ |
|
5872 * @category Utilities |
|
5873 * @param {Function|Object} [object=lodash] object The destination object. |
|
5874 * @param {Object} source The object of functions to add. |
|
5875 * @param {Object} [options] The options object. |
|
5876 * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. |
|
5877 * @example |
|
5878 * |
|
5879 * function capitalize(string) { |
|
5880 * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); |
|
5881 * } |
|
5882 * |
|
5883 * _.mixin({ 'capitalize': capitalize }); |
|
5884 * _.capitalize('fred'); |
|
5885 * // => 'Fred' |
|
5886 * |
|
5887 * _('fred').capitalize().value(); |
|
5888 * // => 'Fred' |
|
5889 * |
|
5890 * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); |
|
5891 * _('fred').capitalize(); |
|
5892 * // => 'Fred' |
|
5893 */ |
|
5894 function mixin(object, source, options) { |
|
5895 var chain = true, |
|
5896 methodNames = source && functions(source); |
|
5897 |
|
5898 if (!source || (!options && !methodNames.length)) { |
|
5899 if (options == null) { |
|
5900 options = source; |
|
5901 } |
|
5902 ctor = lodashWrapper; |
|
5903 source = object; |
|
5904 object = lodash; |
|
5905 methodNames = functions(source); |
|
5906 } |
|
5907 if (options === false) { |
|
5908 chain = false; |
|
5909 } else if (isObject(options) && 'chain' in options) { |
|
5910 chain = options.chain; |
|
5911 } |
|
5912 var ctor = object, |
|
5913 isFunc = isFunction(ctor); |
|
5914 |
|
5915 forEach(methodNames, function(methodName) { |
|
5916 var func = object[methodName] = source[methodName]; |
|
5917 if (isFunc) { |
|
5918 ctor.prototype[methodName] = function() { |
|
5919 var chainAll = this.__chain__, |
|
5920 value = this.__wrapped__, |
|
5921 args = [value]; |
|
5922 |
|
5923 push.apply(args, arguments); |
|
5924 var result = func.apply(object, args); |
|
5925 if (chain || chainAll) { |
|
5926 if (value === result && isObject(result)) { |
|
5927 return this; |
|
5928 } |
|
5929 result = new ctor(result); |
|
5930 result.__chain__ = chainAll; |
|
5931 } |
|
5932 return result; |
|
5933 }; |
|
5934 } |
|
5935 }); |
|
5936 } |
|
5937 |
|
5938 /** |
|
5939 * Reverts the '_' variable to its previous value and returns a reference to |
|
5940 * the `lodash` function. |
|
5941 * |
|
5942 * @static |
|
5943 * @memberOf _ |
|
5944 * @category Utilities |
|
5945 * @returns {Function} Returns the `lodash` function. |
|
5946 * @example |
|
5947 * |
|
5948 * var lodash = _.noConflict(); |
|
5949 */ |
|
5950 function noConflict() { |
|
5951 context._ = oldDash; |
|
5952 return this; |
|
5953 } |
|
5954 |
|
5955 /** |
|
5956 * A no-operation function. |
|
5957 * |
|
5958 * @static |
|
5959 * @memberOf _ |
|
5960 * @category Utilities |
|
5961 * @example |
|
5962 * |
|
5963 * var object = { 'name': 'fred' }; |
|
5964 * _.noop(object) === undefined; |
|
5965 * // => true |
|
5966 */ |
|
5967 function noop() { |
|
5968 // no operation performed |
|
5969 } |
|
5970 |
|
5971 /** |
|
5972 * Gets the number of milliseconds that have elapsed since the Unix epoch |
|
5973 * (1 January 1970 00:00:00 UTC). |
|
5974 * |
|
5975 * @static |
|
5976 * @memberOf _ |
|
5977 * @category Utilities |
|
5978 * @example |
|
5979 * |
|
5980 * var stamp = _.now(); |
|
5981 * _.defer(function() { console.log(_.now() - stamp); }); |
|
5982 * // => logs the number of milliseconds it took for the deferred function to be called |
|
5983 */ |
|
5984 var now = isNative(now = Date.now) && now || function() { |
|
5985 return new Date().getTime(); |
|
5986 }; |
|
5987 |
|
5988 /** |
|
5989 * Converts the given value into an integer of the specified radix. |
|
5990 * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the |
|
5991 * `value` is a hexadecimal, in which case a `radix` of `16` is used. |
|
5992 * |
|
5993 * Note: This method avoids differences in native ES3 and ES5 `parseInt` |
|
5994 * implementations. See http://es5.github.io/#E. |
|
5995 * |
|
5996 * @static |
|
5997 * @memberOf _ |
|
5998 * @category Utilities |
|
5999 * @param {string} value The value to parse. |
|
6000 * @param {number} [radix] The radix used to interpret the value to parse. |
|
6001 * @returns {number} Returns the new integer value. |
|
6002 * @example |
|
6003 * |
|
6004 * _.parseInt('08'); |
|
6005 * // => 8 |
|
6006 */ |
|
6007 var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { |
|
6008 // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` |
|
6009 return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); |
|
6010 }; |
|
6011 |
|
6012 /** |
|
6013 * Creates a "_.pluck" style function, which returns the `key` value of a |
|
6014 * given object. |
|
6015 * |
|
6016 * @static |
|
6017 * @memberOf _ |
|
6018 * @category Utilities |
|
6019 * @param {string} key The name of the property to retrieve. |
|
6020 * @returns {Function} Returns the new function. |
|
6021 * @example |
|
6022 * |
|
6023 * var characters = [ |
|
6024 * { 'name': 'fred', 'age': 40 }, |
|
6025 * { 'name': 'barney', 'age': 36 } |
|
6026 * ]; |
|
6027 * |
|
6028 * var getName = _.property('name'); |
|
6029 * |
|
6030 * _.map(characters, getName); |
|
6031 * // => ['barney', 'fred'] |
|
6032 * |
|
6033 * _.sortBy(characters, getName); |
|
6034 * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] |
|
6035 */ |
|
6036 function property(key) { |
|
6037 return function(object) { |
|
6038 return object[key]; |
|
6039 }; |
|
6040 } |
|
6041 |
|
6042 /** |
|
6043 * Produces a random number between `min` and `max` (inclusive). If only one |
|
6044 * argument is provided a number between `0` and the given number will be |
|
6045 * returned. If `floating` is truey or either `min` or `max` are floats a |
|
6046 * floating-point number will be returned instead of an integer. |
|
6047 * |
|
6048 * @static |
|
6049 * @memberOf _ |
|
6050 * @category Utilities |
|
6051 * @param {number} [min=0] The minimum possible value. |
|
6052 * @param {number} [max=1] The maximum possible value. |
|
6053 * @param {boolean} [floating=false] Specify returning a floating-point number. |
|
6054 * @returns {number} Returns a random number. |
|
6055 * @example |
|
6056 * |
|
6057 * _.random(0, 5); |
|
6058 * // => an integer between 0 and 5 |
|
6059 * |
|
6060 * _.random(5); |
|
6061 * // => also an integer between 0 and 5 |
|
6062 * |
|
6063 * _.random(5, true); |
|
6064 * // => a floating-point number between 0 and 5 |
|
6065 * |
|
6066 * _.random(1.2, 5.2); |
|
6067 * // => a floating-point number between 1.2 and 5.2 |
|
6068 */ |
|
6069 function random(min, max, floating) { |
|
6070 var noMin = min == null, |
|
6071 noMax = max == null; |
|
6072 |
|
6073 if (floating == null) { |
|
6074 if (typeof min == 'boolean' && noMax) { |
|
6075 floating = min; |
|
6076 min = 1; |
|
6077 } |
|
6078 else if (!noMax && typeof max == 'boolean') { |
|
6079 floating = max; |
|
6080 noMax = true; |
|
6081 } |
|
6082 } |
|
6083 if (noMin && noMax) { |
|
6084 max = 1; |
|
6085 } |
|
6086 min = +min || 0; |
|
6087 if (noMax) { |
|
6088 max = min; |
|
6089 min = 0; |
|
6090 } else { |
|
6091 max = +max || 0; |
|
6092 } |
|
6093 if (floating || min % 1 || max % 1) { |
|
6094 var rand = nativeRandom(); |
|
6095 return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); |
|
6096 } |
|
6097 return baseRandom(min, max); |
|
6098 } |
|
6099 |
|
6100 /** |
|
6101 * Resolves the value of property `key` on `object`. If `key` is a function |
|
6102 * it will be invoked with the `this` binding of `object` and its result returned, |
|
6103 * else the property value is returned. If `object` is falsey then `undefined` |
|
6104 * is returned. |
|
6105 * |
|
6106 * @static |
|
6107 * @memberOf _ |
|
6108 * @category Utilities |
|
6109 * @param {Object} object The object to inspect. |
|
6110 * @param {string} key The name of the property to resolve. |
|
6111 * @returns {*} Returns the resolved value. |
|
6112 * @example |
|
6113 * |
|
6114 * var object = { |
|
6115 * 'cheese': 'crumpets', |
|
6116 * 'stuff': function() { |
|
6117 * return 'nonsense'; |
|
6118 * } |
|
6119 * }; |
|
6120 * |
|
6121 * _.result(object, 'cheese'); |
|
6122 * // => 'crumpets' |
|
6123 * |
|
6124 * _.result(object, 'stuff'); |
|
6125 * // => 'nonsense' |
|
6126 */ |
|
6127 function result(object, key) { |
|
6128 if (object) { |
|
6129 var value = object[key]; |
|
6130 return isFunction(value) ? object[key]() : value; |
|
6131 } |
|
6132 } |
|
6133 |
|
6134 /** |
|
6135 * A micro-templating method that handles arbitrary delimiters, preserves |
|
6136 * whitespace, and correctly escapes quotes within interpolated code. |
|
6137 * |
|
6138 * Note: In the development build, `_.template` utilizes sourceURLs for easier |
|
6139 * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl |
|
6140 * |
|
6141 * For more information on precompiling templates see: |
|
6142 * http://lodash.com/custom-builds |
|
6143 * |
|
6144 * For more information on Chrome extension sandboxes see: |
|
6145 * http://developer.chrome.com/stable/extensions/sandboxingEval.html |
|
6146 * |
|
6147 * @static |
|
6148 * @memberOf _ |
|
6149 * @category Utilities |
|
6150 * @param {string} text The template text. |
|
6151 * @param {Object} data The data object used to populate the text. |
|
6152 * @param {Object} [options] The options object. |
|
6153 * @param {RegExp} [options.escape] The "escape" delimiter. |
|
6154 * @param {RegExp} [options.evaluate] The "evaluate" delimiter. |
|
6155 * @param {Object} [options.imports] An object to import into the template as local variables. |
|
6156 * @param {RegExp} [options.interpolate] The "interpolate" delimiter. |
|
6157 * @param {string} [sourceURL] The sourceURL of the template's compiled source. |
|
6158 * @param {string} [variable] The data object variable name. |
|
6159 * @returns {Function|string} Returns a compiled function when no `data` object |
|
6160 * is given, else it returns the interpolated text. |
|
6161 * @example |
|
6162 * |
|
6163 * // using the "interpolate" delimiter to create a compiled template |
|
6164 * var compiled = _.template('hello <%= name %>'); |
|
6165 * compiled({ 'name': 'fred' }); |
|
6166 * // => 'hello fred' |
|
6167 * |
|
6168 * // using the "escape" delimiter to escape HTML in data property values |
|
6169 * _.template('<b><%- value %></b>', { 'value': '<script>' }); |
|
6170 * // => '<b><script></b>' |
|
6171 * |
|
6172 * // using the "evaluate" delimiter to generate HTML |
|
6173 * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>'; |
|
6174 * _.template(list, { 'people': ['fred', 'barney'] }); |
|
6175 * // => '<li>fred</li><li>barney</li>' |
|
6176 * |
|
6177 * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter |
|
6178 * _.template('hello ${ name }', { 'name': 'pebbles' }); |
|
6179 * // => 'hello pebbles' |
|
6180 * |
|
6181 * // using the internal `print` function in "evaluate" delimiters |
|
6182 * _.template('<% print("hello " + name); %>!', { 'name': 'barney' }); |
|
6183 * // => 'hello barney!' |
|
6184 * |
|
6185 * // using a custom template delimiters |
|
6186 * _.templateSettings = { |
|
6187 * 'interpolate': /{{([\s\S]+?)}}/g |
|
6188 * }; |
|
6189 * |
|
6190 * _.template('hello {{ name }}!', { 'name': 'mustache' }); |
|
6191 * // => 'hello mustache!' |
|
6192 * |
|
6193 * // using the `imports` option to import jQuery |
|
6194 * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>'; |
|
6195 * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } }); |
|
6196 * // => '<li>fred</li><li>barney</li>' |
|
6197 * |
|
6198 * // using the `sourceURL` option to specify a custom sourceURL for the template |
|
6199 * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' }); |
|
6200 * compiled(data); |
|
6201 * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector |
|
6202 * |
|
6203 * // using the `variable` option to ensure a with-statement isn't used in the compiled template |
|
6204 * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' }); |
|
6205 * compiled.source; |
|
6206 * // => function(data) { |
|
6207 * var __t, __p = '', __e = _.escape; |
|
6208 * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!'; |
|
6209 * return __p; |
|
6210 * } |
|
6211 * |
|
6212 * // using the `source` property to inline compiled templates for meaningful |
|
6213 * // line numbers in error messages and a stack trace |
|
6214 * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ |
|
6215 * var JST = {\ |
|
6216 * "main": ' + _.template(mainText).source + '\ |
|
6217 * };\ |
|
6218 * '); |
|
6219 */ |
|
6220 function template(text, data, options) { |
|
6221 // based on John Resig's `tmpl` implementation |
|
6222 // http://ejohn.org/blog/javascript-micro-templating/ |
|
6223 // and Laura Doktorova's doT.js |
|
6224 // https://github.com/olado/doT |
|
6225 var settings = lodash.templateSettings; |
|
6226 text = String(text || ''); |
|
6227 |
|
6228 // avoid missing dependencies when `iteratorTemplate` is not defined |
|
6229 options = defaults({}, options, settings); |
|
6230 |
|
6231 var imports = defaults({}, options.imports, settings.imports), |
|
6232 importsKeys = keys(imports), |
|
6233 importsValues = values(imports); |
|
6234 |
|
6235 var isEvaluating, |
|
6236 index = 0, |
|
6237 interpolate = options.interpolate || reNoMatch, |
|
6238 source = "__p += '"; |
|
6239 |
|
6240 // compile the regexp to match each delimiter |
|
6241 var reDelimiters = RegExp( |
|
6242 (options.escape || reNoMatch).source + '|' + |
|
6243 interpolate.source + '|' + |
|
6244 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' + |
|
6245 (options.evaluate || reNoMatch).source + '|$' |
|
6246 , 'g'); |
|
6247 |
|
6248 text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { |
|
6249 interpolateValue || (interpolateValue = esTemplateValue); |
|
6250 |
|
6251 // escape characters that cannot be included in string literals |
|
6252 source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar); |
|
6253 |
|
6254 // replace delimiters with snippets |
|
6255 if (escapeValue) { |
|
6256 source += "' +\n__e(" + escapeValue + ") +\n'"; |
|
6257 } |
|
6258 if (evaluateValue) { |
|
6259 isEvaluating = true; |
|
6260 source += "';\n" + evaluateValue + ";\n__p += '"; |
|
6261 } |
|
6262 if (interpolateValue) { |
|
6263 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'"; |
|
6264 } |
|
6265 index = offset + match.length; |
|
6266 |
|
6267 // the JS engine embedded in Adobe products requires returning the `match` |
|
6268 // string in order to produce the correct `offset` value |
|
6269 return match; |
|
6270 }); |
|
6271 |
|
6272 source += "';\n"; |
|
6273 |
|
6274 // if `variable` is not specified, wrap a with-statement around the generated |
|
6275 // code to add the data object to the top of the scope chain |
|
6276 var variable = options.variable, |
|
6277 hasVariable = variable; |
|
6278 |
|
6279 if (!hasVariable) { |
|
6280 variable = 'obj'; |
|
6281 source = 'with (' + variable + ') {\n' + source + '\n}\n'; |
|
6282 } |
|
6283 // cleanup code by stripping empty strings |
|
6284 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source) |
|
6285 .replace(reEmptyStringMiddle, '$1') |
|
6286 .replace(reEmptyStringTrailing, '$1;'); |
|
6287 |
|
6288 // frame code as the function body |
|
6289 source = 'function(' + variable + ') {\n' + |
|
6290 (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') + |
|
6291 "var __t, __p = '', __e = _.escape" + |
|
6292 (isEvaluating |
|
6293 ? ', __j = Array.prototype.join;\n' + |
|
6294 "function print() { __p += __j.call(arguments, '') }\n" |
|
6295 : ';\n' |
|
6296 ) + |
|
6297 source + |
|
6298 'return __p\n}'; |
|
6299 |
|
6300 // Use a sourceURL for easier debugging. |
|
6301 // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl |
|
6302 var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/'; |
|
6303 |
|
6304 try { |
|
6305 var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues); |
|
6306 } catch(e) { |
|
6307 e.source = source; |
|
6308 throw e; |
|
6309 } |
|
6310 if (data) { |
|
6311 return result(data); |
|
6312 } |
|
6313 // provide the compiled function's source by its `toString` method, in |
|
6314 // supported environments, or the `source` property as a convenience for |
|
6315 // inlining compiled templates during the build process |
|
6316 result.source = source; |
|
6317 return result; |
|
6318 } |
|
6319 |
|
6320 /** |
|
6321 * Executes the callback `n` times, returning an array of the results |
|
6322 * of each callback execution. The callback is bound to `thisArg` and invoked |
|
6323 * with one argument; (index). |
|
6324 * |
|
6325 * @static |
|
6326 * @memberOf _ |
|
6327 * @category Utilities |
|
6328 * @param {number} n The number of times to execute the callback. |
|
6329 * @param {Function} callback The function called per iteration. |
|
6330 * @param {*} [thisArg] The `this` binding of `callback`. |
|
6331 * @returns {Array} Returns an array of the results of each `callback` execution. |
|
6332 * @example |
|
6333 * |
|
6334 * var diceRolls = _.times(3, _.partial(_.random, 1, 6)); |
|
6335 * // => [3, 6, 4] |
|
6336 * |
|
6337 * _.times(3, function(n) { mage.castSpell(n); }); |
|
6338 * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively |
|
6339 * |
|
6340 * _.times(3, function(n) { this.cast(n); }, mage); |
|
6341 * // => also calls `mage.castSpell(n)` three times |
|
6342 */ |
|
6343 function times(n, callback, thisArg) { |
|
6344 n = (n = +n) > -1 ? n : 0; |
|
6345 var index = -1, |
|
6346 result = Array(n); |
|
6347 |
|
6348 callback = baseCreateCallback(callback, thisArg, 1); |
|
6349 while (++index < n) { |
|
6350 result[index] = callback(index); |
|
6351 } |
|
6352 return result; |
|
6353 } |
|
6354 |
|
6355 /** |
|
6356 * The inverse of `_.escape` this method converts the HTML entities |
|
6357 * `&`, `<`, `>`, `"`, and `'` in `string` to their |
|
6358 * corresponding characters. |
|
6359 * |
|
6360 * @static |
|
6361 * @memberOf _ |
|
6362 * @category Utilities |
|
6363 * @param {string} string The string to unescape. |
|
6364 * @returns {string} Returns the unescaped string. |
|
6365 * @example |
|
6366 * |
|
6367 * _.unescape('Fred, Barney & Pebbles'); |
|
6368 * // => 'Fred, Barney & Pebbles' |
|
6369 */ |
|
6370 function unescape(string) { |
|
6371 return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar); |
|
6372 } |
|
6373 |
|
6374 /** |
|
6375 * Generates a unique ID. If `prefix` is provided the ID will be appended to it. |
|
6376 * |
|
6377 * @static |
|
6378 * @memberOf _ |
|
6379 * @category Utilities |
|
6380 * @param {string} [prefix] The value to prefix the ID with. |
|
6381 * @returns {string} Returns the unique ID. |
|
6382 * @example |
|
6383 * |
|
6384 * _.uniqueId('contact_'); |
|
6385 * // => 'contact_104' |
|
6386 * |
|
6387 * _.uniqueId(); |
|
6388 * // => '105' |
|
6389 */ |
|
6390 function uniqueId(prefix) { |
|
6391 var id = ++idCounter; |
|
6392 return String(prefix == null ? '' : prefix) + id; |
|
6393 } |
|
6394 |
|
6395 /*--------------------------------------------------------------------------*/ |
|
6396 |
|
6397 /** |
|
6398 * Creates a `lodash` object that wraps the given value with explicit |
|
6399 * method chaining enabled. |
|
6400 * |
|
6401 * @static |
|
6402 * @memberOf _ |
|
6403 * @category Chaining |
|
6404 * @param {*} value The value to wrap. |
|
6405 * @returns {Object} Returns the wrapper object. |
|
6406 * @example |
|
6407 * |
|
6408 * var characters = [ |
|
6409 * { 'name': 'barney', 'age': 36 }, |
|
6410 * { 'name': 'fred', 'age': 40 }, |
|
6411 * { 'name': 'pebbles', 'age': 1 } |
|
6412 * ]; |
|
6413 * |
|
6414 * var youngest = _.chain(characters) |
|
6415 * .sortBy('age') |
|
6416 * .map(function(chr) { return chr.name + ' is ' + chr.age; }) |
|
6417 * .first() |
|
6418 * .value(); |
|
6419 * // => 'pebbles is 1' |
|
6420 */ |
|
6421 function chain(value) { |
|
6422 value = new lodashWrapper(value); |
|
6423 value.__chain__ = true; |
|
6424 return value; |
|
6425 } |
|
6426 |
|
6427 /** |
|
6428 * Invokes `interceptor` with the `value` as the first argument and then |
|
6429 * returns `value`. The purpose of this method is to "tap into" a method |
|
6430 * chain in order to perform operations on intermediate results within |
|
6431 * the chain. |
|
6432 * |
|
6433 * @static |
|
6434 * @memberOf _ |
|
6435 * @category Chaining |
|
6436 * @param {*} value The value to provide to `interceptor`. |
|
6437 * @param {Function} interceptor The function to invoke. |
|
6438 * @returns {*} Returns `value`. |
|
6439 * @example |
|
6440 * |
|
6441 * _([1, 2, 3, 4]) |
|
6442 * .tap(function(array) { array.pop(); }) |
|
6443 * .reverse() |
|
6444 * .value(); |
|
6445 * // => [3, 2, 1] |
|
6446 */ |
|
6447 function tap(value, interceptor) { |
|
6448 interceptor(value); |
|
6449 return value; |
|
6450 } |
|
6451 |
|
6452 /** |
|
6453 * Enables explicit method chaining on the wrapper object. |
|
6454 * |
|
6455 * @name chain |
|
6456 * @memberOf _ |
|
6457 * @category Chaining |
|
6458 * @returns {*} Returns the wrapper object. |
|
6459 * @example |
|
6460 * |
|
6461 * var characters = [ |
|
6462 * { 'name': 'barney', 'age': 36 }, |
|
6463 * { 'name': 'fred', 'age': 40 } |
|
6464 * ]; |
|
6465 * |
|
6466 * // without explicit chaining |
|
6467 * _(characters).first(); |
|
6468 * // => { 'name': 'barney', 'age': 36 } |
|
6469 * |
|
6470 * // with explicit chaining |
|
6471 * _(characters).chain() |
|
6472 * .first() |
|
6473 * .pick('age') |
|
6474 * .value(); |
|
6475 * // => { 'age': 36 } |
|
6476 */ |
|
6477 function wrapperChain() { |
|
6478 this.__chain__ = true; |
|
6479 return this; |
|
6480 } |
|
6481 |
|
6482 /** |
|
6483 * Produces the `toString` result of the wrapped value. |
|
6484 * |
|
6485 * @name toString |
|
6486 * @memberOf _ |
|
6487 * @category Chaining |
|
6488 * @returns {string} Returns the string result. |
|
6489 * @example |
|
6490 * |
|
6491 * _([1, 2, 3]).toString(); |
|
6492 * // => '1,2,3' |
|
6493 */ |
|
6494 function wrapperToString() { |
|
6495 return String(this.__wrapped__); |
|
6496 } |
|
6497 |
|
6498 /** |
|
6499 * Extracts the wrapped value. |
|
6500 * |
|
6501 * @name valueOf |
|
6502 * @memberOf _ |
|
6503 * @alias value |
|
6504 * @category Chaining |
|
6505 * @returns {*} Returns the wrapped value. |
|
6506 * @example |
|
6507 * |
|
6508 * _([1, 2, 3]).valueOf(); |
|
6509 * // => [1, 2, 3] |
|
6510 */ |
|
6511 function wrapperValueOf() { |
|
6512 return this.__wrapped__; |
|
6513 } |
|
6514 |
|
6515 /*--------------------------------------------------------------------------*/ |
|
6516 |
|
6517 // add functions that return wrapped values when chaining |
|
6518 lodash.after = after; |
|
6519 lodash.assign = assign; |
|
6520 lodash.at = at; |
|
6521 lodash.bind = bind; |
|
6522 lodash.bindAll = bindAll; |
|
6523 lodash.bindKey = bindKey; |
|
6524 lodash.chain = chain; |
|
6525 lodash.compact = compact; |
|
6526 lodash.compose = compose; |
|
6527 lodash.constant = constant; |
|
6528 lodash.countBy = countBy; |
|
6529 lodash.create = create; |
|
6530 lodash.createCallback = createCallback; |
|
6531 lodash.curry = curry; |
|
6532 lodash.debounce = debounce; |
|
6533 lodash.defaults = defaults; |
|
6534 lodash.defer = defer; |
|
6535 lodash.delay = delay; |
|
6536 lodash.difference = difference; |
|
6537 lodash.filter = filter; |
|
6538 lodash.flatten = flatten; |
|
6539 lodash.forEach = forEach; |
|
6540 lodash.forEachRight = forEachRight; |
|
6541 lodash.forIn = forIn; |
|
6542 lodash.forInRight = forInRight; |
|
6543 lodash.forOwn = forOwn; |
|
6544 lodash.forOwnRight = forOwnRight; |
|
6545 lodash.functions = functions; |
|
6546 lodash.groupBy = groupBy; |
|
6547 lodash.indexBy = indexBy; |
|
6548 lodash.initial = initial; |
|
6549 lodash.intersection = intersection; |
|
6550 lodash.invert = invert; |
|
6551 lodash.invoke = invoke; |
|
6552 lodash.keys = keys; |
|
6553 lodash.map = map; |
|
6554 lodash.mapValues = mapValues; |
|
6555 lodash.max = max; |
|
6556 lodash.memoize = memoize; |
|
6557 lodash.merge = merge; |
|
6558 lodash.min = min; |
|
6559 lodash.omit = omit; |
|
6560 lodash.once = once; |
|
6561 lodash.pairs = pairs; |
|
6562 lodash.partial = partial; |
|
6563 lodash.partialRight = partialRight; |
|
6564 lodash.pick = pick; |
|
6565 lodash.pluck = pluck; |
|
6566 lodash.property = property; |
|
6567 lodash.pull = pull; |
|
6568 lodash.range = range; |
|
6569 lodash.reject = reject; |
|
6570 lodash.remove = remove; |
|
6571 lodash.rest = rest; |
|
6572 lodash.shuffle = shuffle; |
|
6573 lodash.sortBy = sortBy; |
|
6574 lodash.tap = tap; |
|
6575 lodash.throttle = throttle; |
|
6576 lodash.times = times; |
|
6577 lodash.toArray = toArray; |
|
6578 lodash.transform = transform; |
|
6579 lodash.union = union; |
|
6580 lodash.uniq = uniq; |
|
6581 lodash.values = values; |
|
6582 lodash.where = where; |
|
6583 lodash.without = without; |
|
6584 lodash.wrap = wrap; |
|
6585 lodash.xor = xor; |
|
6586 lodash.zip = zip; |
|
6587 lodash.zipObject = zipObject; |
|
6588 |
|
6589 // add aliases |
|
6590 lodash.collect = map; |
|
6591 lodash.drop = rest; |
|
6592 lodash.each = forEach; |
|
6593 lodash.eachRight = forEachRight; |
|
6594 lodash.extend = assign; |
|
6595 lodash.methods = functions; |
|
6596 lodash.object = zipObject; |
|
6597 lodash.select = filter; |
|
6598 lodash.tail = rest; |
|
6599 lodash.unique = uniq; |
|
6600 lodash.unzip = zip; |
|
6601 |
|
6602 // add functions to `lodash.prototype` |
|
6603 mixin(lodash); |
|
6604 |
|
6605 /*--------------------------------------------------------------------------*/ |
|
6606 |
|
6607 // add functions that return unwrapped values when chaining |
|
6608 lodash.clone = clone; |
|
6609 lodash.cloneDeep = cloneDeep; |
|
6610 lodash.contains = contains; |
|
6611 lodash.escape = escape; |
|
6612 lodash.every = every; |
|
6613 lodash.find = find; |
|
6614 lodash.findIndex = findIndex; |
|
6615 lodash.findKey = findKey; |
|
6616 lodash.findLast = findLast; |
|
6617 lodash.findLastIndex = findLastIndex; |
|
6618 lodash.findLastKey = findLastKey; |
|
6619 lodash.has = has; |
|
6620 lodash.identity = identity; |
|
6621 lodash.indexOf = indexOf; |
|
6622 lodash.isArguments = isArguments; |
|
6623 lodash.isArray = isArray; |
|
6624 lodash.isBoolean = isBoolean; |
|
6625 lodash.isDate = isDate; |
|
6626 lodash.isElement = isElement; |
|
6627 lodash.isEmpty = isEmpty; |
|
6628 lodash.isEqual = isEqual; |
|
6629 lodash.isFinite = isFinite; |
|
6630 lodash.isFunction = isFunction; |
|
6631 lodash.isNaN = isNaN; |
|
6632 lodash.isNull = isNull; |
|
6633 lodash.isNumber = isNumber; |
|
6634 lodash.isObject = isObject; |
|
6635 lodash.isPlainObject = isPlainObject; |
|
6636 lodash.isRegExp = isRegExp; |
|
6637 lodash.isString = isString; |
|
6638 lodash.isUndefined = isUndefined; |
|
6639 lodash.lastIndexOf = lastIndexOf; |
|
6640 lodash.mixin = mixin; |
|
6641 lodash.noConflict = noConflict; |
|
6642 lodash.noop = noop; |
|
6643 lodash.now = now; |
|
6644 lodash.parseInt = parseInt; |
|
6645 lodash.random = random; |
|
6646 lodash.reduce = reduce; |
|
6647 lodash.reduceRight = reduceRight; |
|
6648 lodash.result = result; |
|
6649 lodash.runInContext = runInContext; |
|
6650 lodash.size = size; |
|
6651 lodash.some = some; |
|
6652 lodash.sortedIndex = sortedIndex; |
|
6653 lodash.template = template; |
|
6654 lodash.unescape = unescape; |
|
6655 lodash.uniqueId = uniqueId; |
|
6656 |
|
6657 // add aliases |
|
6658 lodash.all = every; |
|
6659 lodash.any = some; |
|
6660 lodash.detect = find; |
|
6661 lodash.findWhere = find; |
|
6662 lodash.foldl = reduce; |
|
6663 lodash.foldr = reduceRight; |
|
6664 lodash.include = contains; |
|
6665 lodash.inject = reduce; |
|
6666 |
|
6667 mixin(function() { |
|
6668 var source = {} |
|
6669 forOwn(lodash, function(func, methodName) { |
|
6670 if (!lodash.prototype[methodName]) { |
|
6671 source[methodName] = func; |
|
6672 } |
|
6673 }); |
|
6674 return source; |
|
6675 }(), false); |
|
6676 |
|
6677 /*--------------------------------------------------------------------------*/ |
|
6678 |
|
6679 // add functions capable of returning wrapped and unwrapped values when chaining |
|
6680 lodash.first = first; |
|
6681 lodash.last = last; |
|
6682 lodash.sample = sample; |
|
6683 |
|
6684 // add aliases |
|
6685 lodash.take = first; |
|
6686 lodash.head = first; |
|
6687 |
|
6688 forOwn(lodash, function(func, methodName) { |
|
6689 var callbackable = methodName !== 'sample'; |
|
6690 if (!lodash.prototype[methodName]) { |
|
6691 lodash.prototype[methodName]= function(n, guard) { |
|
6692 var chainAll = this.__chain__, |
|
6693 result = func(this.__wrapped__, n, guard); |
|
6694 |
|
6695 return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function'))) |
|
6696 ? result |
|
6697 : new lodashWrapper(result, chainAll); |
|
6698 }; |
|
6699 } |
|
6700 }); |
|
6701 |
|
6702 /*--------------------------------------------------------------------------*/ |
|
6703 |
|
6704 /** |
|
6705 * The semantic version number. |
|
6706 * |
|
6707 * @static |
|
6708 * @memberOf _ |
|
6709 * @type string |
|
6710 */ |
|
6711 lodash.VERSION = '2.4.1'; |
|
6712 |
|
6713 // add "Chaining" functions to the wrapper |
|
6714 lodash.prototype.chain = wrapperChain; |
|
6715 lodash.prototype.toString = wrapperToString; |
|
6716 lodash.prototype.value = wrapperValueOf; |
|
6717 lodash.prototype.valueOf = wrapperValueOf; |
|
6718 |
|
6719 // add `Array` functions that return unwrapped values |
|
6720 forEach(['join', 'pop', 'shift'], function(methodName) { |
|
6721 var func = arrayRef[methodName]; |
|
6722 lodash.prototype[methodName] = function() { |
|
6723 var chainAll = this.__chain__, |
|
6724 result = func.apply(this.__wrapped__, arguments); |
|
6725 |
|
6726 return chainAll |
|
6727 ? new lodashWrapper(result, chainAll) |
|
6728 : result; |
|
6729 }; |
|
6730 }); |
|
6731 |
|
6732 // add `Array` functions that return the existing wrapped value |
|
6733 forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) { |
|
6734 var func = arrayRef[methodName]; |
|
6735 lodash.prototype[methodName] = function() { |
|
6736 func.apply(this.__wrapped__, arguments); |
|
6737 return this; |
|
6738 }; |
|
6739 }); |
|
6740 |
|
6741 // add `Array` functions that return new wrapped values |
|
6742 forEach(['concat', 'slice', 'splice'], function(methodName) { |
|
6743 var func = arrayRef[methodName]; |
|
6744 lodash.prototype[methodName] = function() { |
|
6745 return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__); |
|
6746 }; |
|
6747 }); |
|
6748 |
|
6749 return lodash; |
|
6750 } |
|
6751 |
|
6752 /*--------------------------------------------------------------------------*/ |
|
6753 |
|
6754 // expose Lo-Dash |
|
6755 var _ = runInContext(); |
|
6756 |
|
6757 // some AMD build optimizers like r.js check for condition patterns like the following: |
|
6758 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { |
|
6759 // Expose Lo-Dash to the global object even when an AMD loader is present in |
|
6760 // case Lo-Dash is loaded with a RequireJS shim config. |
|
6761 // See http://requirejs.org/docs/api.html#config-shim |
|
6762 root._ = _; |
|
6763 |
|
6764 // define as an anonymous module so, through path mapping, it can be |
|
6765 // referenced as the "underscore" module |
|
6766 define(function() { |
|
6767 return _; |
|
6768 }); |
|
6769 } |
|
6770 // check for `exports` after `define` in case a build optimizer adds an `exports` object |
|
6771 else if (freeExports && freeModule) { |
|
6772 // in Node.js or RingoJS |
|
6773 if (moduleExports) { |
|
6774 (freeModule.exports = _)._ = _; |
|
6775 } |
|
6776 // in Narwhal or Rhino -require |
|
6777 else { |
|
6778 freeExports._ = _; |
|
6779 } |
|
6780 } |
|
6781 else { |
|
6782 // in a browser or Rhino |
|
6783 root._ = _; |
|
6784 } |
|
6785 }.call(this)); |