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