lodash-rails 2.4.1 → 4.17.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4979 +0,0 @@
1
- /**
2
- * @license
3
- * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
4
- * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js`
5
- * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
6
- * Based on Underscore.js 1.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 generate unique IDs */
16
- var idCounter = 0;
17
-
18
- /** Used internally to indicate various things */
19
- var indicatorObject = {};
20
-
21
- /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
22
- var keyPrefix = +new Date + '';
23
-
24
- /** Used to match "interpolate" template delimiters */
25
- var reInterpolate = /<%=([\s\S]+?)%>/g;
26
-
27
- /** Used to ensure capturing order of template delimiters */
28
- var reNoMatch = /($^)/;
29
-
30
- /** Used to match unescaped characters in compiled string literals */
31
- var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
32
-
33
- /** `Object#toString` result shortcuts */
34
- var argsClass = '[object Arguments]',
35
- arrayClass = '[object Array]',
36
- boolClass = '[object Boolean]',
37
- dateClass = '[object Date]',
38
- funcClass = '[object Function]',
39
- numberClass = '[object Number]',
40
- objectClass = '[object Object]',
41
- regexpClass = '[object RegExp]',
42
- stringClass = '[object String]';
43
-
44
- /** Used to determine if values are of the language type Object */
45
- var objectTypes = {
46
- 'boolean': false,
47
- 'function': true,
48
- 'object': true,
49
- 'number': false,
50
- 'string': false,
51
- 'undefined': false
52
- };
53
-
54
- /** Used to escape characters for inclusion in compiled string literals */
55
- var stringEscapes = {
56
- '\\': '\\',
57
- "'": "'",
58
- '\n': 'n',
59
- '\r': 'r',
60
- '\t': 't',
61
- '\u2028': 'u2028',
62
- '\u2029': 'u2029'
63
- };
64
-
65
- /** Used as a reference to the global object */
66
- var root = (objectTypes[typeof window] && window) || this;
67
-
68
- /** Detect free variable `exports` */
69
- var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
70
-
71
- /** Detect free variable `module` */
72
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
73
-
74
- /** Detect the popular CommonJS extension `module.exports` */
75
- var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
76
-
77
- /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
78
- var freeGlobal = objectTypes[typeof global] && global;
79
- if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
80
- root = freeGlobal;
81
- }
82
-
83
- /*--------------------------------------------------------------------------*/
84
-
85
- /**
86
- * The base implementation of `_.indexOf` without support for binary searches
87
- * or `fromIndex` constraints.
88
- *
89
- * @private
90
- * @param {Array} array The array to search.
91
- * @param {*} value The value to search for.
92
- * @param {number} [fromIndex=0] The index to search from.
93
- * @returns {number} Returns the index of the matched value or `-1`.
94
- */
95
- function baseIndexOf(array, value, fromIndex) {
96
- var index = (fromIndex || 0) - 1,
97
- length = array ? array.length : 0;
98
-
99
- while (++index < length) {
100
- if (array[index] === value) {
101
- return index;
102
- }
103
- }
104
- return -1;
105
- }
106
-
107
- /**
108
- * Used by `sortBy` to compare transformed `collection` elements, stable sorting
109
- * them in ascending order.
110
- *
111
- * @private
112
- * @param {Object} a The object to compare to `b`.
113
- * @param {Object} b The object to compare to `a`.
114
- * @returns {number} Returns the sort order indicator of `1` or `-1`.
115
- */
116
- function compareAscending(a, b) {
117
- var ac = a.criteria,
118
- bc = b.criteria,
119
- index = -1,
120
- length = ac.length;
121
-
122
- while (++index < length) {
123
- var value = ac[index],
124
- other = bc[index];
125
-
126
- if (value !== other) {
127
- if (value > other || typeof value == 'undefined') {
128
- return 1;
129
- }
130
- if (value < other || typeof other == 'undefined') {
131
- return -1;
132
- }
133
- }
134
- }
135
- // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
136
- // that causes it, under certain circumstances, to return the same value for
137
- // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
138
- //
139
- // This also ensures a stable sort in V8 and other engines.
140
- // See http://code.google.com/p/v8/issues/detail?id=90
141
- return a.index - b.index;
142
- }
143
-
144
- /**
145
- * Used by `template` to escape characters for inclusion in compiled
146
- * string literals.
147
- *
148
- * @private
149
- * @param {string} match The matched character to escape.
150
- * @returns {string} Returns the escaped character.
151
- */
152
- function escapeStringChar(match) {
153
- return '\\' + stringEscapes[match];
154
- }
155
-
156
- /**
157
- * Slices the `collection` from the `start` index up to, but not including,
158
- * the `end` index.
159
- *
160
- * Note: This function is used instead of `Array#slice` to support node lists
161
- * in IE < 9 and to ensure dense arrays are returned.
162
- *
163
- * @private
164
- * @param {Array|Object|string} collection The collection to slice.
165
- * @param {number} start The start index.
166
- * @param {number} end The end index.
167
- * @returns {Array} Returns the new array.
168
- */
169
- function slice(array, start, end) {
170
- start || (start = 0);
171
- if (typeof end == 'undefined') {
172
- end = array ? array.length : 0;
173
- }
174
- var index = -1,
175
- length = end - start || 0,
176
- result = Array(length < 0 ? 0 : length);
177
-
178
- while (++index < length) {
179
- result[index] = array[start + index];
180
- }
181
- return result;
182
- }
183
-
184
- /*--------------------------------------------------------------------------*/
185
-
186
- /**
187
- * Used for `Array` method references.
188
- *
189
- * Normally `Array.prototype` would suffice, however, using an array literal
190
- * avoids issues in Narwhal.
191
- */
192
- var arrayRef = [];
193
-
194
- /** Used for native method references */
195
- var objectProto = Object.prototype;
196
-
197
- /** Used to restore the original `_` reference in `noConflict` */
198
- var oldDash = root._;
199
-
200
- /** Used to resolve the internal [[Class]] of values */
201
- var toString = objectProto.toString;
202
-
203
- /** Used to detect if a method is native */
204
- var reNative = RegExp('^' +
205
- String(toString)
206
- .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
207
- .replace(/toString| for [^\]]+/g, '.*?') + '$'
208
- );
209
-
210
- /** Native method shortcuts */
211
- var ceil = Math.ceil,
212
- floor = Math.floor,
213
- hasOwnProperty = objectProto.hasOwnProperty,
214
- push = arrayRef.push,
215
- propertyIsEnumerable = objectProto.propertyIsEnumerable;
216
-
217
- /* Native method shortcuts for methods with the same name as other `lodash` methods */
218
- var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
219
- nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
220
- nativeIsFinite = root.isFinite,
221
- nativeIsNaN = root.isNaN,
222
- nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
223
- nativeMax = Math.max,
224
- nativeMin = Math.min,
225
- nativeRandom = Math.random;
226
-
227
- /*--------------------------------------------------------------------------*/
228
-
229
- /**
230
- * Creates a `lodash` object which wraps the given value to enable intuitive
231
- * method chaining.
232
- *
233
- * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
234
- * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
235
- * and `unshift`
236
- *
237
- * Chaining is supported in custom builds as long as the `value` method is
238
- * implicitly or explicitly included in the build.
239
- *
240
- * The chainable wrapper functions are:
241
- * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
242
- * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
243
- * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
244
- * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
245
- * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
246
- * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
247
- * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
248
- * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
249
- * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
250
- * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
251
- * and `zip`
252
- *
253
- * The non-chainable wrapper functions are:
254
- * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
255
- * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
256
- * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
257
- * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
258
- * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
259
- * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
260
- * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
261
- * `template`, `unescape`, `uniqueId`, and `value`
262
- *
263
- * The wrapper functions `first` and `last` return wrapped values when `n` is
264
- * provided, otherwise they return unwrapped values.
265
- *
266
- * Explicit chaining can be enabled by using the `_.chain` method.
267
- *
268
- * @name _
269
- * @constructor
270
- * @category Chaining
271
- * @param {*} value The value to wrap in a `lodash` instance.
272
- * @returns {Object} Returns a `lodash` instance.
273
- * @example
274
- *
275
- * var wrapped = _([1, 2, 3]);
276
- *
277
- * // returns an unwrapped value
278
- * wrapped.reduce(function(sum, num) {
279
- * return sum + num;
280
- * });
281
- * // => 6
282
- *
283
- * // returns a wrapped value
284
- * var squares = wrapped.map(function(num) {
285
- * return num * num;
286
- * });
287
- *
288
- * _.isArray(squares);
289
- * // => false
290
- *
291
- * _.isArray(squares.value());
292
- * // => true
293
- */
294
- function lodash(value) {
295
- return (value instanceof lodash)
296
- ? value
297
- : new lodashWrapper(value);
298
- }
299
-
300
- /**
301
- * A fast path for creating `lodash` wrapper objects.
302
- *
303
- * @private
304
- * @param {*} value The value to wrap in a `lodash` instance.
305
- * @param {boolean} chainAll A flag to enable chaining for all methods
306
- * @returns {Object} Returns a `lodash` instance.
307
- */
308
- function lodashWrapper(value, chainAll) {
309
- this.__chain__ = !!chainAll;
310
- this.__wrapped__ = value;
311
- }
312
- // ensure `new lodashWrapper` is an instance of `lodash`
313
- lodashWrapper.prototype = lodash.prototype;
314
-
315
- /**
316
- * An object used to flag environments features.
317
- *
318
- * @static
319
- * @memberOf _
320
- * @type Object
321
- */
322
- var support = {};
323
-
324
- (function() {
325
- var object = { '0': 1, 'length': 1 };
326
-
327
- /**
328
- * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
329
- *
330
- * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
331
- * and `splice()` functions that fail to remove the last element, `value[0]`,
332
- * of array-like objects even though the `length` property is set to `0`.
333
- * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
334
- * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
335
- *
336
- * @memberOf _.support
337
- * @type boolean
338
- */
339
- support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
340
- }(1));
341
-
342
- /**
343
- * By default, the template delimiters used by Lo-Dash are similar to those in
344
- * embedded Ruby (ERB). Change the following template settings to use alternative
345
- * delimiters.
346
- *
347
- * @static
348
- * @memberOf _
349
- * @type Object
350
- */
351
- lodash.templateSettings = {
352
-
353
- /**
354
- * Used to detect `data` property values to be HTML-escaped.
355
- *
356
- * @memberOf _.templateSettings
357
- * @type RegExp
358
- */
359
- 'escape': /<%-([\s\S]+?)%>/g,
360
-
361
- /**
362
- * Used to detect code to be evaluated.
363
- *
364
- * @memberOf _.templateSettings
365
- * @type RegExp
366
- */
367
- 'evaluate': /<%([\s\S]+?)%>/g,
368
-
369
- /**
370
- * Used to detect `data` property values to inject.
371
- *
372
- * @memberOf _.templateSettings
373
- * @type RegExp
374
- */
375
- 'interpolate': reInterpolate,
376
-
377
- /**
378
- * Used to reference the data object in the template text.
379
- *
380
- * @memberOf _.templateSettings
381
- * @type string
382
- */
383
- 'variable': ''
384
- };
385
-
386
- /*--------------------------------------------------------------------------*/
387
-
388
- /**
389
- * The base implementation of `_.bind` that creates the bound function and
390
- * sets its meta data.
391
- *
392
- * @private
393
- * @param {Array} bindData The bind data array.
394
- * @returns {Function} Returns the new bound function.
395
- */
396
- function baseBind(bindData) {
397
- var func = bindData[0],
398
- partialArgs = bindData[2],
399
- thisArg = bindData[4];
400
-
401
- function bound() {
402
- // `Function#bind` spec
403
- // http://es5.github.io/#x15.3.4.5
404
- if (partialArgs) {
405
- // avoid `arguments` object deoptimizations by using `slice` instead
406
- // of `Array.prototype.slice.call` and not assigning `arguments` to a
407
- // variable as a ternary expression
408
- var args = slice(partialArgs);
409
- push.apply(args, arguments);
410
- }
411
- // mimic the constructor's `return` behavior
412
- // http://es5.github.io/#x13.2.2
413
- if (this instanceof bound) {
414
- // ensure `new bound` is an instance of `func`
415
- var thisBinding = baseCreate(func.prototype),
416
- result = func.apply(thisBinding, args || arguments);
417
- return isObject(result) ? result : thisBinding;
418
- }
419
- return func.apply(thisArg, args || arguments);
420
- }
421
- return bound;
422
- }
423
-
424
- /**
425
- * The base implementation of `_.create` without support for assigning
426
- * properties to the created object.
427
- *
428
- * @private
429
- * @param {Object} prototype The object to inherit from.
430
- * @returns {Object} Returns the new object.
431
- */
432
- function baseCreate(prototype, properties) {
433
- return isObject(prototype) ? nativeCreate(prototype) : {};
434
- }
435
- // fallback for browsers without `Object.create`
436
- if (!nativeCreate) {
437
- baseCreate = (function() {
438
- function Object() {}
439
- return function(prototype) {
440
- if (isObject(prototype)) {
441
- Object.prototype = prototype;
442
- var result = new Object;
443
- Object.prototype = null;
444
- }
445
- return result || root.Object();
446
- };
447
- }());
448
- }
449
-
450
- /**
451
- * The base implementation of `_.createCallback` without support for creating
452
- * "_.pluck" or "_.where" style callbacks.
453
- *
454
- * @private
455
- * @param {*} [func=identity] The value to convert to a callback.
456
- * @param {*} [thisArg] The `this` binding of the created callback.
457
- * @param {number} [argCount] The number of arguments the callback accepts.
458
- * @returns {Function} Returns a callback function.
459
- */
460
- function baseCreateCallback(func, thisArg, argCount) {
461
- if (typeof func != 'function') {
462
- return identity;
463
- }
464
- // exit early for no `thisArg` or already bound by `Function#bind`
465
- if (typeof thisArg == 'undefined' || !('prototype' in func)) {
466
- return func;
467
- }
468
- switch (argCount) {
469
- case 1: return function(value) {
470
- return func.call(thisArg, value);
471
- };
472
- case 2: return function(a, b) {
473
- return func.call(thisArg, a, b);
474
- };
475
- case 3: return function(value, index, collection) {
476
- return func.call(thisArg, value, index, collection);
477
- };
478
- case 4: return function(accumulator, value, index, collection) {
479
- return func.call(thisArg, accumulator, value, index, collection);
480
- };
481
- }
482
- return bind(func, thisArg);
483
- }
484
-
485
- /**
486
- * The base implementation of `createWrapper` that creates the wrapper and
487
- * sets its meta data.
488
- *
489
- * @private
490
- * @param {Array} bindData The bind data array.
491
- * @returns {Function} Returns the new function.
492
- */
493
- function baseCreateWrapper(bindData) {
494
- var func = bindData[0],
495
- bitmask = bindData[1],
496
- partialArgs = bindData[2],
497
- partialRightArgs = bindData[3],
498
- thisArg = bindData[4],
499
- arity = bindData[5];
500
-
501
- var isBind = bitmask & 1,
502
- isBindKey = bitmask & 2,
503
- isCurry = bitmask & 4,
504
- isCurryBound = bitmask & 8,
505
- key = func;
506
-
507
- function bound() {
508
- var thisBinding = isBind ? thisArg : this;
509
- if (partialArgs) {
510
- var args = slice(partialArgs);
511
- push.apply(args, arguments);
512
- }
513
- if (partialRightArgs || isCurry) {
514
- args || (args = slice(arguments));
515
- if (partialRightArgs) {
516
- push.apply(args, partialRightArgs);
517
- }
518
- if (isCurry && args.length < arity) {
519
- bitmask |= 16 & ~32;
520
- return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
521
- }
522
- }
523
- args || (args = arguments);
524
- if (isBindKey) {
525
- func = thisBinding[key];
526
- }
527
- if (this instanceof bound) {
528
- thisBinding = baseCreate(func.prototype);
529
- var result = func.apply(thisBinding, args);
530
- return isObject(result) ? result : thisBinding;
531
- }
532
- return func.apply(thisBinding, args);
533
- }
534
- return bound;
535
- }
536
-
537
- /**
538
- * The base implementation of `_.difference` that accepts a single array
539
- * of values to exclude.
540
- *
541
- * @private
542
- * @param {Array} array The array to process.
543
- * @param {Array} [values] The array of values to exclude.
544
- * @returns {Array} Returns a new array of filtered values.
545
- */
546
- function baseDifference(array, values) {
547
- var index = -1,
548
- indexOf = getIndexOf(),
549
- length = array ? array.length : 0,
550
- result = [];
551
-
552
- while (++index < length) {
553
- var value = array[index];
554
- if (indexOf(values, value) < 0) {
555
- result.push(value);
556
- }
557
- }
558
- return result;
559
- }
560
-
561
- /**
562
- * The base implementation of `_.flatten` without support for callback
563
- * shorthands or `thisArg` binding.
564
- *
565
- * @private
566
- * @param {Array} array The array to flatten.
567
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
568
- * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
569
- * @param {number} [fromIndex=0] The index to start from.
570
- * @returns {Array} Returns a new flattened array.
571
- */
572
- function baseFlatten(array, isShallow, isStrict, fromIndex) {
573
- var index = (fromIndex || 0) - 1,
574
- length = array ? array.length : 0,
575
- result = [];
576
-
577
- while (++index < length) {
578
- var value = array[index];
579
-
580
- if (value && typeof value == 'object' && typeof value.length == 'number'
581
- && (isArray(value) || isArguments(value))) {
582
- // recursively flatten arrays (susceptible to call stack limits)
583
- if (!isShallow) {
584
- value = baseFlatten(value, isShallow, isStrict);
585
- }
586
- var valIndex = -1,
587
- valLength = value.length,
588
- resIndex = result.length;
589
-
590
- result.length += valLength;
591
- while (++valIndex < valLength) {
592
- result[resIndex++] = value[valIndex];
593
- }
594
- } else if (!isStrict) {
595
- result.push(value);
596
- }
597
- }
598
- return result;
599
- }
600
-
601
- /**
602
- * The base implementation of `_.isEqual`, without support for `thisArg` binding,
603
- * that allows partial "_.where" style comparisons.
604
- *
605
- * @private
606
- * @param {*} a The value to compare.
607
- * @param {*} b The other value to compare.
608
- * @param {Function} [callback] The function to customize comparing values.
609
- * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
610
- * @param {Array} [stackA=[]] Tracks traversed `a` objects.
611
- * @param {Array} [stackB=[]] Tracks traversed `b` objects.
612
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
613
- */
614
- function baseIsEqual(a, b, stackA, stackB) {
615
- if (a === b) {
616
- return a !== 0 || (1 / a == 1 / b);
617
- }
618
- var type = typeof a,
619
- otherType = typeof b;
620
-
621
- if (a === a &&
622
- !(a && objectTypes[type]) &&
623
- !(b && objectTypes[otherType])) {
624
- return false;
625
- }
626
- if (a == null || b == null) {
627
- return a === b;
628
- }
629
- var className = toString.call(a),
630
- otherClass = toString.call(b);
631
-
632
- if (className != otherClass) {
633
- return false;
634
- }
635
- switch (className) {
636
- case boolClass:
637
- case dateClass:
638
- return +a == +b;
639
-
640
- case numberClass:
641
- return a != +a
642
- ? b != +b
643
- : (a == 0 ? (1 / a == 1 / b) : a == +b);
644
-
645
- case regexpClass:
646
- case stringClass:
647
- return a == String(b);
648
- }
649
- var isArr = className == arrayClass;
650
- if (!isArr) {
651
- var aWrapped = a instanceof lodash,
652
- bWrapped = b instanceof lodash;
653
-
654
- if (aWrapped || bWrapped) {
655
- return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, stackA, stackB);
656
- }
657
- if (className != objectClass) {
658
- return false;
659
- }
660
- var ctorA = a.constructor,
661
- ctorB = b.constructor;
662
-
663
- if (ctorA != ctorB &&
664
- !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
665
- ('constructor' in a && 'constructor' in b)
666
- ) {
667
- return false;
668
- }
669
- }
670
- stackA || (stackA = []);
671
- stackB || (stackB = []);
672
-
673
- var length = stackA.length;
674
- while (length--) {
675
- if (stackA[length] == a) {
676
- return stackB[length] == b;
677
- }
678
- }
679
- var result = true,
680
- size = 0;
681
-
682
- stackA.push(a);
683
- stackB.push(b);
684
-
685
- if (isArr) {
686
- size = b.length;
687
- result = size == a.length;
688
-
689
- if (result) {
690
- while (size--) {
691
- if (!(result = baseIsEqual(a[size], b[size], stackA, stackB))) {
692
- break;
693
- }
694
- }
695
- }
696
- }
697
- else {
698
- forIn(b, function(value, key, b) {
699
- if (hasOwnProperty.call(b, key)) {
700
- size++;
701
- return !(result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, stackA, stackB)) && indicatorObject;
702
- }
703
- });
704
-
705
- if (result) {
706
- forIn(a, function(value, key, a) {
707
- if (hasOwnProperty.call(a, key)) {
708
- return !(result = --size > -1) && indicatorObject;
709
- }
710
- });
711
- }
712
- }
713
- stackA.pop();
714
- stackB.pop();
715
- return result;
716
- }
717
-
718
- /**
719
- * The base implementation of `_.random` without argument juggling or support
720
- * for returning floating-point numbers.
721
- *
722
- * @private
723
- * @param {number} min The minimum possible value.
724
- * @param {number} max The maximum possible value.
725
- * @returns {number} Returns a random number.
726
- */
727
- function baseRandom(min, max) {
728
- return min + floor(nativeRandom() * (max - min + 1));
729
- }
730
-
731
- /**
732
- * The base implementation of `_.uniq` without support for callback shorthands
733
- * or `thisArg` binding.
734
- *
735
- * @private
736
- * @param {Array} array The array to process.
737
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
738
- * @param {Function} [callback] The function called per iteration.
739
- * @returns {Array} Returns a duplicate-value-free array.
740
- */
741
- function baseUniq(array, isSorted, callback) {
742
- var index = -1,
743
- indexOf = getIndexOf(),
744
- length = array ? array.length : 0,
745
- result = [],
746
- seen = callback ? [] : result;
747
-
748
- while (++index < length) {
749
- var value = array[index],
750
- computed = callback ? callback(value, index, array) : value;
751
-
752
- if (isSorted
753
- ? !index || seen[seen.length - 1] !== computed
754
- : indexOf(seen, computed) < 0
755
- ) {
756
- if (callback) {
757
- seen.push(computed);
758
- }
759
- result.push(value);
760
- }
761
- }
762
- return result;
763
- }
764
-
765
- /**
766
- * Creates a function that aggregates a collection, creating an object composed
767
- * of keys generated from the results of running each element of the collection
768
- * through a callback. The given `setter` function sets the keys and values
769
- * of the composed object.
770
- *
771
- * @private
772
- * @param {Function} setter The setter function.
773
- * @returns {Function} Returns the new aggregator function.
774
- */
775
- function createAggregator(setter) {
776
- return function(collection, callback, thisArg) {
777
- var result = {};
778
- callback = createCallback(callback, thisArg, 3);
779
-
780
- var index = -1,
781
- length = collection ? collection.length : 0;
782
-
783
- if (typeof length == 'number') {
784
- while (++index < length) {
785
- var value = collection[index];
786
- setter(result, value, callback(value, index, collection), collection);
787
- }
788
- } else {
789
- forOwn(collection, function(value, key, collection) {
790
- setter(result, value, callback(value, key, collection), collection);
791
- });
792
- }
793
- return result;
794
- };
795
- }
796
-
797
- /**
798
- * Creates a function that, when called, either curries or invokes `func`
799
- * with an optional `this` binding and partially applied arguments.
800
- *
801
- * @private
802
- * @param {Function|string} func The function or method name to reference.
803
- * @param {number} bitmask The bitmask of method flags to compose.
804
- * The bitmask may be composed of the following flags:
805
- * 1 - `_.bind`
806
- * 2 - `_.bindKey`
807
- * 4 - `_.curry`
808
- * 8 - `_.curry` (bound)
809
- * 16 - `_.partial`
810
- * 32 - `_.partialRight`
811
- * @param {Array} [partialArgs] An array of arguments to prepend to those
812
- * provided to the new function.
813
- * @param {Array} [partialRightArgs] An array of arguments to append to those
814
- * provided to the new function.
815
- * @param {*} [thisArg] The `this` binding of `func`.
816
- * @param {number} [arity] The arity of `func`.
817
- * @returns {Function} Returns the new function.
818
- */
819
- function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
820
- var isBind = bitmask & 1,
821
- isBindKey = bitmask & 2,
822
- isCurry = bitmask & 4,
823
- isCurryBound = bitmask & 8,
824
- isPartial = bitmask & 16,
825
- isPartialRight = bitmask & 32;
826
-
827
- if (!isBindKey && !isFunction(func)) {
828
- throw new TypeError;
829
- }
830
- if (isPartial && !partialArgs.length) {
831
- bitmask &= ~16;
832
- isPartial = partialArgs = false;
833
- }
834
- if (isPartialRight && !partialRightArgs.length) {
835
- bitmask &= ~32;
836
- isPartialRight = partialRightArgs = false;
837
- }
838
- // fast path for `_.bind`
839
- var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
840
- return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
841
- }
842
-
843
- /**
844
- * Used by `escape` to convert characters to HTML entities.
845
- *
846
- * @private
847
- * @param {string} match The matched character to escape.
848
- * @returns {string} Returns the escaped character.
849
- */
850
- function escapeHtmlChar(match) {
851
- return htmlEscapes[match];
852
- }
853
-
854
- /**
855
- * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
856
- * customized, this method returns the custom method, otherwise it returns
857
- * the `baseIndexOf` function.
858
- *
859
- * @private
860
- * @returns {Function} Returns the "indexOf" function.
861
- */
862
- function getIndexOf() {
863
- var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
864
- return result;
865
- }
866
-
867
- /**
868
- * Checks if `value` is a native function.
869
- *
870
- * @private
871
- * @param {*} value The value to check.
872
- * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
873
- */
874
- function isNative(value) {
875
- return typeof value == 'function' && reNative.test(value);
876
- }
877
-
878
- /**
879
- * Used by `unescape` to convert HTML entities to characters.
880
- *
881
- * @private
882
- * @param {string} match The matched character to unescape.
883
- * @returns {string} Returns the unescaped character.
884
- */
885
- function unescapeHtmlChar(match) {
886
- return htmlUnescapes[match];
887
- }
888
-
889
- /*--------------------------------------------------------------------------*/
890
-
891
- /**
892
- * Checks if `value` is an `arguments` object.
893
- *
894
- * @static
895
- * @memberOf _
896
- * @category Objects
897
- * @param {*} value The value to check.
898
- * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
899
- * @example
900
- *
901
- * (function() { return _.isArguments(arguments); })(1, 2, 3);
902
- * // => true
903
- *
904
- * _.isArguments([1, 2, 3]);
905
- * // => false
906
- */
907
- function isArguments(value) {
908
- return value && typeof value == 'object' && typeof value.length == 'number' &&
909
- toString.call(value) == argsClass || false;
910
- }
911
- // fallback for browsers that can't detect `arguments` objects by [[Class]]
912
- if (!isArguments(arguments)) {
913
- isArguments = function(value) {
914
- return value && typeof value == 'object' && typeof value.length == 'number' &&
915
- hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
916
- };
917
- }
918
-
919
- /**
920
- * Checks if `value` is an array.
921
- *
922
- * @static
923
- * @memberOf _
924
- * @type Function
925
- * @category Objects
926
- * @param {*} value The value to check.
927
- * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
928
- * @example
929
- *
930
- * (function() { return _.isArray(arguments); })();
931
- * // => false
932
- *
933
- * _.isArray([1, 2, 3]);
934
- * // => true
935
- */
936
- var isArray = nativeIsArray || function(value) {
937
- return value && typeof value == 'object' && typeof value.length == 'number' &&
938
- toString.call(value) == arrayClass || false;
939
- };
940
-
941
- /**
942
- * A fallback implementation of `Object.keys` which produces an array of the
943
- * given object's own enumerable property names.
944
- *
945
- * @private
946
- * @type Function
947
- * @param {Object} object The object to inspect.
948
- * @returns {Array} Returns an array of property names.
949
- */
950
- var shimKeys = function(object) {
951
- var index, iterable = object, result = [];
952
- if (!iterable) return result;
953
- if (!(objectTypes[typeof object])) return result;
954
- for (index in iterable) {
955
- if (hasOwnProperty.call(iterable, index)) {
956
- result.push(index);
957
- }
958
- }
959
- return result
960
- };
961
-
962
- /**
963
- * Creates an array composed of the own enumerable property names of an object.
964
- *
965
- * @static
966
- * @memberOf _
967
- * @category Objects
968
- * @param {Object} object The object to inspect.
969
- * @returns {Array} Returns an array of property names.
970
- * @example
971
- *
972
- * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
973
- * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
974
- */
975
- var keys = !nativeKeys ? shimKeys : function(object) {
976
- if (!isObject(object)) {
977
- return [];
978
- }
979
- return nativeKeys(object);
980
- };
981
-
982
- /**
983
- * Used to convert characters to HTML entities:
984
- *
985
- * Though the `>` character is escaped for symmetry, characters like `>` and `/`
986
- * don't require escaping in HTML and have no special meaning unless they're part
987
- * of a tag or an unquoted attribute value.
988
- * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
989
- */
990
- var htmlEscapes = {
991
- '&': '&amp;',
992
- '<': '&lt;',
993
- '>': '&gt;',
994
- '"': '&quot;',
995
- "'": '&#x27;'
996
- };
997
-
998
- /** Used to convert HTML entities to characters */
999
- var htmlUnescapes = invert(htmlEscapes);
1000
-
1001
- /** Used to match HTML entities and HTML characters */
1002
- var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
1003
- reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
1004
-
1005
- /*--------------------------------------------------------------------------*/
1006
-
1007
- /**
1008
- * Assigns own enumerable properties of source object(s) to the destination
1009
- * object. Subsequent sources will overwrite property assignments of previous
1010
- * sources. If a callback is provided it will be executed to produce the
1011
- * assigned values. The callback is bound to `thisArg` and invoked with two
1012
- * arguments; (objectValue, sourceValue).
1013
- *
1014
- * @static
1015
- * @memberOf _
1016
- * @type Function
1017
- * @alias extend
1018
- * @category Objects
1019
- * @param {Object} object The destination object.
1020
- * @param {...Object} [source] The source objects.
1021
- * @param {Function} [callback] The function to customize assigning values.
1022
- * @param {*} [thisArg] The `this` binding of `callback`.
1023
- * @returns {Object} Returns the destination object.
1024
- * @example
1025
- *
1026
- * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
1027
- * // => { 'name': 'fred', 'employer': 'slate' }
1028
- *
1029
- * var defaults = _.partialRight(_.assign, function(a, b) {
1030
- * return typeof a == 'undefined' ? b : a;
1031
- * });
1032
- *
1033
- * var object = { 'name': 'barney' };
1034
- * defaults(object, { 'name': 'fred', 'employer': 'slate' });
1035
- * // => { 'name': 'barney', 'employer': 'slate' }
1036
- */
1037
- function assign(object) {
1038
- if (!object) {
1039
- return object;
1040
- }
1041
- for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
1042
- var iterable = arguments[argsIndex];
1043
- if (iterable) {
1044
- for (var key in iterable) {
1045
- object[key] = iterable[key];
1046
- }
1047
- }
1048
- }
1049
- return object;
1050
- }
1051
-
1052
- /**
1053
- * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
1054
- * be cloned, otherwise they will be assigned by reference. If a callback
1055
- * is provided it will be executed to produce the cloned values. If the
1056
- * callback returns `undefined` cloning will be handled by the method instead.
1057
- * The callback is bound to `thisArg` and invoked with one argument; (value).
1058
- *
1059
- * @static
1060
- * @memberOf _
1061
- * @category Objects
1062
- * @param {*} value The value to clone.
1063
- * @param {boolean} [isDeep=false] Specify a deep clone.
1064
- * @param {Function} [callback] The function to customize cloning values.
1065
- * @param {*} [thisArg] The `this` binding of `callback`.
1066
- * @returns {*} Returns the cloned value.
1067
- * @example
1068
- *
1069
- * var characters = [
1070
- * { 'name': 'barney', 'age': 36 },
1071
- * { 'name': 'fred', 'age': 40 }
1072
- * ];
1073
- *
1074
- * var shallow = _.clone(characters);
1075
- * shallow[0] === characters[0];
1076
- * // => true
1077
- *
1078
- * var deep = _.clone(characters, true);
1079
- * deep[0] === characters[0];
1080
- * // => false
1081
- *
1082
- * _.mixin({
1083
- * 'clone': _.partialRight(_.clone, function(value) {
1084
- * return _.isElement(value) ? value.cloneNode(false) : undefined;
1085
- * })
1086
- * });
1087
- *
1088
- * var clone = _.clone(document.body);
1089
- * clone.childNodes.length;
1090
- * // => 0
1091
- */
1092
- function clone(value) {
1093
- return isObject(value)
1094
- ? (isArray(value) ? slice(value) : assign({}, value))
1095
- : value;
1096
- }
1097
-
1098
- /**
1099
- * Assigns own enumerable properties of source object(s) to the destination
1100
- * object for all destination properties that resolve to `undefined`. Once a
1101
- * property is set, additional defaults of the same property will be ignored.
1102
- *
1103
- * @static
1104
- * @memberOf _
1105
- * @type Function
1106
- * @category Objects
1107
- * @param {Object} object The destination object.
1108
- * @param {...Object} [source] The source objects.
1109
- * @param- {Object} [guard] Allows working with `_.reduce` without using its
1110
- * `key` and `object` arguments as sources.
1111
- * @returns {Object} Returns the destination object.
1112
- * @example
1113
- *
1114
- * var object = { 'name': 'barney' };
1115
- * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
1116
- * // => { 'name': 'barney', 'employer': 'slate' }
1117
- */
1118
- function defaults(object) {
1119
- if (!object) {
1120
- return object;
1121
- }
1122
- for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
1123
- var iterable = arguments[argsIndex];
1124
- if (iterable) {
1125
- for (var key in iterable) {
1126
- if (typeof object[key] == 'undefined') {
1127
- object[key] = iterable[key];
1128
- }
1129
- }
1130
- }
1131
- }
1132
- return object;
1133
- }
1134
-
1135
- /**
1136
- * Iterates over own and inherited enumerable properties of an object,
1137
- * executing the callback for each property. The callback is bound to `thisArg`
1138
- * and invoked with three arguments; (value, key, object). Callbacks may exit
1139
- * iteration early by explicitly returning `false`.
1140
- *
1141
- * @static
1142
- * @memberOf _
1143
- * @type Function
1144
- * @category Objects
1145
- * @param {Object} object The object to iterate over.
1146
- * @param {Function} [callback=identity] The function called per iteration.
1147
- * @param {*} [thisArg] The `this` binding of `callback`.
1148
- * @returns {Object} Returns `object`.
1149
- * @example
1150
- *
1151
- * function Shape() {
1152
- * this.x = 0;
1153
- * this.y = 0;
1154
- * }
1155
- *
1156
- * Shape.prototype.move = function(x, y) {
1157
- * this.x += x;
1158
- * this.y += y;
1159
- * };
1160
- *
1161
- * _.forIn(new Shape, function(value, key) {
1162
- * console.log(key);
1163
- * });
1164
- * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
1165
- */
1166
- var forIn = function(collection, callback) {
1167
- var index, iterable = collection, result = iterable;
1168
- if (!iterable) return result;
1169
- if (!objectTypes[typeof iterable]) return result;
1170
- for (index in iterable) {
1171
- if (callback(iterable[index], index, collection) === indicatorObject) return result;
1172
- }
1173
- return result
1174
- };
1175
-
1176
- /**
1177
- * Iterates over own enumerable properties of an object, executing the callback
1178
- * for each property. The callback is bound to `thisArg` and invoked with three
1179
- * arguments; (value, key, object). Callbacks may exit iteration early by
1180
- * explicitly returning `false`.
1181
- *
1182
- * @static
1183
- * @memberOf _
1184
- * @type Function
1185
- * @category Objects
1186
- * @param {Object} object The object to iterate over.
1187
- * @param {Function} [callback=identity] The function called per iteration.
1188
- * @param {*} [thisArg] The `this` binding of `callback`.
1189
- * @returns {Object} Returns `object`.
1190
- * @example
1191
- *
1192
- * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
1193
- * console.log(key);
1194
- * });
1195
- * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
1196
- */
1197
- var forOwn = function(collection, callback) {
1198
- var index, iterable = collection, result = iterable;
1199
- if (!iterable) return result;
1200
- if (!objectTypes[typeof iterable]) return result;
1201
- for (index in iterable) {
1202
- if (hasOwnProperty.call(iterable, index)) {
1203
- if (callback(iterable[index], index, collection) === indicatorObject) return result;
1204
- }
1205
- }
1206
- return result
1207
- };
1208
-
1209
- /**
1210
- * Creates a sorted array of property names of all enumerable properties,
1211
- * own and inherited, of `object` that have function values.
1212
- *
1213
- * @static
1214
- * @memberOf _
1215
- * @alias methods
1216
- * @category Objects
1217
- * @param {Object} object The object to inspect.
1218
- * @returns {Array} Returns an array of property names that have function values.
1219
- * @example
1220
- *
1221
- * _.functions(_);
1222
- * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
1223
- */
1224
- function functions(object) {
1225
- var result = [];
1226
- forIn(object, function(value, key) {
1227
- if (isFunction(value)) {
1228
- result.push(key);
1229
- }
1230
- });
1231
- return result.sort();
1232
- }
1233
-
1234
- /**
1235
- * Checks if the specified property name exists as a direct property of `object`,
1236
- * instead of an inherited property.
1237
- *
1238
- * @static
1239
- * @memberOf _
1240
- * @category Objects
1241
- * @param {Object} object The object to inspect.
1242
- * @param {string} key The name of the property to check.
1243
- * @returns {boolean} Returns `true` if key is a direct property, else `false`.
1244
- * @example
1245
- *
1246
- * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
1247
- * // => true
1248
- */
1249
- function has(object, key) {
1250
- return object ? hasOwnProperty.call(object, key) : false;
1251
- }
1252
-
1253
- /**
1254
- * Creates an object composed of the inverted keys and values of the given object.
1255
- *
1256
- * @static
1257
- * @memberOf _
1258
- * @category Objects
1259
- * @param {Object} object The object to invert.
1260
- * @returns {Object} Returns the created inverted object.
1261
- * @example
1262
- *
1263
- * _.invert({ 'first': 'fred', 'second': 'barney' });
1264
- * // => { 'fred': 'first', 'barney': 'second' }
1265
- */
1266
- function invert(object) {
1267
- var index = -1,
1268
- props = keys(object),
1269
- length = props.length,
1270
- result = {};
1271
-
1272
- while (++index < length) {
1273
- var key = props[index];
1274
- result[object[key]] = key;
1275
- }
1276
- return result;
1277
- }
1278
-
1279
- /**
1280
- * Checks if `value` is a boolean value.
1281
- *
1282
- * @static
1283
- * @memberOf _
1284
- * @category Objects
1285
- * @param {*} value The value to check.
1286
- * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
1287
- * @example
1288
- *
1289
- * _.isBoolean(null);
1290
- * // => false
1291
- */
1292
- function isBoolean(value) {
1293
- return value === true || value === false ||
1294
- value && typeof value == 'object' && toString.call(value) == boolClass || false;
1295
- }
1296
-
1297
- /**
1298
- * Checks if `value` is a date.
1299
- *
1300
- * @static
1301
- * @memberOf _
1302
- * @category Objects
1303
- * @param {*} value The value to check.
1304
- * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
1305
- * @example
1306
- *
1307
- * _.isDate(new Date);
1308
- * // => true
1309
- */
1310
- function isDate(value) {
1311
- return value && typeof value == 'object' && toString.call(value) == dateClass || false;
1312
- }
1313
-
1314
- /**
1315
- * Checks if `value` is a DOM element.
1316
- *
1317
- * @static
1318
- * @memberOf _
1319
- * @category Objects
1320
- * @param {*} value The value to check.
1321
- * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
1322
- * @example
1323
- *
1324
- * _.isElement(document.body);
1325
- * // => true
1326
- */
1327
- function isElement(value) {
1328
- return value && value.nodeType === 1 || false;
1329
- }
1330
-
1331
- /**
1332
- * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
1333
- * length of `0` and objects with no own enumerable properties are considered
1334
- * "empty".
1335
- *
1336
- * @static
1337
- * @memberOf _
1338
- * @category Objects
1339
- * @param {Array|Object|string} value The value to inspect.
1340
- * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
1341
- * @example
1342
- *
1343
- * _.isEmpty([1, 2, 3]);
1344
- * // => false
1345
- *
1346
- * _.isEmpty({});
1347
- * // => true
1348
- *
1349
- * _.isEmpty('');
1350
- * // => true
1351
- */
1352
- function isEmpty(value) {
1353
- if (!value) {
1354
- return true;
1355
- }
1356
- if (isArray(value) || isString(value)) {
1357
- return !value.length;
1358
- }
1359
- for (var key in value) {
1360
- if (hasOwnProperty.call(value, key)) {
1361
- return false;
1362
- }
1363
- }
1364
- return true;
1365
- }
1366
-
1367
- /**
1368
- * Performs a deep comparison between two values to determine if they are
1369
- * equivalent to each other. If a callback is provided it will be executed
1370
- * to compare values. If the callback returns `undefined` comparisons will
1371
- * be handled by the method instead. The callback is bound to `thisArg` and
1372
- * invoked with two arguments; (a, b).
1373
- *
1374
- * @static
1375
- * @memberOf _
1376
- * @category Objects
1377
- * @param {*} a The value to compare.
1378
- * @param {*} b The other value to compare.
1379
- * @param {Function} [callback] The function to customize comparing values.
1380
- * @param {*} [thisArg] The `this` binding of `callback`.
1381
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1382
- * @example
1383
- *
1384
- * var object = { 'name': 'fred' };
1385
- * var copy = { 'name': 'fred' };
1386
- *
1387
- * object == copy;
1388
- * // => false
1389
- *
1390
- * _.isEqual(object, copy);
1391
- * // => true
1392
- *
1393
- * var words = ['hello', 'goodbye'];
1394
- * var otherWords = ['hi', 'goodbye'];
1395
- *
1396
- * _.isEqual(words, otherWords, function(a, b) {
1397
- * var reGreet = /^(?:hello|hi)$/i,
1398
- * aGreet = _.isString(a) && reGreet.test(a),
1399
- * bGreet = _.isString(b) && reGreet.test(b);
1400
- *
1401
- * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
1402
- * });
1403
- * // => true
1404
- */
1405
- function isEqual(a, b) {
1406
- return baseIsEqual(a, b);
1407
- }
1408
-
1409
- /**
1410
- * Checks if `value` is, or can be coerced to, a finite number.
1411
- *
1412
- * Note: This is not the same as native `isFinite` which will return true for
1413
- * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
1414
- *
1415
- * @static
1416
- * @memberOf _
1417
- * @category Objects
1418
- * @param {*} value The value to check.
1419
- * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
1420
- * @example
1421
- *
1422
- * _.isFinite(-101);
1423
- * // => true
1424
- *
1425
- * _.isFinite('10');
1426
- * // => true
1427
- *
1428
- * _.isFinite(true);
1429
- * // => false
1430
- *
1431
- * _.isFinite('');
1432
- * // => false
1433
- *
1434
- * _.isFinite(Infinity);
1435
- * // => false
1436
- */
1437
- function isFinite(value) {
1438
- return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
1439
- }
1440
-
1441
- /**
1442
- * Checks if `value` is a function.
1443
- *
1444
- * @static
1445
- * @memberOf _
1446
- * @category Objects
1447
- * @param {*} value The value to check.
1448
- * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
1449
- * @example
1450
- *
1451
- * _.isFunction(_);
1452
- * // => true
1453
- */
1454
- function isFunction(value) {
1455
- return typeof value == 'function';
1456
- }
1457
- // fallback for older versions of Chrome and Safari
1458
- if (isFunction(/x/)) {
1459
- isFunction = function(value) {
1460
- return typeof value == 'function' && toString.call(value) == funcClass;
1461
- };
1462
- }
1463
-
1464
- /**
1465
- * Checks if `value` is the language type of Object.
1466
- * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
1467
- *
1468
- * @static
1469
- * @memberOf _
1470
- * @category Objects
1471
- * @param {*} value The value to check.
1472
- * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
1473
- * @example
1474
- *
1475
- * _.isObject({});
1476
- * // => true
1477
- *
1478
- * _.isObject([1, 2, 3]);
1479
- * // => true
1480
- *
1481
- * _.isObject(1);
1482
- * // => false
1483
- */
1484
- function isObject(value) {
1485
- // check if the value is the ECMAScript language type of Object
1486
- // http://es5.github.io/#x8
1487
- // and avoid a V8 bug
1488
- // http://code.google.com/p/v8/issues/detail?id=2291
1489
- return !!(value && objectTypes[typeof value]);
1490
- }
1491
-
1492
- /**
1493
- * Checks if `value` is `NaN`.
1494
- *
1495
- * Note: This is not the same as native `isNaN` which will return `true` for
1496
- * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
1497
- *
1498
- * @static
1499
- * @memberOf _
1500
- * @category Objects
1501
- * @param {*} value The value to check.
1502
- * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
1503
- * @example
1504
- *
1505
- * _.isNaN(NaN);
1506
- * // => true
1507
- *
1508
- * _.isNaN(new Number(NaN));
1509
- * // => true
1510
- *
1511
- * isNaN(undefined);
1512
- * // => true
1513
- *
1514
- * _.isNaN(undefined);
1515
- * // => false
1516
- */
1517
- function isNaN(value) {
1518
- // `NaN` as a primitive is the only value that is not equal to itself
1519
- // (perform the [[Class]] check first to avoid errors with some host objects in IE)
1520
- return isNumber(value) && value != +value;
1521
- }
1522
-
1523
- /**
1524
- * Checks if `value` is `null`.
1525
- *
1526
- * @static
1527
- * @memberOf _
1528
- * @category Objects
1529
- * @param {*} value The value to check.
1530
- * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
1531
- * @example
1532
- *
1533
- * _.isNull(null);
1534
- * // => true
1535
- *
1536
- * _.isNull(undefined);
1537
- * // => false
1538
- */
1539
- function isNull(value) {
1540
- return value === null;
1541
- }
1542
-
1543
- /**
1544
- * Checks if `value` is a number.
1545
- *
1546
- * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
1547
- *
1548
- * @static
1549
- * @memberOf _
1550
- * @category Objects
1551
- * @param {*} value The value to check.
1552
- * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
1553
- * @example
1554
- *
1555
- * _.isNumber(8.4 * 5);
1556
- * // => true
1557
- */
1558
- function isNumber(value) {
1559
- return typeof value == 'number' ||
1560
- value && typeof value == 'object' && toString.call(value) == numberClass || false;
1561
- }
1562
-
1563
- /**
1564
- * Checks if `value` is a regular expression.
1565
- *
1566
- * @static
1567
- * @memberOf _
1568
- * @category Objects
1569
- * @param {*} value The value to check.
1570
- * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
1571
- * @example
1572
- *
1573
- * _.isRegExp(/fred/);
1574
- * // => true
1575
- */
1576
- function isRegExp(value) {
1577
- return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
1578
- }
1579
-
1580
- /**
1581
- * Checks if `value` is a string.
1582
- *
1583
- * @static
1584
- * @memberOf _
1585
- * @category Objects
1586
- * @param {*} value The value to check.
1587
- * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
1588
- * @example
1589
- *
1590
- * _.isString('fred');
1591
- * // => true
1592
- */
1593
- function isString(value) {
1594
- return typeof value == 'string' ||
1595
- value && typeof value == 'object' && toString.call(value) == stringClass || false;
1596
- }
1597
-
1598
- /**
1599
- * Checks if `value` is `undefined`.
1600
- *
1601
- * @static
1602
- * @memberOf _
1603
- * @category Objects
1604
- * @param {*} value The value to check.
1605
- * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
1606
- * @example
1607
- *
1608
- * _.isUndefined(void 0);
1609
- * // => true
1610
- */
1611
- function isUndefined(value) {
1612
- return typeof value == 'undefined';
1613
- }
1614
-
1615
- /**
1616
- * Creates a shallow clone of `object` excluding the specified properties.
1617
- * Property names may be specified as individual arguments or as arrays of
1618
- * property names. If a callback is provided it will be executed for each
1619
- * property of `object` omitting the properties the callback returns truey
1620
- * for. The callback is bound to `thisArg` and invoked with three arguments;
1621
- * (value, key, object).
1622
- *
1623
- * @static
1624
- * @memberOf _
1625
- * @category Objects
1626
- * @param {Object} object The source object.
1627
- * @param {Function|...string|string[]} [callback] The properties to omit or the
1628
- * function called per iteration.
1629
- * @param {*} [thisArg] The `this` binding of `callback`.
1630
- * @returns {Object} Returns an object without the omitted properties.
1631
- * @example
1632
- *
1633
- * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
1634
- * // => { 'name': 'fred' }
1635
- *
1636
- * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
1637
- * return typeof value == 'number';
1638
- * });
1639
- * // => { 'name': 'fred' }
1640
- */
1641
- function omit(object) {
1642
- var props = [];
1643
- forIn(object, function(value, key) {
1644
- props.push(key);
1645
- });
1646
- props = baseDifference(props, baseFlatten(arguments, true, false, 1));
1647
-
1648
- var index = -1,
1649
- length = props.length,
1650
- result = {};
1651
-
1652
- while (++index < length) {
1653
- var key = props[index];
1654
- result[key] = object[key];
1655
- }
1656
- return result;
1657
- }
1658
-
1659
- /**
1660
- * Creates a two dimensional array of an object's key-value pairs,
1661
- * i.e. `[[key1, value1], [key2, value2]]`.
1662
- *
1663
- * @static
1664
- * @memberOf _
1665
- * @category Objects
1666
- * @param {Object} object The object to inspect.
1667
- * @returns {Array} Returns new array of key-value pairs.
1668
- * @example
1669
- *
1670
- * _.pairs({ 'barney': 36, 'fred': 40 });
1671
- * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
1672
- */
1673
- function pairs(object) {
1674
- var index = -1,
1675
- props = keys(object),
1676
- length = props.length,
1677
- result = Array(length);
1678
-
1679
- while (++index < length) {
1680
- var key = props[index];
1681
- result[index] = [key, object[key]];
1682
- }
1683
- return result;
1684
- }
1685
-
1686
- /**
1687
- * Creates a shallow clone of `object` composed of the specified properties.
1688
- * Property names may be specified as individual arguments or as arrays of
1689
- * property names. If a callback is provided it will be executed for each
1690
- * property of `object` picking the properties the callback returns truey
1691
- * for. The callback is bound to `thisArg` and invoked with three arguments;
1692
- * (value, key, object).
1693
- *
1694
- * @static
1695
- * @memberOf _
1696
- * @category Objects
1697
- * @param {Object} object The source object.
1698
- * @param {Function|...string|string[]} [callback] The function called per
1699
- * iteration or property names to pick, specified as individual property
1700
- * names or arrays of property names.
1701
- * @param {*} [thisArg] The `this` binding of `callback`.
1702
- * @returns {Object} Returns an object composed of the picked properties.
1703
- * @example
1704
- *
1705
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
1706
- * // => { 'name': 'fred' }
1707
- *
1708
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
1709
- * return key.charAt(0) != '_';
1710
- * });
1711
- * // => { 'name': 'fred' }
1712
- */
1713
- function pick(object) {
1714
- var index = -1,
1715
- props = baseFlatten(arguments, true, false, 1),
1716
- length = props.length,
1717
- result = {};
1718
-
1719
- while (++index < length) {
1720
- var key = props[index];
1721
- if (key in object) {
1722
- result[key] = object[key];
1723
- }
1724
- }
1725
- return result;
1726
- }
1727
-
1728
- /**
1729
- * Creates an array composed of the own enumerable property values of `object`.
1730
- *
1731
- * @static
1732
- * @memberOf _
1733
- * @category Objects
1734
- * @param {Object} object The object to inspect.
1735
- * @returns {Array} Returns an array of property values.
1736
- * @example
1737
- *
1738
- * _.values({ 'one': 1, 'two': 2, 'three': 3 });
1739
- * // => [1, 2, 3] (property order is not guaranteed across environments)
1740
- */
1741
- function values(object) {
1742
- var index = -1,
1743
- props = keys(object),
1744
- length = props.length,
1745
- result = Array(length);
1746
-
1747
- while (++index < length) {
1748
- result[index] = object[props[index]];
1749
- }
1750
- return result;
1751
- }
1752
-
1753
- /*--------------------------------------------------------------------------*/
1754
-
1755
- /**
1756
- * Checks if a given value is present in a collection using strict equality
1757
- * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
1758
- * offset from the end of the collection.
1759
- *
1760
- * @static
1761
- * @memberOf _
1762
- * @alias include
1763
- * @category Collections
1764
- * @param {Array|Object|string} collection The collection to iterate over.
1765
- * @param {*} target The value to check for.
1766
- * @param {number} [fromIndex=0] The index to search from.
1767
- * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
1768
- * @example
1769
- *
1770
- * _.contains([1, 2, 3], 1);
1771
- * // => true
1772
- *
1773
- * _.contains([1, 2, 3], 1, 2);
1774
- * // => false
1775
- *
1776
- * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
1777
- * // => true
1778
- *
1779
- * _.contains('pebbles', 'eb');
1780
- * // => true
1781
- */
1782
- function contains(collection, target) {
1783
- var indexOf = getIndexOf(),
1784
- length = collection ? collection.length : 0,
1785
- result = false;
1786
- if (length && typeof length == 'number') {
1787
- result = indexOf(collection, target) > -1;
1788
- } else {
1789
- forOwn(collection, function(value) {
1790
- return (result = value === target) && indicatorObject;
1791
- });
1792
- }
1793
- return result;
1794
- }
1795
-
1796
- /**
1797
- * Creates an object composed of keys generated from the results of running
1798
- * each element of `collection` through the callback. The corresponding value
1799
- * of each key is the number of times the key was returned by the callback.
1800
- * The callback is bound to `thisArg` and invoked with three arguments;
1801
- * (value, index|key, collection).
1802
- *
1803
- * If a property name is provided for `callback` the created "_.pluck" style
1804
- * callback will return the property value of the given element.
1805
- *
1806
- * If an object is provided for `callback` the created "_.where" style callback
1807
- * will return `true` for elements that have the properties of the given object,
1808
- * else `false`.
1809
- *
1810
- * @static
1811
- * @memberOf _
1812
- * @category Collections
1813
- * @param {Array|Object|string} collection The collection to iterate over.
1814
- * @param {Function|Object|string} [callback=identity] The function called
1815
- * per iteration. If a property name or object is provided it will be used
1816
- * to create a "_.pluck" or "_.where" style callback, respectively.
1817
- * @param {*} [thisArg] The `this` binding of `callback`.
1818
- * @returns {Object} Returns the composed aggregate object.
1819
- * @example
1820
- *
1821
- * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
1822
- * // => { '4': 1, '6': 2 }
1823
- *
1824
- * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
1825
- * // => { '4': 1, '6': 2 }
1826
- *
1827
- * _.countBy(['one', 'two', 'three'], 'length');
1828
- * // => { '3': 2, '5': 1 }
1829
- */
1830
- var countBy = createAggregator(function(result, value, key) {
1831
- (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
1832
- });
1833
-
1834
- /**
1835
- * Checks if the given callback returns truey value for **all** elements of
1836
- * a collection. The callback is bound to `thisArg` and invoked with three
1837
- * arguments; (value, index|key, collection).
1838
- *
1839
- * If a property name is provided for `callback` the created "_.pluck" style
1840
- * callback will return the property value of the given element.
1841
- *
1842
- * If an object is provided for `callback` the created "_.where" style callback
1843
- * will return `true` for elements that have the properties of the given object,
1844
- * else `false`.
1845
- *
1846
- * @static
1847
- * @memberOf _
1848
- * @alias all
1849
- * @category Collections
1850
- * @param {Array|Object|string} collection The collection to iterate over.
1851
- * @param {Function|Object|string} [callback=identity] The function called
1852
- * per iteration. If a property name or object is provided it will be used
1853
- * to create a "_.pluck" or "_.where" style callback, respectively.
1854
- * @param {*} [thisArg] The `this` binding of `callback`.
1855
- * @returns {boolean} Returns `true` if all elements passed the callback check,
1856
- * else `false`.
1857
- * @example
1858
- *
1859
- * _.every([true, 1, null, 'yes']);
1860
- * // => false
1861
- *
1862
- * var characters = [
1863
- * { 'name': 'barney', 'age': 36 },
1864
- * { 'name': 'fred', 'age': 40 }
1865
- * ];
1866
- *
1867
- * // using "_.pluck" callback shorthand
1868
- * _.every(characters, 'age');
1869
- * // => true
1870
- *
1871
- * // using "_.where" callback shorthand
1872
- * _.every(characters, { 'age': 36 });
1873
- * // => false
1874
- */
1875
- function every(collection, callback, thisArg) {
1876
- var result = true;
1877
- callback = createCallback(callback, thisArg, 3);
1878
-
1879
- var index = -1,
1880
- length = collection ? collection.length : 0;
1881
-
1882
- if (typeof length == 'number') {
1883
- while (++index < length) {
1884
- if (!(result = !!callback(collection[index], index, collection))) {
1885
- break;
1886
- }
1887
- }
1888
- } else {
1889
- forOwn(collection, function(value, index, collection) {
1890
- return !(result = !!callback(value, index, collection)) && indicatorObject;
1891
- });
1892
- }
1893
- return result;
1894
- }
1895
-
1896
- /**
1897
- * Iterates over elements of a collection, returning an array of all elements
1898
- * the callback returns truey for. The callback is bound to `thisArg` and
1899
- * invoked with three arguments; (value, index|key, collection).
1900
- *
1901
- * If a property name is provided for `callback` the created "_.pluck" style
1902
- * callback will return the property value of the given element.
1903
- *
1904
- * If an object is provided for `callback` the created "_.where" style callback
1905
- * will return `true` for elements that have the properties of the given object,
1906
- * else `false`.
1907
- *
1908
- * @static
1909
- * @memberOf _
1910
- * @alias select
1911
- * @category Collections
1912
- * @param {Array|Object|string} collection The collection to iterate over.
1913
- * @param {Function|Object|string} [callback=identity] The function called
1914
- * per iteration. If a property name or object is provided it will be used
1915
- * to create a "_.pluck" or "_.where" style callback, respectively.
1916
- * @param {*} [thisArg] The `this` binding of `callback`.
1917
- * @returns {Array} Returns a new array of elements that passed the callback check.
1918
- * @example
1919
- *
1920
- * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
1921
- * // => [2, 4, 6]
1922
- *
1923
- * var characters = [
1924
- * { 'name': 'barney', 'age': 36, 'blocked': false },
1925
- * { 'name': 'fred', 'age': 40, 'blocked': true }
1926
- * ];
1927
- *
1928
- * // using "_.pluck" callback shorthand
1929
- * _.filter(characters, 'blocked');
1930
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
1931
- *
1932
- * // using "_.where" callback shorthand
1933
- * _.filter(characters, { 'age': 36 });
1934
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
1935
- */
1936
- function filter(collection, callback, thisArg) {
1937
- var result = [];
1938
- callback = createCallback(callback, thisArg, 3);
1939
-
1940
- var index = -1,
1941
- length = collection ? collection.length : 0;
1942
-
1943
- if (typeof length == 'number') {
1944
- while (++index < length) {
1945
- var value = collection[index];
1946
- if (callback(value, index, collection)) {
1947
- result.push(value);
1948
- }
1949
- }
1950
- } else {
1951
- forOwn(collection, function(value, index, collection) {
1952
- if (callback(value, index, collection)) {
1953
- result.push(value);
1954
- }
1955
- });
1956
- }
1957
- return result;
1958
- }
1959
-
1960
- /**
1961
- * Iterates over elements of a collection, returning the first element that
1962
- * the callback returns truey for. The callback is bound to `thisArg` and
1963
- * invoked with three arguments; (value, index|key, collection).
1964
- *
1965
- * If a property name is provided for `callback` the created "_.pluck" style
1966
- * callback will return the property value of the given element.
1967
- *
1968
- * If an object is provided for `callback` the created "_.where" style callback
1969
- * will return `true` for elements that have the properties of the given object,
1970
- * else `false`.
1971
- *
1972
- * @static
1973
- * @memberOf _
1974
- * @alias detect, findWhere
1975
- * @category Collections
1976
- * @param {Array|Object|string} collection The collection to iterate over.
1977
- * @param {Function|Object|string} [callback=identity] The function called
1978
- * per iteration. If a property name or object is provided it will be used
1979
- * to create a "_.pluck" or "_.where" style callback, respectively.
1980
- * @param {*} [thisArg] The `this` binding of `callback`.
1981
- * @returns {*} Returns the found element, else `undefined`.
1982
- * @example
1983
- *
1984
- * var characters = [
1985
- * { 'name': 'barney', 'age': 36, 'blocked': false },
1986
- * { 'name': 'fred', 'age': 40, 'blocked': true },
1987
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
1988
- * ];
1989
- *
1990
- * _.find(characters, function(chr) {
1991
- * return chr.age < 40;
1992
- * });
1993
- * // => { 'name': 'barney', 'age': 36, 'blocked': false }
1994
- *
1995
- * // using "_.where" callback shorthand
1996
- * _.find(characters, { 'age': 1 });
1997
- * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
1998
- *
1999
- * // using "_.pluck" callback shorthand
2000
- * _.find(characters, 'blocked');
2001
- * // => { 'name': 'fred', 'age': 40, 'blocked': true }
2002
- */
2003
- function find(collection, callback, thisArg) {
2004
- callback = createCallback(callback, thisArg, 3);
2005
-
2006
- var index = -1,
2007
- length = collection ? collection.length : 0;
2008
-
2009
- if (typeof length == 'number') {
2010
- while (++index < length) {
2011
- var value = collection[index];
2012
- if (callback(value, index, collection)) {
2013
- return value;
2014
- }
2015
- }
2016
- } else {
2017
- var result;
2018
- forOwn(collection, function(value, index, collection) {
2019
- if (callback(value, index, collection)) {
2020
- result = value;
2021
- return indicatorObject;
2022
- }
2023
- });
2024
- return result;
2025
- }
2026
- }
2027
-
2028
- /**
2029
- * Examines each element in a `collection`, returning the first that
2030
- * has the given properties. When checking `properties`, this method
2031
- * performs a deep comparison between values to determine if they are
2032
- * equivalent to each other.
2033
- *
2034
- * @static
2035
- * @memberOf _
2036
- * @category Collections
2037
- * @param {Array|Object|string} collection The collection to iterate over.
2038
- * @param {Object} properties The object of property values to filter by.
2039
- * @returns {*} Returns the found element, else `undefined`.
2040
- * @example
2041
- *
2042
- * var food = [
2043
- * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
2044
- * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
2045
- * { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
2046
- * ];
2047
- *
2048
- * _.findWhere(food, { 'type': 'vegetable' });
2049
- * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
2050
- */
2051
- function findWhere(object, properties) {
2052
- return where(object, properties, true);
2053
- }
2054
-
2055
- /**
2056
- * Iterates over elements of a collection, executing the callback for each
2057
- * element. The callback is bound to `thisArg` and invoked with three arguments;
2058
- * (value, index|key, collection). Callbacks may exit iteration early by
2059
- * explicitly returning `false`.
2060
- *
2061
- * Note: As with other "Collections" methods, objects with a `length` property
2062
- * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
2063
- * may be used for object iteration.
2064
- *
2065
- * @static
2066
- * @memberOf _
2067
- * @alias each
2068
- * @category Collections
2069
- * @param {Array|Object|string} collection The collection to iterate over.
2070
- * @param {Function} [callback=identity] The function called per iteration.
2071
- * @param {*} [thisArg] The `this` binding of `callback`.
2072
- * @returns {Array|Object|string} Returns `collection`.
2073
- * @example
2074
- *
2075
- * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
2076
- * // => logs each number and returns '1,2,3'
2077
- *
2078
- * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
2079
- * // => logs each number and returns the object (property order is not guaranteed across environments)
2080
- */
2081
- function forEach(collection, callback, thisArg) {
2082
- var index = -1,
2083
- length = collection ? collection.length : 0;
2084
-
2085
- callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
2086
- if (typeof length == 'number') {
2087
- while (++index < length) {
2088
- if (callback(collection[index], index, collection) === indicatorObject) {
2089
- break;
2090
- }
2091
- }
2092
- } else {
2093
- forOwn(collection, callback);
2094
- }
2095
- }
2096
-
2097
- /**
2098
- * This method is like `_.forEach` except that it iterates over elements
2099
- * of a `collection` from right to left.
2100
- *
2101
- * @static
2102
- * @memberOf _
2103
- * @alias eachRight
2104
- * @category Collections
2105
- * @param {Array|Object|string} collection The collection to iterate over.
2106
- * @param {Function} [callback=identity] The function called per iteration.
2107
- * @param {*} [thisArg] The `this` binding of `callback`.
2108
- * @returns {Array|Object|string} Returns `collection`.
2109
- * @example
2110
- *
2111
- * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
2112
- * // => logs each number from right to left and returns '3,2,1'
2113
- */
2114
- function forEachRight(collection, callback) {
2115
- var length = collection ? collection.length : 0;
2116
- if (typeof length == 'number') {
2117
- while (length--) {
2118
- if (callback(collection[length], length, collection) === false) {
2119
- break;
2120
- }
2121
- }
2122
- } else {
2123
- var props = keys(collection);
2124
- length = props.length;
2125
- forOwn(collection, function(value, key, collection) {
2126
- key = props ? props[--length] : --length;
2127
- return callback(collection[key], key, collection) === false && indicatorObject;
2128
- });
2129
- }
2130
- }
2131
-
2132
- /**
2133
- * Creates an object composed of keys generated from the results of running
2134
- * each element of a collection through the callback. The corresponding value
2135
- * of each key is an array of the elements responsible for generating the key.
2136
- * The callback is bound to `thisArg` and invoked with three arguments;
2137
- * (value, index|key, collection).
2138
- *
2139
- * If a property name is provided for `callback` the created "_.pluck" style
2140
- * callback will return the property value of the given element.
2141
- *
2142
- * If an object is provided for `callback` the created "_.where" style callback
2143
- * will return `true` for elements that have the properties of the given object,
2144
- * else `false`
2145
- *
2146
- * @static
2147
- * @memberOf _
2148
- * @category Collections
2149
- * @param {Array|Object|string} collection The collection to iterate over.
2150
- * @param {Function|Object|string} [callback=identity] The function called
2151
- * per iteration. If a property name or object is provided it will be used
2152
- * to create a "_.pluck" or "_.where" style callback, respectively.
2153
- * @param {*} [thisArg] The `this` binding of `callback`.
2154
- * @returns {Object} Returns the composed aggregate object.
2155
- * @example
2156
- *
2157
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
2158
- * // => { '4': [4.2], '6': [6.1, 6.4] }
2159
- *
2160
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
2161
- * // => { '4': [4.2], '6': [6.1, 6.4] }
2162
- *
2163
- * // using "_.pluck" callback shorthand
2164
- * _.groupBy(['one', 'two', 'three'], 'length');
2165
- * // => { '3': ['one', 'two'], '5': ['three'] }
2166
- */
2167
- var groupBy = createAggregator(function(result, value, key) {
2168
- (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
2169
- });
2170
-
2171
- /**
2172
- * Creates an object composed of keys generated from the results of running
2173
- * each element of the collection through the given callback. The corresponding
2174
- * value of each key is the last element responsible for generating the key.
2175
- * The callback is bound to `thisArg` and invoked with three arguments;
2176
- * (value, index|key, collection).
2177
- *
2178
- * If a property name is provided for `callback` the created "_.pluck" style
2179
- * callback will return the property value of the given element.
2180
- *
2181
- * If an object is provided for `callback` the created "_.where" style callback
2182
- * will return `true` for elements that have the properties of the given object,
2183
- * else `false`.
2184
- *
2185
- * @static
2186
- * @memberOf _
2187
- * @category Collections
2188
- * @param {Array|Object|string} collection The collection to iterate over.
2189
- * @param {Function|Object|string} [callback=identity] The function called
2190
- * per iteration. If a property name or object is provided it will be used
2191
- * to create a "_.pluck" or "_.where" style callback, respectively.
2192
- * @param {*} [thisArg] The `this` binding of `callback`.
2193
- * @returns {Object} Returns the composed aggregate object.
2194
- * @example
2195
- *
2196
- * var keys = [
2197
- * { 'dir': 'left', 'code': 97 },
2198
- * { 'dir': 'right', 'code': 100 }
2199
- * ];
2200
- *
2201
- * _.indexBy(keys, 'dir');
2202
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
2203
- *
2204
- * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
2205
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
2206
- *
2207
- * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
2208
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
2209
- */
2210
- var indexBy = createAggregator(function(result, value, key) {
2211
- result[key] = value;
2212
- });
2213
-
2214
- /**
2215
- * Invokes the method named by `methodName` on each element in the `collection`
2216
- * returning an array of the results of each invoked method. Additional arguments
2217
- * will be provided to each invoked method. If `methodName` is a function it
2218
- * will be invoked for, and `this` bound to, each element in the `collection`.
2219
- *
2220
- * @static
2221
- * @memberOf _
2222
- * @category Collections
2223
- * @param {Array|Object|string} collection The collection to iterate over.
2224
- * @param {Function|string} methodName The name of the method to invoke or
2225
- * the function invoked per iteration.
2226
- * @param {...*} [arg] Arguments to invoke the method with.
2227
- * @returns {Array} Returns a new array of the results of each invoked method.
2228
- * @example
2229
- *
2230
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
2231
- * // => [[1, 5, 7], [1, 2, 3]]
2232
- *
2233
- * _.invoke([123, 456], String.prototype.split, '');
2234
- * // => [['1', '2', '3'], ['4', '5', '6']]
2235
- */
2236
- function invoke(collection, methodName) {
2237
- var args = slice(arguments, 2),
2238
- index = -1,
2239
- isFunc = typeof methodName == 'function',
2240
- length = collection ? collection.length : 0,
2241
- result = Array(typeof length == 'number' ? length : 0);
2242
-
2243
- forEach(collection, function(value) {
2244
- result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
2245
- });
2246
- return result;
2247
- }
2248
-
2249
- /**
2250
- * Creates an array of values by running each element in the collection
2251
- * through the callback. The callback is bound to `thisArg` and invoked with
2252
- * three arguments; (value, index|key, collection).
2253
- *
2254
- * If a property name is provided for `callback` the created "_.pluck" style
2255
- * callback will return the property value of the given element.
2256
- *
2257
- * If an object is provided for `callback` the created "_.where" style callback
2258
- * will return `true` for elements that have the properties of the given object,
2259
- * else `false`.
2260
- *
2261
- * @static
2262
- * @memberOf _
2263
- * @alias collect
2264
- * @category Collections
2265
- * @param {Array|Object|string} collection The collection to iterate over.
2266
- * @param {Function|Object|string} [callback=identity] The function called
2267
- * per iteration. If a property name or object is provided it will be used
2268
- * to create a "_.pluck" or "_.where" style callback, respectively.
2269
- * @param {*} [thisArg] The `this` binding of `callback`.
2270
- * @returns {Array} Returns a new array of the results of each `callback` execution.
2271
- * @example
2272
- *
2273
- * _.map([1, 2, 3], function(num) { return num * 3; });
2274
- * // => [3, 6, 9]
2275
- *
2276
- * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
2277
- * // => [3, 6, 9] (property order is not guaranteed across environments)
2278
- *
2279
- * var characters = [
2280
- * { 'name': 'barney', 'age': 36 },
2281
- * { 'name': 'fred', 'age': 40 }
2282
- * ];
2283
- *
2284
- * // using "_.pluck" callback shorthand
2285
- * _.map(characters, 'name');
2286
- * // => ['barney', 'fred']
2287
- */
2288
- function map(collection, callback, thisArg) {
2289
- var index = -1,
2290
- length = collection ? collection.length : 0;
2291
-
2292
- callback = createCallback(callback, thisArg, 3);
2293
- if (typeof length == 'number') {
2294
- var result = Array(length);
2295
- while (++index < length) {
2296
- result[index] = callback(collection[index], index, collection);
2297
- }
2298
- } else {
2299
- result = [];
2300
- forOwn(collection, function(value, key, collection) {
2301
- result[++index] = callback(value, key, collection);
2302
- });
2303
- }
2304
- return result;
2305
- }
2306
-
2307
- /**
2308
- * Retrieves the maximum value of a collection. If the collection is empty or
2309
- * falsey `-Infinity` is returned. If a callback is provided it will be executed
2310
- * for each value in the collection to generate the criterion by which the value
2311
- * is ranked. The callback is bound to `thisArg` and invoked with three
2312
- * arguments; (value, index, collection).
2313
- *
2314
- * If a property name is provided for `callback` the created "_.pluck" style
2315
- * callback will return the property value of the given element.
2316
- *
2317
- * If an object is provided for `callback` the created "_.where" style callback
2318
- * will return `true` for elements that have the properties of the given object,
2319
- * else `false`.
2320
- *
2321
- * @static
2322
- * @memberOf _
2323
- * @category Collections
2324
- * @param {Array|Object|string} collection The collection to iterate over.
2325
- * @param {Function|Object|string} [callback=identity] The function called
2326
- * per iteration. If a property name or object is provided it will be used
2327
- * to create a "_.pluck" or "_.where" style callback, respectively.
2328
- * @param {*} [thisArg] The `this` binding of `callback`.
2329
- * @returns {*} Returns the maximum value.
2330
- * @example
2331
- *
2332
- * _.max([4, 2, 8, 6]);
2333
- * // => 8
2334
- *
2335
- * var characters = [
2336
- * { 'name': 'barney', 'age': 36 },
2337
- * { 'name': 'fred', 'age': 40 }
2338
- * ];
2339
- *
2340
- * _.max(characters, function(chr) { return chr.age; });
2341
- * // => { 'name': 'fred', 'age': 40 };
2342
- *
2343
- * // using "_.pluck" callback shorthand
2344
- * _.max(characters, 'age');
2345
- * // => { 'name': 'fred', 'age': 40 };
2346
- */
2347
- function max(collection, callback, thisArg) {
2348
- var computed = -Infinity,
2349
- result = computed;
2350
-
2351
- // allows working with functions like `_.map` without using
2352
- // their `index` argument as a callback
2353
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
2354
- callback = null;
2355
- }
2356
- var index = -1,
2357
- length = collection ? collection.length : 0;
2358
-
2359
- if (callback == null && typeof length == 'number') {
2360
- while (++index < length) {
2361
- var value = collection[index];
2362
- if (value > result) {
2363
- result = value;
2364
- }
2365
- }
2366
- } else {
2367
- callback = createCallback(callback, thisArg, 3);
2368
-
2369
- forEach(collection, function(value, index, collection) {
2370
- var current = callback(value, index, collection);
2371
- if (current > computed) {
2372
- computed = current;
2373
- result = value;
2374
- }
2375
- });
2376
- }
2377
- return result;
2378
- }
2379
-
2380
- /**
2381
- * Retrieves the minimum value of a collection. If the collection is empty or
2382
- * falsey `Infinity` is returned. If a callback is provided it will be executed
2383
- * for each value in the collection to generate the criterion by which the value
2384
- * is ranked. The callback is bound to `thisArg` and invoked with three
2385
- * arguments; (value, index, collection).
2386
- *
2387
- * If a property name is provided for `callback` the created "_.pluck" style
2388
- * callback will return the property value of the given element.
2389
- *
2390
- * If an object is provided for `callback` the created "_.where" style callback
2391
- * will return `true` for elements that have the properties of the given object,
2392
- * else `false`.
2393
- *
2394
- * @static
2395
- * @memberOf _
2396
- * @category Collections
2397
- * @param {Array|Object|string} collection The collection to iterate over.
2398
- * @param {Function|Object|string} [callback=identity] The function called
2399
- * per iteration. If a property name or object is provided it will be used
2400
- * to create a "_.pluck" or "_.where" style callback, respectively.
2401
- * @param {*} [thisArg] The `this` binding of `callback`.
2402
- * @returns {*} Returns the minimum value.
2403
- * @example
2404
- *
2405
- * _.min([4, 2, 8, 6]);
2406
- * // => 2
2407
- *
2408
- * var characters = [
2409
- * { 'name': 'barney', 'age': 36 },
2410
- * { 'name': 'fred', 'age': 40 }
2411
- * ];
2412
- *
2413
- * _.min(characters, function(chr) { return chr.age; });
2414
- * // => { 'name': 'barney', 'age': 36 };
2415
- *
2416
- * // using "_.pluck" callback shorthand
2417
- * _.min(characters, 'age');
2418
- * // => { 'name': 'barney', 'age': 36 };
2419
- */
2420
- function min(collection, callback, thisArg) {
2421
- var computed = Infinity,
2422
- result = computed;
2423
-
2424
- // allows working with functions like `_.map` without using
2425
- // their `index` argument as a callback
2426
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
2427
- callback = null;
2428
- }
2429
- var index = -1,
2430
- length = collection ? collection.length : 0;
2431
-
2432
- if (callback == null && typeof length == 'number') {
2433
- while (++index < length) {
2434
- var value = collection[index];
2435
- if (value < result) {
2436
- result = value;
2437
- }
2438
- }
2439
- } else {
2440
- callback = createCallback(callback, thisArg, 3);
2441
-
2442
- forEach(collection, function(value, index, collection) {
2443
- var current = callback(value, index, collection);
2444
- if (current < computed) {
2445
- computed = current;
2446
- result = value;
2447
- }
2448
- });
2449
- }
2450
- return result;
2451
- }
2452
-
2453
- /**
2454
- * Retrieves the value of a specified property from all elements in the collection.
2455
- *
2456
- * @static
2457
- * @memberOf _
2458
- * @type Function
2459
- * @category Collections
2460
- * @param {Array|Object|string} collection The collection to iterate over.
2461
- * @param {string} property The name of the property to pluck.
2462
- * @returns {Array} Returns a new array of property values.
2463
- * @example
2464
- *
2465
- * var characters = [
2466
- * { 'name': 'barney', 'age': 36 },
2467
- * { 'name': 'fred', 'age': 40 }
2468
- * ];
2469
- *
2470
- * _.pluck(characters, 'name');
2471
- * // => ['barney', 'fred']
2472
- */
2473
- var pluck = map;
2474
-
2475
- /**
2476
- * Reduces a collection to a value which is the accumulated result of running
2477
- * each element in the collection through the callback, where each successive
2478
- * callback execution consumes the return value of the previous execution. If
2479
- * `accumulator` is not provided the first element of the collection will be
2480
- * used as the initial `accumulator` value. The callback is bound to `thisArg`
2481
- * and invoked with four arguments; (accumulator, value, index|key, collection).
2482
- *
2483
- * @static
2484
- * @memberOf _
2485
- * @alias foldl, inject
2486
- * @category Collections
2487
- * @param {Array|Object|string} collection The collection to iterate over.
2488
- * @param {Function} [callback=identity] The function called per iteration.
2489
- * @param {*} [accumulator] Initial value of the accumulator.
2490
- * @param {*} [thisArg] The `this` binding of `callback`.
2491
- * @returns {*} Returns the accumulated value.
2492
- * @example
2493
- *
2494
- * var sum = _.reduce([1, 2, 3], function(sum, num) {
2495
- * return sum + num;
2496
- * });
2497
- * // => 6
2498
- *
2499
- * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2500
- * result[key] = num * 3;
2501
- * return result;
2502
- * }, {});
2503
- * // => { 'a': 3, 'b': 6, 'c': 9 }
2504
- */
2505
- function reduce(collection, callback, accumulator, thisArg) {
2506
- if (!collection) return accumulator;
2507
- var noaccum = arguments.length < 3;
2508
- callback = createCallback(callback, thisArg, 4);
2509
-
2510
- var index = -1,
2511
- length = collection.length;
2512
-
2513
- if (typeof length == 'number') {
2514
- if (noaccum) {
2515
- accumulator = collection[++index];
2516
- }
2517
- while (++index < length) {
2518
- accumulator = callback(accumulator, collection[index], index, collection);
2519
- }
2520
- } else {
2521
- forOwn(collection, function(value, index, collection) {
2522
- accumulator = noaccum
2523
- ? (noaccum = false, value)
2524
- : callback(accumulator, value, index, collection)
2525
- });
2526
- }
2527
- return accumulator;
2528
- }
2529
-
2530
- /**
2531
- * This method is like `_.reduce` except that it iterates over elements
2532
- * of a `collection` from right to left.
2533
- *
2534
- * @static
2535
- * @memberOf _
2536
- * @alias foldr
2537
- * @category Collections
2538
- * @param {Array|Object|string} collection The collection to iterate over.
2539
- * @param {Function} [callback=identity] The function called per iteration.
2540
- * @param {*} [accumulator] Initial value of the accumulator.
2541
- * @param {*} [thisArg] The `this` binding of `callback`.
2542
- * @returns {*} Returns the accumulated value.
2543
- * @example
2544
- *
2545
- * var list = [[0, 1], [2, 3], [4, 5]];
2546
- * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
2547
- * // => [4, 5, 2, 3, 0, 1]
2548
- */
2549
- function reduceRight(collection, callback, accumulator, thisArg) {
2550
- var noaccum = arguments.length < 3;
2551
- callback = createCallback(callback, thisArg, 4);
2552
- forEachRight(collection, function(value, index, collection) {
2553
- accumulator = noaccum
2554
- ? (noaccum = false, value)
2555
- : callback(accumulator, value, index, collection);
2556
- });
2557
- return accumulator;
2558
- }
2559
-
2560
- /**
2561
- * The opposite of `_.filter` this method returns the elements of a
2562
- * collection that the callback does **not** return truey for.
2563
- *
2564
- * If a property name is provided for `callback` the created "_.pluck" style
2565
- * callback will return the property value of the given element.
2566
- *
2567
- * If an object is provided for `callback` the created "_.where" style callback
2568
- * will return `true` for elements that have the properties of the given object,
2569
- * else `false`.
2570
- *
2571
- * @static
2572
- * @memberOf _
2573
- * @category Collections
2574
- * @param {Array|Object|string} collection The collection to iterate over.
2575
- * @param {Function|Object|string} [callback=identity] The function called
2576
- * per iteration. If a property name or object is provided it will be used
2577
- * to create a "_.pluck" or "_.where" style callback, respectively.
2578
- * @param {*} [thisArg] The `this` binding of `callback`.
2579
- * @returns {Array} Returns a new array of elements that failed the callback check.
2580
- * @example
2581
- *
2582
- * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2583
- * // => [1, 3, 5]
2584
- *
2585
- * var characters = [
2586
- * { 'name': 'barney', 'age': 36, 'blocked': false },
2587
- * { 'name': 'fred', 'age': 40, 'blocked': true }
2588
- * ];
2589
- *
2590
- * // using "_.pluck" callback shorthand
2591
- * _.reject(characters, 'blocked');
2592
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
2593
- *
2594
- * // using "_.where" callback shorthand
2595
- * _.reject(characters, { 'age': 36 });
2596
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
2597
- */
2598
- function reject(collection, callback, thisArg) {
2599
- callback = createCallback(callback, thisArg, 3);
2600
- return filter(collection, function(value, index, collection) {
2601
- return !callback(value, index, collection);
2602
- });
2603
- }
2604
-
2605
- /**
2606
- * Retrieves a random element or `n` random elements from a collection.
2607
- *
2608
- * @static
2609
- * @memberOf _
2610
- * @category Collections
2611
- * @param {Array|Object|string} collection The collection to sample.
2612
- * @param {number} [n] The number of elements to sample.
2613
- * @param- {Object} [guard] Allows working with functions like `_.map`
2614
- * without using their `index` arguments as `n`.
2615
- * @returns {Array} Returns the random sample(s) of `collection`.
2616
- * @example
2617
- *
2618
- * _.sample([1, 2, 3, 4]);
2619
- * // => 2
2620
- *
2621
- * _.sample([1, 2, 3, 4], 2);
2622
- * // => [3, 1]
2623
- */
2624
- function sample(collection, n, guard) {
2625
- if (collection && typeof collection.length != 'number') {
2626
- collection = values(collection);
2627
- }
2628
- if (n == null || guard) {
2629
- return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
2630
- }
2631
- var result = shuffle(collection);
2632
- result.length = nativeMin(nativeMax(0, n), result.length);
2633
- return result;
2634
- }
2635
-
2636
- /**
2637
- * Creates an array of shuffled values, using a version of the Fisher-Yates
2638
- * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
2639
- *
2640
- * @static
2641
- * @memberOf _
2642
- * @category Collections
2643
- * @param {Array|Object|string} collection The collection to shuffle.
2644
- * @returns {Array} Returns a new shuffled collection.
2645
- * @example
2646
- *
2647
- * _.shuffle([1, 2, 3, 4, 5, 6]);
2648
- * // => [4, 1, 6, 3, 5, 2]
2649
- */
2650
- function shuffle(collection) {
2651
- var index = -1,
2652
- length = collection ? collection.length : 0,
2653
- result = Array(typeof length == 'number' ? length : 0);
2654
-
2655
- forEach(collection, function(value) {
2656
- var rand = baseRandom(0, ++index);
2657
- result[index] = result[rand];
2658
- result[rand] = value;
2659
- });
2660
- return result;
2661
- }
2662
-
2663
- /**
2664
- * Gets the size of the `collection` by returning `collection.length` for arrays
2665
- * and array-like objects or the number of own enumerable properties for objects.
2666
- *
2667
- * @static
2668
- * @memberOf _
2669
- * @category Collections
2670
- * @param {Array|Object|string} collection The collection to inspect.
2671
- * @returns {number} Returns `collection.length` or number of own enumerable properties.
2672
- * @example
2673
- *
2674
- * _.size([1, 2]);
2675
- * // => 2
2676
- *
2677
- * _.size({ 'one': 1, 'two': 2, 'three': 3 });
2678
- * // => 3
2679
- *
2680
- * _.size('pebbles');
2681
- * // => 7
2682
- */
2683
- function size(collection) {
2684
- var length = collection ? collection.length : 0;
2685
- return typeof length == 'number' ? length : keys(collection).length;
2686
- }
2687
-
2688
- /**
2689
- * Checks if the callback returns a truey value for **any** element of a
2690
- * collection. The function returns as soon as it finds a passing value and
2691
- * does not iterate over the entire collection. The callback is bound to
2692
- * `thisArg` and invoked with three arguments; (value, index|key, collection).
2693
- *
2694
- * If a property name is provided for `callback` the created "_.pluck" style
2695
- * callback will return the property value of the given element.
2696
- *
2697
- * If an object is provided for `callback` the created "_.where" style callback
2698
- * will return `true` for elements that have the properties of the given object,
2699
- * else `false`.
2700
- *
2701
- * @static
2702
- * @memberOf _
2703
- * @alias any
2704
- * @category Collections
2705
- * @param {Array|Object|string} collection The collection to iterate over.
2706
- * @param {Function|Object|string} [callback=identity] The function called
2707
- * per iteration. If a property name or object is provided it will be used
2708
- * to create a "_.pluck" or "_.where" style callback, respectively.
2709
- * @param {*} [thisArg] The `this` binding of `callback`.
2710
- * @returns {boolean} Returns `true` if any element passed the callback check,
2711
- * else `false`.
2712
- * @example
2713
- *
2714
- * _.some([null, 0, 'yes', false], Boolean);
2715
- * // => true
2716
- *
2717
- * var characters = [
2718
- * { 'name': 'barney', 'age': 36, 'blocked': false },
2719
- * { 'name': 'fred', 'age': 40, 'blocked': true }
2720
- * ];
2721
- *
2722
- * // using "_.pluck" callback shorthand
2723
- * _.some(characters, 'blocked');
2724
- * // => true
2725
- *
2726
- * // using "_.where" callback shorthand
2727
- * _.some(characters, { 'age': 1 });
2728
- * // => false
2729
- */
2730
- function some(collection, callback, thisArg) {
2731
- var result;
2732
- callback = createCallback(callback, thisArg, 3);
2733
-
2734
- var index = -1,
2735
- length = collection ? collection.length : 0;
2736
-
2737
- if (typeof length == 'number') {
2738
- while (++index < length) {
2739
- if ((result = callback(collection[index], index, collection))) {
2740
- break;
2741
- }
2742
- }
2743
- } else {
2744
- forOwn(collection, function(value, index, collection) {
2745
- return (result = callback(value, index, collection)) && indicatorObject;
2746
- });
2747
- }
2748
- return !!result;
2749
- }
2750
-
2751
- /**
2752
- * Creates an array of elements, sorted in ascending order by the results of
2753
- * running each element in a collection through the callback. This method
2754
- * performs a stable sort, that is, it will preserve the original sort order
2755
- * of equal elements. The callback is bound to `thisArg` and invoked with
2756
- * three arguments; (value, index|key, collection).
2757
- *
2758
- * If a property name is provided for `callback` the created "_.pluck" style
2759
- * callback will return the property value of the given element.
2760
- *
2761
- * If an array of property names is provided for `callback` the collection
2762
- * will be sorted by each property value.
2763
- *
2764
- * If an object is provided for `callback` the created "_.where" style callback
2765
- * will return `true` for elements that have the properties of the given object,
2766
- * else `false`.
2767
- *
2768
- * @static
2769
- * @memberOf _
2770
- * @category Collections
2771
- * @param {Array|Object|string} collection The collection to iterate over.
2772
- * @param {Array|Function|Object|string} [callback=identity] The function called
2773
- * per iteration. If a property name or object is provided it will be used
2774
- * to create a "_.pluck" or "_.where" style callback, respectively.
2775
- * @param {*} [thisArg] The `this` binding of `callback`.
2776
- * @returns {Array} Returns a new array of sorted elements.
2777
- * @example
2778
- *
2779
- * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
2780
- * // => [3, 1, 2]
2781
- *
2782
- * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
2783
- * // => [3, 1, 2]
2784
- *
2785
- * var characters = [
2786
- * { 'name': 'barney', 'age': 36 },
2787
- * { 'name': 'fred', 'age': 40 },
2788
- * { 'name': 'barney', 'age': 26 },
2789
- * { 'name': 'fred', 'age': 30 }
2790
- * ];
2791
- *
2792
- * // using "_.pluck" callback shorthand
2793
- * _.map(_.sortBy(characters, 'age'), _.values);
2794
- * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
2795
- *
2796
- * // sorting by multiple properties
2797
- * _.map(_.sortBy(characters, ['name', 'age']), _.values);
2798
- * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
2799
- */
2800
- function sortBy(collection, callback, thisArg) {
2801
- var index = -1,
2802
- length = collection ? collection.length : 0,
2803
- result = Array(typeof length == 'number' ? length : 0);
2804
-
2805
- callback = createCallback(callback, thisArg, 3);
2806
- forEach(collection, function(value, key, collection) {
2807
- result[++index] = {
2808
- 'criteria': [callback(value, key, collection)],
2809
- 'index': index,
2810
- 'value': value
2811
- };
2812
- });
2813
-
2814
- length = result.length;
2815
- result.sort(compareAscending);
2816
- while (length--) {
2817
- result[length] = result[length].value;
2818
- }
2819
- return result;
2820
- }
2821
-
2822
- /**
2823
- * Converts the `collection` to an array.
2824
- *
2825
- * @static
2826
- * @memberOf _
2827
- * @category Collections
2828
- * @param {Array|Object|string} collection The collection to convert.
2829
- * @returns {Array} Returns the new converted array.
2830
- * @example
2831
- *
2832
- * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
2833
- * // => [2, 3, 4]
2834
- */
2835
- function toArray(collection) {
2836
- if (isArray(collection)) {
2837
- return slice(collection);
2838
- }
2839
- if (collection && typeof collection.length == 'number') {
2840
- return map(collection);
2841
- }
2842
- return values(collection);
2843
- }
2844
-
2845
- /**
2846
- * Performs a deep comparison of each element in a `collection` to the given
2847
- * `properties` object, returning an array of all elements that have equivalent
2848
- * property values.
2849
- *
2850
- * @static
2851
- * @memberOf _
2852
- * @type Function
2853
- * @category Collections
2854
- * @param {Array|Object|string} collection The collection to iterate over.
2855
- * @param {Object} props The object of property values to filter by.
2856
- * @returns {Array} Returns a new array of elements that have the given properties.
2857
- * @example
2858
- *
2859
- * var characters = [
2860
- * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
2861
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
2862
- * ];
2863
- *
2864
- * _.where(characters, { 'age': 36 });
2865
- * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
2866
- *
2867
- * _.where(characters, { 'pets': ['dino'] });
2868
- * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
2869
- */
2870
- function where(collection, properties, first) {
2871
- return (first && isEmpty(properties))
2872
- ? undefined
2873
- : (first ? find : filter)(collection, properties);
2874
- }
2875
-
2876
- /*--------------------------------------------------------------------------*/
2877
-
2878
- /**
2879
- * Creates an array with all falsey values removed. The values `false`, `null`,
2880
- * `0`, `""`, `undefined`, and `NaN` are all falsey.
2881
- *
2882
- * @static
2883
- * @memberOf _
2884
- * @category Arrays
2885
- * @param {Array} array The array to compact.
2886
- * @returns {Array} Returns a new array of filtered values.
2887
- * @example
2888
- *
2889
- * _.compact([0, 1, false, 2, '', 3]);
2890
- * // => [1, 2, 3]
2891
- */
2892
- function compact(array) {
2893
- var index = -1,
2894
- length = array ? array.length : 0,
2895
- result = [];
2896
-
2897
- while (++index < length) {
2898
- var value = array[index];
2899
- if (value) {
2900
- result.push(value);
2901
- }
2902
- }
2903
- return result;
2904
- }
2905
-
2906
- /**
2907
- * Creates an array excluding all values of the provided arrays using strict
2908
- * equality for comparisons, i.e. `===`.
2909
- *
2910
- * @static
2911
- * @memberOf _
2912
- * @category Arrays
2913
- * @param {Array} array The array to process.
2914
- * @param {...Array} [values] The arrays of values to exclude.
2915
- * @returns {Array} Returns a new array of filtered values.
2916
- * @example
2917
- *
2918
- * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
2919
- * // => [1, 3, 4]
2920
- */
2921
- function difference(array) {
2922
- return baseDifference(array, baseFlatten(arguments, true, true, 1));
2923
- }
2924
-
2925
- /**
2926
- * Gets the first element or first `n` elements of an array. If a callback
2927
- * is provided elements at the beginning of the array are returned as long
2928
- * as the callback returns truey. The callback is bound to `thisArg` and
2929
- * invoked with three arguments; (value, index, array).
2930
- *
2931
- * If a property name is provided for `callback` the created "_.pluck" style
2932
- * callback will return the property value of the given element.
2933
- *
2934
- * If an object is provided for `callback` the created "_.where" style callback
2935
- * will return `true` for elements that have the properties of the given object,
2936
- * else `false`.
2937
- *
2938
- * @static
2939
- * @memberOf _
2940
- * @alias head, take
2941
- * @category Arrays
2942
- * @param {Array} array The array to query.
2943
- * @param {Function|Object|number|string} [callback] The function called
2944
- * per element or the number of elements to return. If a property name or
2945
- * object is provided it will be used to create a "_.pluck" or "_.where"
2946
- * style callback, respectively.
2947
- * @param {*} [thisArg] The `this` binding of `callback`.
2948
- * @returns {*} Returns the first element(s) of `array`.
2949
- * @example
2950
- *
2951
- * _.first([1, 2, 3]);
2952
- * // => 1
2953
- *
2954
- * _.first([1, 2, 3], 2);
2955
- * // => [1, 2]
2956
- *
2957
- * _.first([1, 2, 3], function(num) {
2958
- * return num < 3;
2959
- * });
2960
- * // => [1, 2]
2961
- *
2962
- * var characters = [
2963
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
2964
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
2965
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
2966
- * ];
2967
- *
2968
- * // using "_.pluck" callback shorthand
2969
- * _.first(characters, 'blocked');
2970
- * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
2971
- *
2972
- * // using "_.where" callback shorthand
2973
- * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
2974
- * // => ['barney', 'fred']
2975
- */
2976
- function first(array, callback, thisArg) {
2977
- var n = 0,
2978
- length = array ? array.length : 0;
2979
-
2980
- if (typeof callback != 'number' && callback != null) {
2981
- var index = -1;
2982
- callback = createCallback(callback, thisArg, 3);
2983
- while (++index < length && callback(array[index], index, array)) {
2984
- n++;
2985
- }
2986
- } else {
2987
- n = callback;
2988
- if (n == null || thisArg) {
2989
- return array ? array[0] : undefined;
2990
- }
2991
- }
2992
- return slice(array, 0, nativeMin(nativeMax(0, n), length));
2993
- }
2994
-
2995
- /**
2996
- * Flattens a nested array (the nesting can be to any depth). If `isShallow`
2997
- * is truey, the array will only be flattened a single level. If a callback
2998
- * is provided each element of the array is passed through the callback before
2999
- * flattening. The callback is bound to `thisArg` and invoked with three
3000
- * arguments; (value, index, array).
3001
- *
3002
- * If a property name is provided for `callback` the created "_.pluck" style
3003
- * callback will return the property value of the given element.
3004
- *
3005
- * If an object is provided for `callback` the created "_.where" style callback
3006
- * will return `true` for elements that have the properties of the given object,
3007
- * else `false`.
3008
- *
3009
- * @static
3010
- * @memberOf _
3011
- * @category Arrays
3012
- * @param {Array} array The array to flatten.
3013
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
3014
- * @param {Function|Object|string} [callback=identity] The function called
3015
- * per iteration. If a property name or object is provided it will be used
3016
- * to create a "_.pluck" or "_.where" style callback, respectively.
3017
- * @param {*} [thisArg] The `this` binding of `callback`.
3018
- * @returns {Array} Returns a new flattened array.
3019
- * @example
3020
- *
3021
- * _.flatten([1, [2], [3, [[4]]]]);
3022
- * // => [1, 2, 3, 4];
3023
- *
3024
- * _.flatten([1, [2], [3, [[4]]]], true);
3025
- * // => [1, 2, 3, [[4]]];
3026
- *
3027
- * var characters = [
3028
- * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
3029
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
3030
- * ];
3031
- *
3032
- * // using "_.pluck" callback shorthand
3033
- * _.flatten(characters, 'pets');
3034
- * // => ['hoppy', 'baby puss', 'dino']
3035
- */
3036
- function flatten(array, isShallow) {
3037
- return baseFlatten(array, isShallow);
3038
- }
3039
-
3040
- /**
3041
- * Gets the index at which the first occurrence of `value` is found using
3042
- * strict equality for comparisons, i.e. `===`. If the array is already sorted
3043
- * providing `true` for `fromIndex` will run a faster binary search.
3044
- *
3045
- * @static
3046
- * @memberOf _
3047
- * @category Arrays
3048
- * @param {Array} array The array to search.
3049
- * @param {*} value The value to search for.
3050
- * @param {boolean|number} [fromIndex=0] The index to search from or `true`
3051
- * to perform a binary search on a sorted array.
3052
- * @returns {number} Returns the index of the matched value or `-1`.
3053
- * @example
3054
- *
3055
- * _.indexOf([1, 2, 3, 1, 2, 3], 2);
3056
- * // => 1
3057
- *
3058
- * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
3059
- * // => 4
3060
- *
3061
- * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
3062
- * // => 2
3063
- */
3064
- function indexOf(array, value, fromIndex) {
3065
- if (typeof fromIndex == 'number') {
3066
- var length = array ? array.length : 0;
3067
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
3068
- } else if (fromIndex) {
3069
- var index = sortedIndex(array, value);
3070
- return array[index] === value ? index : -1;
3071
- }
3072
- return baseIndexOf(array, value, fromIndex);
3073
- }
3074
-
3075
- /**
3076
- * Gets all but the last element or last `n` elements of an array. If a
3077
- * callback is provided elements at the end of the array are excluded from
3078
- * the result as long as the callback returns truey. The callback is bound
3079
- * to `thisArg` and invoked with three arguments; (value, index, array).
3080
- *
3081
- * If a property name is provided for `callback` the created "_.pluck" style
3082
- * callback will return the property value of the given element.
3083
- *
3084
- * If an object is provided for `callback` the created "_.where" style callback
3085
- * will return `true` for elements that have the properties of the given object,
3086
- * else `false`.
3087
- *
3088
- * @static
3089
- * @memberOf _
3090
- * @category Arrays
3091
- * @param {Array} array The array to query.
3092
- * @param {Function|Object|number|string} [callback=1] The function called
3093
- * per element or the number of elements to exclude. If a property name or
3094
- * object is provided it will be used to create a "_.pluck" or "_.where"
3095
- * style callback, respectively.
3096
- * @param {*} [thisArg] The `this` binding of `callback`.
3097
- * @returns {Array} Returns a slice of `array`.
3098
- * @example
3099
- *
3100
- * _.initial([1, 2, 3]);
3101
- * // => [1, 2]
3102
- *
3103
- * _.initial([1, 2, 3], 2);
3104
- * // => [1]
3105
- *
3106
- * _.initial([1, 2, 3], function(num) {
3107
- * return num > 1;
3108
- * });
3109
- * // => [1]
3110
- *
3111
- * var characters = [
3112
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
3113
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
3114
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
3115
- * ];
3116
- *
3117
- * // using "_.pluck" callback shorthand
3118
- * _.initial(characters, 'blocked');
3119
- * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
3120
- *
3121
- * // using "_.where" callback shorthand
3122
- * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
3123
- * // => ['barney', 'fred']
3124
- */
3125
- function initial(array, callback, thisArg) {
3126
- var n = 0,
3127
- length = array ? array.length : 0;
3128
-
3129
- if (typeof callback != 'number' && callback != null) {
3130
- var index = length;
3131
- callback = createCallback(callback, thisArg, 3);
3132
- while (index-- && callback(array[index], index, array)) {
3133
- n++;
3134
- }
3135
- } else {
3136
- n = (callback == null || thisArg) ? 1 : callback || n;
3137
- }
3138
- return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
3139
- }
3140
-
3141
- /**
3142
- * Creates an array of unique values present in all provided arrays using
3143
- * strict equality for comparisons, i.e. `===`.
3144
- *
3145
- * @static
3146
- * @memberOf _
3147
- * @category Arrays
3148
- * @param {...Array} [array] The arrays to inspect.
3149
- * @returns {Array} Returns an array of shared values.
3150
- * @example
3151
- *
3152
- * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
3153
- * // => [1, 2]
3154
- */
3155
- function intersection() {
3156
- var args = [],
3157
- argsIndex = -1,
3158
- argsLength = arguments.length;
3159
-
3160
- while (++argsIndex < argsLength) {
3161
- var value = arguments[argsIndex];
3162
- if (isArray(value) || isArguments(value)) {
3163
- args.push(value);
3164
- }
3165
- }
3166
- var array = args[0],
3167
- index = -1,
3168
- indexOf = getIndexOf(),
3169
- length = array ? array.length : 0,
3170
- result = [];
3171
-
3172
- outer:
3173
- while (++index < length) {
3174
- value = array[index];
3175
- if (indexOf(result, value) < 0) {
3176
- var argsIndex = argsLength;
3177
- while (--argsIndex) {
3178
- if (indexOf(args[argsIndex], value) < 0) {
3179
- continue outer;
3180
- }
3181
- }
3182
- result.push(value);
3183
- }
3184
- }
3185
- return result;
3186
- }
3187
-
3188
- /**
3189
- * Gets the last element or last `n` elements of an array. If a callback is
3190
- * provided elements at the end of the array are returned as long as the
3191
- * callback returns truey. The callback is bound to `thisArg` and invoked
3192
- * with three arguments; (value, index, array).
3193
- *
3194
- * If a property name is provided for `callback` the created "_.pluck" style
3195
- * callback will return the property value of the given element.
3196
- *
3197
- * If an object is provided for `callback` the created "_.where" style callback
3198
- * will return `true` for elements that have the properties of the given object,
3199
- * else `false`.
3200
- *
3201
- * @static
3202
- * @memberOf _
3203
- * @category Arrays
3204
- * @param {Array} array The array to query.
3205
- * @param {Function|Object|number|string} [callback] The function called
3206
- * per element or the number of elements to return. If a property name or
3207
- * object is provided it will be used to create a "_.pluck" or "_.where"
3208
- * style callback, respectively.
3209
- * @param {*} [thisArg] The `this` binding of `callback`.
3210
- * @returns {*} Returns the last element(s) of `array`.
3211
- * @example
3212
- *
3213
- * _.last([1, 2, 3]);
3214
- * // => 3
3215
- *
3216
- * _.last([1, 2, 3], 2);
3217
- * // => [2, 3]
3218
- *
3219
- * _.last([1, 2, 3], function(num) {
3220
- * return num > 1;
3221
- * });
3222
- * // => [2, 3]
3223
- *
3224
- * var characters = [
3225
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
3226
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
3227
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
3228
- * ];
3229
- *
3230
- * // using "_.pluck" callback shorthand
3231
- * _.pluck(_.last(characters, 'blocked'), 'name');
3232
- * // => ['fred', 'pebbles']
3233
- *
3234
- * // using "_.where" callback shorthand
3235
- * _.last(characters, { 'employer': 'na' });
3236
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
3237
- */
3238
- function last(array, callback, thisArg) {
3239
- var n = 0,
3240
- length = array ? array.length : 0;
3241
-
3242
- if (typeof callback != 'number' && callback != null) {
3243
- var index = length;
3244
- callback = createCallback(callback, thisArg, 3);
3245
- while (index-- && callback(array[index], index, array)) {
3246
- n++;
3247
- }
3248
- } else {
3249
- n = callback;
3250
- if (n == null || thisArg) {
3251
- return array ? array[length - 1] : undefined;
3252
- }
3253
- }
3254
- return slice(array, nativeMax(0, length - n));
3255
- }
3256
-
3257
- /**
3258
- * Gets the index at which the last occurrence of `value` is found using strict
3259
- * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
3260
- * as the offset from the end of the collection.
3261
- *
3262
- * If a property name is provided for `callback` the created "_.pluck" style
3263
- * callback will return the property value of the given element.
3264
- *
3265
- * If an object is provided for `callback` the created "_.where" style callback
3266
- * will return `true` for elements that have the properties of the given object,
3267
- * else `false`.
3268
- *
3269
- * @static
3270
- * @memberOf _
3271
- * @category Arrays
3272
- * @param {Array} array The array to search.
3273
- * @param {*} value The value to search for.
3274
- * @param {number} [fromIndex=array.length-1] The index to search from.
3275
- * @returns {number} Returns the index of the matched value or `-1`.
3276
- * @example
3277
- *
3278
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
3279
- * // => 4
3280
- *
3281
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
3282
- * // => 1
3283
- */
3284
- function lastIndexOf(array, value, fromIndex) {
3285
- var index = array ? array.length : 0;
3286
- if (typeof fromIndex == 'number') {
3287
- index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
3288
- }
3289
- while (index--) {
3290
- if (array[index] === value) {
3291
- return index;
3292
- }
3293
- }
3294
- return -1;
3295
- }
3296
-
3297
- /**
3298
- * Creates an array of numbers (positive and/or negative) progressing from
3299
- * `start` up to but not including `end`. If `start` is less than `stop` a
3300
- * zero-length range is created unless a negative `step` is specified.
3301
- *
3302
- * @static
3303
- * @memberOf _
3304
- * @category Arrays
3305
- * @param {number} [start=0] The start of the range.
3306
- * @param {number} end The end of the range.
3307
- * @param {number} [step=1] The value to increment or decrement by.
3308
- * @returns {Array} Returns a new range array.
3309
- * @example
3310
- *
3311
- * _.range(4);
3312
- * // => [0, 1, 2, 3]
3313
- *
3314
- * _.range(1, 5);
3315
- * // => [1, 2, 3, 4]
3316
- *
3317
- * _.range(0, 20, 5);
3318
- * // => [0, 5, 10, 15]
3319
- *
3320
- * _.range(0, -4, -1);
3321
- * // => [0, -1, -2, -3]
3322
- *
3323
- * _.range(1, 4, 0);
3324
- * // => [1, 1, 1]
3325
- *
3326
- * _.range(0);
3327
- * // => []
3328
- */
3329
- function range(start, end, step) {
3330
- start = +start || 0;
3331
- step = (+step || 1);
3332
-
3333
- if (end == null) {
3334
- end = start;
3335
- start = 0;
3336
- }
3337
- // use `Array(length)` so engines like Chakra and V8 avoid slower modes
3338
- // http://youtu.be/XAqIpGU8ZZk#t=17m25s
3339
- var index = -1,
3340
- length = nativeMax(0, ceil((end - start) / step)),
3341
- result = Array(length);
3342
-
3343
- while (++index < length) {
3344
- result[index] = start;
3345
- start += step;
3346
- }
3347
- return result;
3348
- }
3349
-
3350
- /**
3351
- * The opposite of `_.initial` this method gets all but the first element or
3352
- * first `n` elements of an array. If a callback function is provided elements
3353
- * at the beginning of the array are excluded from the result as long as the
3354
- * callback returns truey. The callback is bound to `thisArg` and invoked
3355
- * with three arguments; (value, index, array).
3356
- *
3357
- * If a property name is provided for `callback` the created "_.pluck" style
3358
- * callback will return the property value of the given element.
3359
- *
3360
- * If an object is provided for `callback` the created "_.where" style callback
3361
- * will return `true` for elements that have the properties of the given object,
3362
- * else `false`.
3363
- *
3364
- * @static
3365
- * @memberOf _
3366
- * @alias drop, tail
3367
- * @category Arrays
3368
- * @param {Array} array The array to query.
3369
- * @param {Function|Object|number|string} [callback=1] The function called
3370
- * per element or the number of elements to exclude. If a property name or
3371
- * object is provided it will be used to create a "_.pluck" or "_.where"
3372
- * style callback, respectively.
3373
- * @param {*} [thisArg] The `this` binding of `callback`.
3374
- * @returns {Array} Returns a slice of `array`.
3375
- * @example
3376
- *
3377
- * _.rest([1, 2, 3]);
3378
- * // => [2, 3]
3379
- *
3380
- * _.rest([1, 2, 3], 2);
3381
- * // => [3]
3382
- *
3383
- * _.rest([1, 2, 3], function(num) {
3384
- * return num < 3;
3385
- * });
3386
- * // => [3]
3387
- *
3388
- * var characters = [
3389
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
3390
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
3391
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
3392
- * ];
3393
- *
3394
- * // using "_.pluck" callback shorthand
3395
- * _.pluck(_.rest(characters, 'blocked'), 'name');
3396
- * // => ['fred', 'pebbles']
3397
- *
3398
- * // using "_.where" callback shorthand
3399
- * _.rest(characters, { 'employer': 'slate' });
3400
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
3401
- */
3402
- function rest(array, callback, thisArg) {
3403
- if (typeof callback != 'number' && callback != null) {
3404
- var n = 0,
3405
- index = -1,
3406
- length = array ? array.length : 0;
3407
-
3408
- callback = createCallback(callback, thisArg, 3);
3409
- while (++index < length && callback(array[index], index, array)) {
3410
- n++;
3411
- }
3412
- } else {
3413
- n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
3414
- }
3415
- return slice(array, n);
3416
- }
3417
-
3418
- /**
3419
- * Uses a binary search to determine the smallest index at which a value
3420
- * should be inserted into a given sorted array in order to maintain the sort
3421
- * order of the array. If a callback is provided it will be executed for
3422
- * `value` and each element of `array` to compute their sort ranking. The
3423
- * callback is bound to `thisArg` and invoked with one argument; (value).
3424
- *
3425
- * If a property name is provided for `callback` the created "_.pluck" style
3426
- * callback will return the property value of the given element.
3427
- *
3428
- * If an object is provided for `callback` the created "_.where" style callback
3429
- * will return `true` for elements that have the properties of the given object,
3430
- * else `false`.
3431
- *
3432
- * @static
3433
- * @memberOf _
3434
- * @category Arrays
3435
- * @param {Array} array The array to inspect.
3436
- * @param {*} value The value to evaluate.
3437
- * @param {Function|Object|string} [callback=identity] The function called
3438
- * per iteration. If a property name or object is provided it will be used
3439
- * to create a "_.pluck" or "_.where" style callback, respectively.
3440
- * @param {*} [thisArg] The `this` binding of `callback`.
3441
- * @returns {number} Returns the index at which `value` should be inserted
3442
- * into `array`.
3443
- * @example
3444
- *
3445
- * _.sortedIndex([20, 30, 50], 40);
3446
- * // => 2
3447
- *
3448
- * // using "_.pluck" callback shorthand
3449
- * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
3450
- * // => 2
3451
- *
3452
- * var dict = {
3453
- * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
3454
- * };
3455
- *
3456
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3457
- * return dict.wordToNumber[word];
3458
- * });
3459
- * // => 2
3460
- *
3461
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3462
- * return this.wordToNumber[word];
3463
- * }, dict);
3464
- * // => 2
3465
- */
3466
- function sortedIndex(array, value, callback, thisArg) {
3467
- var low = 0,
3468
- high = array ? array.length : low;
3469
-
3470
- // explicitly reference `identity` for better inlining in Firefox
3471
- callback = callback ? createCallback(callback, thisArg, 1) : identity;
3472
- value = callback(value);
3473
-
3474
- while (low < high) {
3475
- var mid = (low + high) >>> 1;
3476
- (callback(array[mid]) < value)
3477
- ? low = mid + 1
3478
- : high = mid;
3479
- }
3480
- return low;
3481
- }
3482
-
3483
- /**
3484
- * Creates an array of unique values, in order, of the provided arrays using
3485
- * strict equality for comparisons, i.e. `===`.
3486
- *
3487
- * @static
3488
- * @memberOf _
3489
- * @category Arrays
3490
- * @param {...Array} [array] The arrays to inspect.
3491
- * @returns {Array} Returns an array of combined values.
3492
- * @example
3493
- *
3494
- * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
3495
- * // => [1, 2, 3, 5, 4]
3496
- */
3497
- function union() {
3498
- return baseUniq(baseFlatten(arguments, true, true));
3499
- }
3500
-
3501
- /**
3502
- * Creates a duplicate-value-free version of an array using strict equality
3503
- * for comparisons, i.e. `===`. If the array is sorted, providing
3504
- * `true` for `isSorted` will use a faster algorithm. If a callback is provided
3505
- * each element of `array` is passed through the callback before uniqueness
3506
- * is computed. The callback is bound to `thisArg` and invoked with three
3507
- * arguments; (value, index, array).
3508
- *
3509
- * If a property name is provided for `callback` the created "_.pluck" style
3510
- * callback will return the property value of the given element.
3511
- *
3512
- * If an object is provided for `callback` the created "_.where" style callback
3513
- * will return `true` for elements that have the properties of the given object,
3514
- * else `false`.
3515
- *
3516
- * @static
3517
- * @memberOf _
3518
- * @alias unique
3519
- * @category Arrays
3520
- * @param {Array} array The array to process.
3521
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
3522
- * @param {Function|Object|string} [callback=identity] The function called
3523
- * per iteration. If a property name or object is provided it will be used
3524
- * to create a "_.pluck" or "_.where" style callback, respectively.
3525
- * @param {*} [thisArg] The `this` binding of `callback`.
3526
- * @returns {Array} Returns a duplicate-value-free array.
3527
- * @example
3528
- *
3529
- * _.uniq([1, 2, 1, 3, 1]);
3530
- * // => [1, 2, 3]
3531
- *
3532
- * _.uniq([1, 1, 2, 2, 3], true);
3533
- * // => [1, 2, 3]
3534
- *
3535
- * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
3536
- * // => ['A', 'b', 'C']
3537
- *
3538
- * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
3539
- * // => [1, 2.5, 3]
3540
- *
3541
- * // using "_.pluck" callback shorthand
3542
- * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
3543
- * // => [{ 'x': 1 }, { 'x': 2 }]
3544
- */
3545
- function uniq(array, isSorted, callback, thisArg) {
3546
- // juggle arguments
3547
- if (typeof isSorted != 'boolean' && isSorted != null) {
3548
- thisArg = callback;
3549
- callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
3550
- isSorted = false;
3551
- }
3552
- if (callback != null) {
3553
- callback = createCallback(callback, thisArg, 3);
3554
- }
3555
- return baseUniq(array, isSorted, callback);
3556
- }
3557
-
3558
- /**
3559
- * Creates an array excluding all provided values using strict equality for
3560
- * comparisons, i.e. `===`.
3561
- *
3562
- * @static
3563
- * @memberOf _
3564
- * @category Arrays
3565
- * @param {Array} array The array to filter.
3566
- * @param {...*} [value] The values to exclude.
3567
- * @returns {Array} Returns a new array of filtered values.
3568
- * @example
3569
- *
3570
- * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
3571
- * // => [2, 3, 4]
3572
- */
3573
- function without(array) {
3574
- return baseDifference(array, slice(arguments, 1));
3575
- }
3576
-
3577
- /**
3578
- * Creates an array of grouped elements, the first of which contains the first
3579
- * elements of the given arrays, the second of which contains the second
3580
- * elements of the given arrays, and so on.
3581
- *
3582
- * @static
3583
- * @memberOf _
3584
- * @alias unzip
3585
- * @category Arrays
3586
- * @param {...Array} [array] Arrays to process.
3587
- * @returns {Array} Returns a new array of grouped elements.
3588
- * @example
3589
- *
3590
- * _.zip(['fred', 'barney'], [30, 40], [true, false]);
3591
- * // => [['fred', 30, true], ['barney', 40, false]]
3592
- */
3593
- function zip() {
3594
- var index = -1,
3595
- length = max(pluck(arguments, 'length')),
3596
- result = Array(length < 0 ? 0 : length);
3597
-
3598
- while (++index < length) {
3599
- result[index] = pluck(arguments, index);
3600
- }
3601
- return result;
3602
- }
3603
-
3604
- /**
3605
- * Creates an object composed from arrays of `keys` and `values`. Provide
3606
- * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
3607
- * or two arrays, one of `keys` and one of corresponding `values`.
3608
- *
3609
- * @static
3610
- * @memberOf _
3611
- * @alias object
3612
- * @category Arrays
3613
- * @param {Array} keys The array of keys.
3614
- * @param {Array} [values=[]] The array of values.
3615
- * @returns {Object} Returns an object composed of the given keys and
3616
- * corresponding values.
3617
- * @example
3618
- *
3619
- * _.zipObject(['fred', 'barney'], [30, 40]);
3620
- * // => { 'fred': 30, 'barney': 40 }
3621
- */
3622
- function zipObject(keys, values) {
3623
- var index = -1,
3624
- length = keys ? keys.length : 0,
3625
- result = {};
3626
-
3627
- if (!values && length && !isArray(keys[0])) {
3628
- values = [];
3629
- }
3630
- while (++index < length) {
3631
- var key = keys[index];
3632
- if (values) {
3633
- result[key] = values[index];
3634
- } else if (key) {
3635
- result[key[0]] = key[1];
3636
- }
3637
- }
3638
- return result;
3639
- }
3640
-
3641
- /*--------------------------------------------------------------------------*/
3642
-
3643
- /**
3644
- * Creates a function that executes `func`, with the `this` binding and
3645
- * arguments of the created function, only after being called `n` times.
3646
- *
3647
- * @static
3648
- * @memberOf _
3649
- * @category Functions
3650
- * @param {number} n The number of times the function must be called before
3651
- * `func` is executed.
3652
- * @param {Function} func The function to restrict.
3653
- * @returns {Function} Returns the new restricted function.
3654
- * @example
3655
- *
3656
- * var saves = ['profile', 'settings'];
3657
- *
3658
- * var done = _.after(saves.length, function() {
3659
- * console.log('Done saving!');
3660
- * });
3661
- *
3662
- * _.forEach(saves, function(type) {
3663
- * asyncSave({ 'type': type, 'complete': done });
3664
- * });
3665
- * // => logs 'Done saving!', after all saves have completed
3666
- */
3667
- function after(n, func) {
3668
- if (!isFunction(func)) {
3669
- throw new TypeError;
3670
- }
3671
- return function() {
3672
- if (--n < 1) {
3673
- return func.apply(this, arguments);
3674
- }
3675
- };
3676
- }
3677
-
3678
- /**
3679
- * Creates a function that, when called, invokes `func` with the `this`
3680
- * binding of `thisArg` and prepends any additional `bind` arguments to those
3681
- * provided to the bound function.
3682
- *
3683
- * @static
3684
- * @memberOf _
3685
- * @category Functions
3686
- * @param {Function} func The function to bind.
3687
- * @param {*} [thisArg] The `this` binding of `func`.
3688
- * @param {...*} [arg] Arguments to be partially applied.
3689
- * @returns {Function} Returns the new bound function.
3690
- * @example
3691
- *
3692
- * var func = function(greeting) {
3693
- * return greeting + ' ' + this.name;
3694
- * };
3695
- *
3696
- * func = _.bind(func, { 'name': 'fred' }, 'hi');
3697
- * func();
3698
- * // => 'hi fred'
3699
- */
3700
- function bind(func, thisArg) {
3701
- return arguments.length > 2
3702
- ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
3703
- : createWrapper(func, 1, null, null, thisArg);
3704
- }
3705
-
3706
- /**
3707
- * Binds methods of an object to the object itself, overwriting the existing
3708
- * method. Method names may be specified as individual arguments or as arrays
3709
- * of method names. If no method names are provided all the function properties
3710
- * of `object` will be bound.
3711
- *
3712
- * @static
3713
- * @memberOf _
3714
- * @category Functions
3715
- * @param {Object} object The object to bind and assign the bound methods to.
3716
- * @param {...string} [methodName] The object method names to
3717
- * bind, specified as individual method names or arrays of method names.
3718
- * @returns {Object} Returns `object`.
3719
- * @example
3720
- *
3721
- * var view = {
3722
- * 'label': 'docs',
3723
- * 'onClick': function() { console.log('clicked ' + this.label); }
3724
- * };
3725
- *
3726
- * _.bindAll(view);
3727
- * jQuery('#docs').on('click', view.onClick);
3728
- * // => logs 'clicked docs', when the button is clicked
3729
- */
3730
- function bindAll(object) {
3731
- var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
3732
- index = -1,
3733
- length = funcs.length;
3734
-
3735
- while (++index < length) {
3736
- var key = funcs[index];
3737
- object[key] = createWrapper(object[key], 1, null, null, object);
3738
- }
3739
- return object;
3740
- }
3741
-
3742
- /**
3743
- * Creates a function that is the composition of the provided functions,
3744
- * where each function consumes the return value of the function that follows.
3745
- * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
3746
- * Each function is executed with the `this` binding of the composed function.
3747
- *
3748
- * @static
3749
- * @memberOf _
3750
- * @category Functions
3751
- * @param {...Function} [func] Functions to compose.
3752
- * @returns {Function} Returns the new composed function.
3753
- * @example
3754
- *
3755
- * var realNameMap = {
3756
- * 'pebbles': 'penelope'
3757
- * };
3758
- *
3759
- * var format = function(name) {
3760
- * name = realNameMap[name.toLowerCase()] || name;
3761
- * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
3762
- * };
3763
- *
3764
- * var greet = function(formatted) {
3765
- * return 'Hiya ' + formatted + '!';
3766
- * };
3767
- *
3768
- * var welcome = _.compose(greet, format);
3769
- * welcome('pebbles');
3770
- * // => 'Hiya Penelope!'
3771
- */
3772
- function compose() {
3773
- var funcs = arguments,
3774
- length = funcs.length;
3775
-
3776
- while (length--) {
3777
- if (!isFunction(funcs[length])) {
3778
- throw new TypeError;
3779
- }
3780
- }
3781
- return function() {
3782
- var args = arguments,
3783
- length = funcs.length;
3784
-
3785
- while (length--) {
3786
- args = [funcs[length].apply(this, args)];
3787
- }
3788
- return args[0];
3789
- };
3790
- }
3791
-
3792
- /**
3793
- * Creates a function that will delay the execution of `func` until after
3794
- * `wait` milliseconds have elapsed since the last time it was invoked.
3795
- * Provide an options object to indicate that `func` should be invoked on
3796
- * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
3797
- * to the debounced function will return the result of the last `func` call.
3798
- *
3799
- * Note: If `leading` and `trailing` options are `true` `func` will be called
3800
- * on the trailing edge of the timeout only if the the debounced function is
3801
- * invoked more than once during the `wait` timeout.
3802
- *
3803
- * @static
3804
- * @memberOf _
3805
- * @category Functions
3806
- * @param {Function} func The function to debounce.
3807
- * @param {number} wait The number of milliseconds to delay.
3808
- * @param {Object} [options] The options object.
3809
- * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
3810
- * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
3811
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
3812
- * @returns {Function} Returns the new debounced function.
3813
- * @example
3814
- *
3815
- * // avoid costly calculations while the window size is in flux
3816
- * var lazyLayout = _.debounce(calculateLayout, 150);
3817
- * jQuery(window).on('resize', lazyLayout);
3818
- *
3819
- * // execute `sendMail` when the click event is fired, debouncing subsequent calls
3820
- * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
3821
- * 'leading': true,
3822
- * 'trailing': false
3823
- * });
3824
- *
3825
- * // ensure `batchLog` is executed once after 1 second of debounced calls
3826
- * var source = new EventSource('/stream');
3827
- * source.addEventListener('message', _.debounce(batchLog, 250, {
3828
- * 'maxWait': 1000
3829
- * }, false);
3830
- */
3831
- function debounce(func, wait, options) {
3832
- var args,
3833
- maxTimeoutId,
3834
- result,
3835
- stamp,
3836
- thisArg,
3837
- timeoutId,
3838
- trailingCall,
3839
- lastCalled = 0,
3840
- maxWait = false,
3841
- trailing = true;
3842
-
3843
- if (!isFunction(func)) {
3844
- throw new TypeError;
3845
- }
3846
- wait = nativeMax(0, wait) || 0;
3847
- if (options === true) {
3848
- var leading = true;
3849
- trailing = false;
3850
- } else if (isObject(options)) {
3851
- leading = options.leading;
3852
- maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
3853
- trailing = 'trailing' in options ? options.trailing : trailing;
3854
- }
3855
- var delayed = function() {
3856
- var remaining = wait - (now() - stamp);
3857
- if (remaining <= 0) {
3858
- if (maxTimeoutId) {
3859
- clearTimeout(maxTimeoutId);
3860
- }
3861
- var isCalled = trailingCall;
3862
- maxTimeoutId = timeoutId = trailingCall = undefined;
3863
- if (isCalled) {
3864
- lastCalled = now();
3865
- result = func.apply(thisArg, args);
3866
- if (!timeoutId && !maxTimeoutId) {
3867
- args = thisArg = null;
3868
- }
3869
- }
3870
- } else {
3871
- timeoutId = setTimeout(delayed, remaining);
3872
- }
3873
- };
3874
-
3875
- var maxDelayed = function() {
3876
- if (timeoutId) {
3877
- clearTimeout(timeoutId);
3878
- }
3879
- maxTimeoutId = timeoutId = trailingCall = undefined;
3880
- if (trailing || (maxWait !== wait)) {
3881
- lastCalled = now();
3882
- result = func.apply(thisArg, args);
3883
- if (!timeoutId && !maxTimeoutId) {
3884
- args = thisArg = null;
3885
- }
3886
- }
3887
- };
3888
-
3889
- return function() {
3890
- args = arguments;
3891
- stamp = now();
3892
- thisArg = this;
3893
- trailingCall = trailing && (timeoutId || !leading);
3894
-
3895
- if (maxWait === false) {
3896
- var leadingCall = leading && !timeoutId;
3897
- } else {
3898
- if (!maxTimeoutId && !leading) {
3899
- lastCalled = stamp;
3900
- }
3901
- var remaining = maxWait - (stamp - lastCalled),
3902
- isCalled = remaining <= 0;
3903
-
3904
- if (isCalled) {
3905
- if (maxTimeoutId) {
3906
- maxTimeoutId = clearTimeout(maxTimeoutId);
3907
- }
3908
- lastCalled = stamp;
3909
- result = func.apply(thisArg, args);
3910
- }
3911
- else if (!maxTimeoutId) {
3912
- maxTimeoutId = setTimeout(maxDelayed, remaining);
3913
- }
3914
- }
3915
- if (isCalled && timeoutId) {
3916
- timeoutId = clearTimeout(timeoutId);
3917
- }
3918
- else if (!timeoutId && wait !== maxWait) {
3919
- timeoutId = setTimeout(delayed, wait);
3920
- }
3921
- if (leadingCall) {
3922
- isCalled = true;
3923
- result = func.apply(thisArg, args);
3924
- }
3925
- if (isCalled && !timeoutId && !maxTimeoutId) {
3926
- args = thisArg = null;
3927
- }
3928
- return result;
3929
- };
3930
- }
3931
-
3932
- /**
3933
- * Defers executing the `func` function until the current call stack has cleared.
3934
- * Additional arguments will be provided to `func` when it is invoked.
3935
- *
3936
- * @static
3937
- * @memberOf _
3938
- * @category Functions
3939
- * @param {Function} func The function to defer.
3940
- * @param {...*} [arg] Arguments to invoke the function with.
3941
- * @returns {number} Returns the timer id.
3942
- * @example
3943
- *
3944
- * _.defer(function(text) { console.log(text); }, 'deferred');
3945
- * // logs 'deferred' after one or more milliseconds
3946
- */
3947
- function defer(func) {
3948
- if (!isFunction(func)) {
3949
- throw new TypeError;
3950
- }
3951
- var args = slice(arguments, 1);
3952
- return setTimeout(function() { func.apply(undefined, args); }, 1);
3953
- }
3954
-
3955
- /**
3956
- * Executes the `func` function after `wait` milliseconds. Additional arguments
3957
- * will be provided to `func` when it is invoked.
3958
- *
3959
- * @static
3960
- * @memberOf _
3961
- * @category Functions
3962
- * @param {Function} func The function to delay.
3963
- * @param {number} wait The number of milliseconds to delay execution.
3964
- * @param {...*} [arg] Arguments to invoke the function with.
3965
- * @returns {number} Returns the timer id.
3966
- * @example
3967
- *
3968
- * _.delay(function(text) { console.log(text); }, 1000, 'later');
3969
- * // => logs 'later' after one second
3970
- */
3971
- function delay(func, wait) {
3972
- if (!isFunction(func)) {
3973
- throw new TypeError;
3974
- }
3975
- var args = slice(arguments, 2);
3976
- return setTimeout(function() { func.apply(undefined, args); }, wait);
3977
- }
3978
-
3979
- /**
3980
- * Creates a function that memoizes the result of `func`. If `resolver` is
3981
- * provided it will be used to determine the cache key for storing the result
3982
- * based on the arguments provided to the memoized function. By default, the
3983
- * first argument provided to the memoized function is used as the cache key.
3984
- * The `func` is executed with the `this` binding of the memoized function.
3985
- * The result cache is exposed as the `cache` property on the memoized function.
3986
- *
3987
- * @static
3988
- * @memberOf _
3989
- * @category Functions
3990
- * @param {Function} func The function to have its output memoized.
3991
- * @param {Function} [resolver] A function used to resolve the cache key.
3992
- * @returns {Function} Returns the new memoizing function.
3993
- * @example
3994
- *
3995
- * var fibonacci = _.memoize(function(n) {
3996
- * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
3997
- * });
3998
- *
3999
- * fibonacci(9)
4000
- * // => 34
4001
- *
4002
- * var data = {
4003
- * 'fred': { 'name': 'fred', 'age': 40 },
4004
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
4005
- * };
4006
- *
4007
- * // modifying the result cache
4008
- * var get = _.memoize(function(name) { return data[name]; }, _.identity);
4009
- * get('pebbles');
4010
- * // => { 'name': 'pebbles', 'age': 1 }
4011
- *
4012
- * get.cache.pebbles.name = 'penelope';
4013
- * get('pebbles');
4014
- * // => { 'name': 'penelope', 'age': 1 }
4015
- */
4016
- function memoize(func, resolver) {
4017
- var cache = {};
4018
- return function() {
4019
- var key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
4020
- return hasOwnProperty.call(cache, key)
4021
- ? cache[key]
4022
- : (cache[key] = func.apply(this, arguments));
4023
- };
4024
- }
4025
-
4026
- /**
4027
- * Creates a function that is restricted to execute `func` once. Repeat calls to
4028
- * the function will return the value of the first call. The `func` is executed
4029
- * with the `this` binding of the created function.
4030
- *
4031
- * @static
4032
- * @memberOf _
4033
- * @category Functions
4034
- * @param {Function} func The function to restrict.
4035
- * @returns {Function} Returns the new restricted function.
4036
- * @example
4037
- *
4038
- * var initialize = _.once(createApplication);
4039
- * initialize();
4040
- * initialize();
4041
- * // `initialize` executes `createApplication` once
4042
- */
4043
- function once(func) {
4044
- var ran,
4045
- result;
4046
-
4047
- if (!isFunction(func)) {
4048
- throw new TypeError;
4049
- }
4050
- return function() {
4051
- if (ran) {
4052
- return result;
4053
- }
4054
- ran = true;
4055
- result = func.apply(this, arguments);
4056
-
4057
- // clear the `func` variable so the function may be garbage collected
4058
- func = null;
4059
- return result;
4060
- };
4061
- }
4062
-
4063
- /**
4064
- * Creates a function that, when called, invokes `func` with any additional
4065
- * `partial` arguments prepended to those provided to the new function. This
4066
- * method is similar to `_.bind` except it does **not** alter the `this` binding.
4067
- *
4068
- * @static
4069
- * @memberOf _
4070
- * @category Functions
4071
- * @param {Function} func The function to partially apply arguments to.
4072
- * @param {...*} [arg] Arguments to be partially applied.
4073
- * @returns {Function} Returns the new partially applied function.
4074
- * @example
4075
- *
4076
- * var greet = function(greeting, name) { return greeting + ' ' + name; };
4077
- * var hi = _.partial(greet, 'hi');
4078
- * hi('fred');
4079
- * // => 'hi fred'
4080
- */
4081
- function partial(func) {
4082
- return createWrapper(func, 16, slice(arguments, 1));
4083
- }
4084
-
4085
- /**
4086
- * Creates a function that, when executed, will only call the `func` function
4087
- * at most once per every `wait` milliseconds. Provide an options object to
4088
- * indicate that `func` should be invoked on the leading and/or trailing edge
4089
- * of the `wait` timeout. Subsequent calls to the throttled function will
4090
- * return the result of the last `func` call.
4091
- *
4092
- * Note: If `leading` and `trailing` options are `true` `func` will be called
4093
- * on the trailing edge of the timeout only if the the throttled function is
4094
- * invoked more than once during the `wait` timeout.
4095
- *
4096
- * @static
4097
- * @memberOf _
4098
- * @category Functions
4099
- * @param {Function} func The function to throttle.
4100
- * @param {number} wait The number of milliseconds to throttle executions to.
4101
- * @param {Object} [options] The options object.
4102
- * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
4103
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
4104
- * @returns {Function} Returns the new throttled function.
4105
- * @example
4106
- *
4107
- * // avoid excessively updating the position while scrolling
4108
- * var throttled = _.throttle(updatePosition, 100);
4109
- * jQuery(window).on('scroll', throttled);
4110
- *
4111
- * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
4112
- * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
4113
- * 'trailing': false
4114
- * }));
4115
- */
4116
- function throttle(func, wait, options) {
4117
- var leading = true,
4118
- trailing = true;
4119
-
4120
- if (!isFunction(func)) {
4121
- throw new TypeError;
4122
- }
4123
- if (options === false) {
4124
- leading = false;
4125
- } else if (isObject(options)) {
4126
- leading = 'leading' in options ? options.leading : leading;
4127
- trailing = 'trailing' in options ? options.trailing : trailing;
4128
- }
4129
- options = {};
4130
- options.leading = leading;
4131
- options.maxWait = wait;
4132
- options.trailing = trailing;
4133
-
4134
- return debounce(func, wait, options);
4135
- }
4136
-
4137
- /**
4138
- * Creates a function that provides `value` to the wrapper function as its
4139
- * first argument. Additional arguments provided to the function are appended
4140
- * to those provided to the wrapper function. The wrapper is executed with
4141
- * the `this` binding of the created function.
4142
- *
4143
- * @static
4144
- * @memberOf _
4145
- * @category Functions
4146
- * @param {*} value The value to wrap.
4147
- * @param {Function} wrapper The wrapper function.
4148
- * @returns {Function} Returns the new function.
4149
- * @example
4150
- *
4151
- * var p = _.wrap(_.escape, function(func, text) {
4152
- * return '<p>' + func(text) + '</p>';
4153
- * });
4154
- *
4155
- * p('Fred, Wilma, & Pebbles');
4156
- * // => '<p>Fred, Wilma, &amp; Pebbles</p>'
4157
- */
4158
- function wrap(value, wrapper) {
4159
- return createWrapper(wrapper, 16, [value]);
4160
- }
4161
-
4162
- /*--------------------------------------------------------------------------*/
4163
-
4164
- /**
4165
- * Produces a callback bound to an optional `thisArg`. If `func` is a property
4166
- * name the created callback will return the property value for a given element.
4167
- * If `func` is an object the created callback will return `true` for elements
4168
- * that contain the equivalent object properties, otherwise it will return `false`.
4169
- *
4170
- * @static
4171
- * @memberOf _
4172
- * @category Utilities
4173
- * @param {*} [func=identity] The value to convert to a callback.
4174
- * @param {*} [thisArg] The `this` binding of the created callback.
4175
- * @param {number} [argCount] The number of arguments the callback accepts.
4176
- * @returns {Function} Returns a callback function.
4177
- * @example
4178
- *
4179
- * var characters = [
4180
- * { 'name': 'barney', 'age': 36 },
4181
- * { 'name': 'fred', 'age': 40 }
4182
- * ];
4183
- *
4184
- * // wrap to create custom callback shorthands
4185
- * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
4186
- * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
4187
- * return !match ? func(callback, thisArg) : function(object) {
4188
- * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
4189
- * };
4190
- * });
4191
- *
4192
- * _.filter(characters, 'age__gt38');
4193
- * // => [{ 'name': 'fred', 'age': 40 }]
4194
- */
4195
- function createCallback(func, thisArg, argCount) {
4196
- var type = typeof func;
4197
- if (func == null || type == 'function') {
4198
- return baseCreateCallback(func, thisArg, argCount);
4199
- }
4200
- // handle "_.pluck" style callback shorthands
4201
- if (type != 'object') {
4202
- return property(func);
4203
- }
4204
- var props = keys(func);
4205
- return function(object) {
4206
- var length = props.length,
4207
- result = false;
4208
-
4209
- while (length--) {
4210
- if (!(result = object[props[length]] === func[props[length]])) {
4211
- break;
4212
- }
4213
- }
4214
- return result;
4215
- };
4216
- }
4217
-
4218
- /**
4219
- * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
4220
- * corresponding HTML entities.
4221
- *
4222
- * @static
4223
- * @memberOf _
4224
- * @category Utilities
4225
- * @param {string} string The string to escape.
4226
- * @returns {string} Returns the escaped string.
4227
- * @example
4228
- *
4229
- * _.escape('Fred, Wilma, & Pebbles');
4230
- * // => 'Fred, Wilma, &amp; Pebbles'
4231
- */
4232
- function escape(string) {
4233
- return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
4234
- }
4235
-
4236
- /**
4237
- * This method returns the first argument provided to it.
4238
- *
4239
- * @static
4240
- * @memberOf _
4241
- * @category Utilities
4242
- * @param {*} value Any value.
4243
- * @returns {*} Returns `value`.
4244
- * @example
4245
- *
4246
- * var object = { 'name': 'fred' };
4247
- * _.identity(object) === object;
4248
- * // => true
4249
- */
4250
- function identity(value) {
4251
- return value;
4252
- }
4253
-
4254
- /**
4255
- * Adds function properties of a source object to the destination object.
4256
- * If `object` is a function methods will be added to its prototype as well.
4257
- *
4258
- * @static
4259
- * @memberOf _
4260
- * @category Utilities
4261
- * @param {Function|Object} [object=lodash] object The destination object.
4262
- * @param {Object} source The object of functions to add.
4263
- * @param {Object} [options] The options object.
4264
- * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
4265
- * @example
4266
- *
4267
- * function capitalize(string) {
4268
- * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
4269
- * }
4270
- *
4271
- * _.mixin({ 'capitalize': capitalize });
4272
- * _.capitalize('fred');
4273
- * // => 'Fred'
4274
- *
4275
- * _('fred').capitalize().value();
4276
- * // => 'Fred'
4277
- *
4278
- * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
4279
- * _('fred').capitalize();
4280
- * // => 'Fred'
4281
- */
4282
- function mixin(object) {
4283
- forEach(functions(object), function(methodName) {
4284
- var func = lodash[methodName] = object[methodName];
4285
-
4286
- lodash.prototype[methodName] = function() {
4287
- var args = [this.__wrapped__];
4288
- push.apply(args, arguments);
4289
-
4290
- var result = func.apply(lodash, args);
4291
- return this.__chain__
4292
- ? new lodashWrapper(result, true)
4293
- : result;
4294
- };
4295
- });
4296
- }
4297
-
4298
- /**
4299
- * Reverts the '_' variable to its previous value and returns a reference to
4300
- * the `lodash` function.
4301
- *
4302
- * @static
4303
- * @memberOf _
4304
- * @category Utilities
4305
- * @returns {Function} Returns the `lodash` function.
4306
- * @example
4307
- *
4308
- * var lodash = _.noConflict();
4309
- */
4310
- function noConflict() {
4311
- root._ = oldDash;
4312
- return this;
4313
- }
4314
-
4315
- /**
4316
- * A no-operation function.
4317
- *
4318
- * @static
4319
- * @memberOf _
4320
- * @category Utilities
4321
- * @example
4322
- *
4323
- * var object = { 'name': 'fred' };
4324
- * _.noop(object) === undefined;
4325
- * // => true
4326
- */
4327
- function noop() {
4328
- // no operation performed
4329
- }
4330
-
4331
- /**
4332
- * Gets the number of milliseconds that have elapsed since the Unix epoch
4333
- * (1 January 1970 00:00:00 UTC).
4334
- *
4335
- * @static
4336
- * @memberOf _
4337
- * @category Utilities
4338
- * @example
4339
- *
4340
- * var stamp = _.now();
4341
- * _.defer(function() { console.log(_.now() - stamp); });
4342
- * // => logs the number of milliseconds it took for the deferred function to be called
4343
- */
4344
- var now = isNative(now = Date.now) && now || function() {
4345
- return new Date().getTime();
4346
- };
4347
-
4348
- /**
4349
- * Creates a "_.pluck" style function, which returns the `key` value of a
4350
- * given object.
4351
- *
4352
- * @static
4353
- * @memberOf _
4354
- * @category Utilities
4355
- * @param {string} key The name of the property to retrieve.
4356
- * @returns {Function} Returns the new function.
4357
- * @example
4358
- *
4359
- * var characters = [
4360
- * { 'name': 'fred', 'age': 40 },
4361
- * { 'name': 'barney', 'age': 36 }
4362
- * ];
4363
- *
4364
- * var getName = _.property('name');
4365
- *
4366
- * _.map(characters, getName);
4367
- * // => ['barney', 'fred']
4368
- *
4369
- * _.sortBy(characters, getName);
4370
- * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
4371
- */
4372
- function property(key) {
4373
- return function(object) {
4374
- return object[key];
4375
- };
4376
- }
4377
-
4378
- /**
4379
- * Produces a random number between `min` and `max` (inclusive). If only one
4380
- * argument is provided a number between `0` and the given number will be
4381
- * returned. If `floating` is truey or either `min` or `max` are floats a
4382
- * floating-point number will be returned instead of an integer.
4383
- *
4384
- * @static
4385
- * @memberOf _
4386
- * @category Utilities
4387
- * @param {number} [min=0] The minimum possible value.
4388
- * @param {number} [max=1] The maximum possible value.
4389
- * @param {boolean} [floating=false] Specify returning a floating-point number.
4390
- * @returns {number} Returns a random number.
4391
- * @example
4392
- *
4393
- * _.random(0, 5);
4394
- * // => an integer between 0 and 5
4395
- *
4396
- * _.random(5);
4397
- * // => also an integer between 0 and 5
4398
- *
4399
- * _.random(5, true);
4400
- * // => a floating-point number between 0 and 5
4401
- *
4402
- * _.random(1.2, 5.2);
4403
- * // => a floating-point number between 1.2 and 5.2
4404
- */
4405
- function random(min, max) {
4406
- if (min == null && max == null) {
4407
- max = 1;
4408
- }
4409
- min = +min || 0;
4410
- if (max == null) {
4411
- max = min;
4412
- min = 0;
4413
- } else {
4414
- max = +max || 0;
4415
- }
4416
- return min + floor(nativeRandom() * (max - min + 1));
4417
- }
4418
-
4419
- /**
4420
- * Resolves the value of property `key` on `object`. If `key` is a function
4421
- * it will be invoked with the `this` binding of `object` and its result returned,
4422
- * else the property value is returned. If `object` is falsey then `undefined`
4423
- * is returned.
4424
- *
4425
- * @static
4426
- * @memberOf _
4427
- * @category Utilities
4428
- * @param {Object} object The object to inspect.
4429
- * @param {string} key The name of the property to resolve.
4430
- * @returns {*} Returns the resolved value.
4431
- * @example
4432
- *
4433
- * var object = {
4434
- * 'cheese': 'crumpets',
4435
- * 'stuff': function() {
4436
- * return 'nonsense';
4437
- * }
4438
- * };
4439
- *
4440
- * _.result(object, 'cheese');
4441
- * // => 'crumpets'
4442
- *
4443
- * _.result(object, 'stuff');
4444
- * // => 'nonsense'
4445
- */
4446
- function result(object, key) {
4447
- if (object) {
4448
- var value = object[key];
4449
- return isFunction(value) ? object[key]() : value;
4450
- }
4451
- }
4452
-
4453
- /**
4454
- * A micro-templating method that handles arbitrary delimiters, preserves
4455
- * whitespace, and correctly escapes quotes within interpolated code.
4456
- *
4457
- * Note: In the development build, `_.template` utilizes sourceURLs for easier
4458
- * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
4459
- *
4460
- * For more information on precompiling templates see:
4461
- * http://lodash.com/custom-builds
4462
- *
4463
- * For more information on Chrome extension sandboxes see:
4464
- * http://developer.chrome.com/stable/extensions/sandboxingEval.html
4465
- *
4466
- * @static
4467
- * @memberOf _
4468
- * @category Utilities
4469
- * @param {string} text The template text.
4470
- * @param {Object} data The data object used to populate the text.
4471
- * @param {Object} [options] The options object.
4472
- * @param {RegExp} [options.escape] The "escape" delimiter.
4473
- * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
4474
- * @param {Object} [options.imports] An object to import into the template as local variables.
4475
- * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
4476
- * @param {string} [sourceURL] The sourceURL of the template's compiled source.
4477
- * @param {string} [variable] The data object variable name.
4478
- * @returns {Function|string} Returns a compiled function when no `data` object
4479
- * is given, else it returns the interpolated text.
4480
- * @example
4481
- *
4482
- * // using the "interpolate" delimiter to create a compiled template
4483
- * var compiled = _.template('hello <%= name %>');
4484
- * compiled({ 'name': 'fred' });
4485
- * // => 'hello fred'
4486
- *
4487
- * // using the "escape" delimiter to escape HTML in data property values
4488
- * _.template('<b><%- value %></b>', { 'value': '<script>' });
4489
- * // => '<b>&lt;script&gt;</b>'
4490
- *
4491
- * // using the "evaluate" delimiter to generate HTML
4492
- * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
4493
- * _.template(list, { 'people': ['fred', 'barney'] });
4494
- * // => '<li>fred</li><li>barney</li>'
4495
- *
4496
- * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
4497
- * _.template('hello ${ name }', { 'name': 'pebbles' });
4498
- * // => 'hello pebbles'
4499
- *
4500
- * // using the internal `print` function in "evaluate" delimiters
4501
- * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
4502
- * // => 'hello barney!'
4503
- *
4504
- * // using a custom template delimiters
4505
- * _.templateSettings = {
4506
- * 'interpolate': /{{([\s\S]+?)}}/g
4507
- * };
4508
- *
4509
- * _.template('hello {{ name }}!', { 'name': 'mustache' });
4510
- * // => 'hello mustache!'
4511
- *
4512
- * // using the `imports` option to import jQuery
4513
- * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
4514
- * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
4515
- * // => '<li>fred</li><li>barney</li>'
4516
- *
4517
- * // using the `sourceURL` option to specify a custom sourceURL for the template
4518
- * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
4519
- * compiled(data);
4520
- * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
4521
- *
4522
- * // using the `variable` option to ensure a with-statement isn't used in the compiled template
4523
- * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
4524
- * compiled.source;
4525
- * // => function(data) {
4526
- * var __t, __p = '', __e = _.escape;
4527
- * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
4528
- * return __p;
4529
- * }
4530
- *
4531
- * // using the `source` property to inline compiled templates for meaningful
4532
- * // line numbers in error messages and a stack trace
4533
- * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
4534
- * var JST = {\
4535
- * "main": ' + _.template(mainText).source + '\
4536
- * };\
4537
- * ');
4538
- */
4539
- function template(text, data, options) {
4540
- var _ = lodash,
4541
- settings = _.templateSettings;
4542
-
4543
- text = String(text || '');
4544
- options = defaults({}, options, settings);
4545
-
4546
- var index = 0,
4547
- source = "__p += '",
4548
- variable = options.variable;
4549
-
4550
- var reDelimiters = RegExp(
4551
- (options.escape || reNoMatch).source + '|' +
4552
- (options.interpolate || reNoMatch).source + '|' +
4553
- (options.evaluate || reNoMatch).source + '|$'
4554
- , 'g');
4555
-
4556
- text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {
4557
- source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
4558
- if (escapeValue) {
4559
- source += "' +\n_.escape(" + escapeValue + ") +\n'";
4560
- }
4561
- if (evaluateValue) {
4562
- source += "';\n" + evaluateValue + ";\n__p += '";
4563
- }
4564
- if (interpolateValue) {
4565
- source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
4566
- }
4567
- index = offset + match.length;
4568
- return match;
4569
- });
4570
-
4571
- source += "';\n";
4572
- if (!variable) {
4573
- variable = 'obj';
4574
- source = 'with (' + variable + ' || {}) {\n' + source + '\n}\n';
4575
- }
4576
- source = 'function(' + variable + ') {\n' +
4577
- "var __t, __p = '', __j = Array.prototype.join;\n" +
4578
- "function print() { __p += __j.call(arguments, '') }\n" +
4579
- source +
4580
- 'return __p\n}';
4581
-
4582
- try {
4583
- var result = Function('_', 'return ' + source)(_);
4584
- } catch(e) {
4585
- e.source = source;
4586
- throw e;
4587
- }
4588
- if (data) {
4589
- return result(data);
4590
- }
4591
- result.source = source;
4592
- return result;
4593
- }
4594
-
4595
- /**
4596
- * Executes the callback `n` times, returning an array of the results
4597
- * of each callback execution. The callback is bound to `thisArg` and invoked
4598
- * with one argument; (index).
4599
- *
4600
- * @static
4601
- * @memberOf _
4602
- * @category Utilities
4603
- * @param {number} n The number of times to execute the callback.
4604
- * @param {Function} callback The function called per iteration.
4605
- * @param {*} [thisArg] The `this` binding of `callback`.
4606
- * @returns {Array} Returns an array of the results of each `callback` execution.
4607
- * @example
4608
- *
4609
- * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
4610
- * // => [3, 6, 4]
4611
- *
4612
- * _.times(3, function(n) { mage.castSpell(n); });
4613
- * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
4614
- *
4615
- * _.times(3, function(n) { this.cast(n); }, mage);
4616
- * // => also calls `mage.castSpell(n)` three times
4617
- */
4618
- function times(n, callback, thisArg) {
4619
- n = (n = +n) > -1 ? n : 0;
4620
- var index = -1,
4621
- result = Array(n);
4622
-
4623
- callback = baseCreateCallback(callback, thisArg, 1);
4624
- while (++index < n) {
4625
- result[index] = callback(index);
4626
- }
4627
- return result;
4628
- }
4629
-
4630
- /**
4631
- * The inverse of `_.escape` this method converts the HTML entities
4632
- * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
4633
- * corresponding characters.
4634
- *
4635
- * @static
4636
- * @memberOf _
4637
- * @category Utilities
4638
- * @param {string} string The string to unescape.
4639
- * @returns {string} Returns the unescaped string.
4640
- * @example
4641
- *
4642
- * _.unescape('Fred, Barney &amp; Pebbles');
4643
- * // => 'Fred, Barney & Pebbles'
4644
- */
4645
- function unescape(string) {
4646
- return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
4647
- }
4648
-
4649
- /**
4650
- * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
4651
- *
4652
- * @static
4653
- * @memberOf _
4654
- * @category Utilities
4655
- * @param {string} [prefix] The value to prefix the ID with.
4656
- * @returns {string} Returns the unique ID.
4657
- * @example
4658
- *
4659
- * _.uniqueId('contact_');
4660
- * // => 'contact_104'
4661
- *
4662
- * _.uniqueId();
4663
- * // => '105'
4664
- */
4665
- function uniqueId(prefix) {
4666
- var id = ++idCounter + '';
4667
- return prefix ? prefix + id : id;
4668
- }
4669
-
4670
- /*--------------------------------------------------------------------------*/
4671
-
4672
- /**
4673
- * Creates a `lodash` object that wraps the given value with explicit
4674
- * method chaining enabled.
4675
- *
4676
- * @static
4677
- * @memberOf _
4678
- * @category Chaining
4679
- * @param {*} value The value to wrap.
4680
- * @returns {Object} Returns the wrapper object.
4681
- * @example
4682
- *
4683
- * var characters = [
4684
- * { 'name': 'barney', 'age': 36 },
4685
- * { 'name': 'fred', 'age': 40 },
4686
- * { 'name': 'pebbles', 'age': 1 }
4687
- * ];
4688
- *
4689
- * var youngest = _.chain(characters)
4690
- * .sortBy('age')
4691
- * .map(function(chr) { return chr.name + ' is ' + chr.age; })
4692
- * .first()
4693
- * .value();
4694
- * // => 'pebbles is 1'
4695
- */
4696
- function chain(value) {
4697
- value = new lodashWrapper(value);
4698
- value.__chain__ = true;
4699
- return value;
4700
- }
4701
-
4702
- /**
4703
- * Invokes `interceptor` with the `value` as the first argument and then
4704
- * returns `value`. The purpose of this method is to "tap into" a method
4705
- * chain in order to perform operations on intermediate results within
4706
- * the chain.
4707
- *
4708
- * @static
4709
- * @memberOf _
4710
- * @category Chaining
4711
- * @param {*} value The value to provide to `interceptor`.
4712
- * @param {Function} interceptor The function to invoke.
4713
- * @returns {*} Returns `value`.
4714
- * @example
4715
- *
4716
- * _([1, 2, 3, 4])
4717
- * .tap(function(array) { array.pop(); })
4718
- * .reverse()
4719
- * .value();
4720
- * // => [3, 2, 1]
4721
- */
4722
- function tap(value, interceptor) {
4723
- interceptor(value);
4724
- return value;
4725
- }
4726
-
4727
- /**
4728
- * Enables explicit method chaining on the wrapper object.
4729
- *
4730
- * @name chain
4731
- * @memberOf _
4732
- * @category Chaining
4733
- * @returns {*} Returns the wrapper object.
4734
- * @example
4735
- *
4736
- * var characters = [
4737
- * { 'name': 'barney', 'age': 36 },
4738
- * { 'name': 'fred', 'age': 40 }
4739
- * ];
4740
- *
4741
- * // without explicit chaining
4742
- * _(characters).first();
4743
- * // => { 'name': 'barney', 'age': 36 }
4744
- *
4745
- * // with explicit chaining
4746
- * _(characters).chain()
4747
- * .first()
4748
- * .pick('age')
4749
- * .value();
4750
- * // => { 'age': 36 }
4751
- */
4752
- function wrapperChain() {
4753
- this.__chain__ = true;
4754
- return this;
4755
- }
4756
-
4757
- /**
4758
- * Extracts the wrapped value.
4759
- *
4760
- * @name valueOf
4761
- * @memberOf _
4762
- * @alias value
4763
- * @category Chaining
4764
- * @returns {*} Returns the wrapped value.
4765
- * @example
4766
- *
4767
- * _([1, 2, 3]).valueOf();
4768
- * // => [1, 2, 3]
4769
- */
4770
- function wrapperValueOf() {
4771
- return this.__wrapped__;
4772
- }
4773
-
4774
- /*--------------------------------------------------------------------------*/
4775
-
4776
- // add functions that return wrapped values when chaining
4777
- lodash.after = after;
4778
- lodash.bind = bind;
4779
- lodash.bindAll = bindAll;
4780
- lodash.chain = chain;
4781
- lodash.compact = compact;
4782
- lodash.compose = compose;
4783
- lodash.countBy = countBy;
4784
- lodash.debounce = debounce;
4785
- lodash.defaults = defaults;
4786
- lodash.defer = defer;
4787
- lodash.delay = delay;
4788
- lodash.difference = difference;
4789
- lodash.filter = filter;
4790
- lodash.flatten = flatten;
4791
- lodash.forEach = forEach;
4792
- lodash.functions = functions;
4793
- lodash.groupBy = groupBy;
4794
- lodash.indexBy = indexBy;
4795
- lodash.initial = initial;
4796
- lodash.intersection = intersection;
4797
- lodash.invert = invert;
4798
- lodash.invoke = invoke;
4799
- lodash.keys = keys;
4800
- lodash.map = map;
4801
- lodash.max = max;
4802
- lodash.memoize = memoize;
4803
- lodash.min = min;
4804
- lodash.omit = omit;
4805
- lodash.once = once;
4806
- lodash.pairs = pairs;
4807
- lodash.partial = partial;
4808
- lodash.pick = pick;
4809
- lodash.pluck = pluck;
4810
- lodash.range = range;
4811
- lodash.reject = reject;
4812
- lodash.rest = rest;
4813
- lodash.shuffle = shuffle;
4814
- lodash.sortBy = sortBy;
4815
- lodash.tap = tap;
4816
- lodash.throttle = throttle;
4817
- lodash.times = times;
4818
- lodash.toArray = toArray;
4819
- lodash.union = union;
4820
- lodash.uniq = uniq;
4821
- lodash.values = values;
4822
- lodash.where = where;
4823
- lodash.without = without;
4824
- lodash.wrap = wrap;
4825
- lodash.zip = zip;
4826
-
4827
- // add aliases
4828
- lodash.collect = map;
4829
- lodash.drop = rest;
4830
- lodash.each = forEach;
4831
- lodash.extend = assign;
4832
- lodash.methods = functions;
4833
- lodash.object = zipObject;
4834
- lodash.select = filter;
4835
- lodash.tail = rest;
4836
- lodash.unique = uniq;
4837
-
4838
- /*--------------------------------------------------------------------------*/
4839
-
4840
- // add functions that return unwrapped values when chaining
4841
- lodash.clone = clone;
4842
- lodash.contains = contains;
4843
- lodash.escape = escape;
4844
- lodash.every = every;
4845
- lodash.find = find;
4846
- lodash.has = has;
4847
- lodash.identity = identity;
4848
- lodash.indexOf = indexOf;
4849
- lodash.isArguments = isArguments;
4850
- lodash.isArray = isArray;
4851
- lodash.isBoolean = isBoolean;
4852
- lodash.isDate = isDate;
4853
- lodash.isElement = isElement;
4854
- lodash.isEmpty = isEmpty;
4855
- lodash.isEqual = isEqual;
4856
- lodash.isFinite = isFinite;
4857
- lodash.isFunction = isFunction;
4858
- lodash.isNaN = isNaN;
4859
- lodash.isNull = isNull;
4860
- lodash.isNumber = isNumber;
4861
- lodash.isObject = isObject;
4862
- lodash.isRegExp = isRegExp;
4863
- lodash.isString = isString;
4864
- lodash.isUndefined = isUndefined;
4865
- lodash.lastIndexOf = lastIndexOf;
4866
- lodash.mixin = mixin;
4867
- lodash.noConflict = noConflict;
4868
- lodash.random = random;
4869
- lodash.reduce = reduce;
4870
- lodash.reduceRight = reduceRight;
4871
- lodash.result = result;
4872
- lodash.size = size;
4873
- lodash.some = some;
4874
- lodash.sortedIndex = sortedIndex;
4875
- lodash.template = template;
4876
- lodash.unescape = unescape;
4877
- lodash.uniqueId = uniqueId;
4878
-
4879
- // add aliases
4880
- lodash.all = every;
4881
- lodash.any = some;
4882
- lodash.detect = find;
4883
- lodash.findWhere = findWhere;
4884
- lodash.foldl = reduce;
4885
- lodash.foldr = reduceRight;
4886
- lodash.include = contains;
4887
- lodash.inject = reduce;
4888
-
4889
- /*--------------------------------------------------------------------------*/
4890
-
4891
- // add functions capable of returning wrapped and unwrapped values when chaining
4892
- lodash.first = first;
4893
- lodash.last = last;
4894
- lodash.sample = sample;
4895
-
4896
- // add aliases
4897
- lodash.take = first;
4898
- lodash.head = first;
4899
-
4900
- /*--------------------------------------------------------------------------*/
4901
-
4902
- // add functions to `lodash.prototype`
4903
- mixin(lodash);
4904
-
4905
- /**
4906
- * The semantic version number.
4907
- *
4908
- * @static
4909
- * @memberOf _
4910
- * @type string
4911
- */
4912
- lodash.VERSION = '2.4.1';
4913
-
4914
- // add "Chaining" functions to the wrapper
4915
- lodash.prototype.chain = wrapperChain;
4916
- lodash.prototype.value = wrapperValueOf;
4917
-
4918
- // add `Array` mutator functions to the wrapper
4919
- forEach(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
4920
- var func = arrayRef[methodName];
4921
- lodash.prototype[methodName] = function() {
4922
- var value = this.__wrapped__;
4923
- func.apply(value, arguments);
4924
-
4925
- // avoid array-like object bugs with `Array#shift` and `Array#splice`
4926
- // in Firefox < 10 and IE < 9
4927
- if (!support.spliceObjects && value.length === 0) {
4928
- delete value[0];
4929
- }
4930
- return this;
4931
- };
4932
- });
4933
-
4934
- // add `Array` accessor functions to the wrapper
4935
- forEach(['concat', 'join', 'slice'], function(methodName) {
4936
- var func = arrayRef[methodName];
4937
- lodash.prototype[methodName] = function() {
4938
- var value = this.__wrapped__,
4939
- result = func.apply(value, arguments);
4940
-
4941
- if (this.__chain__) {
4942
- result = new lodashWrapper(result);
4943
- result.__chain__ = true;
4944
- }
4945
- return result;
4946
- };
4947
- });
4948
-
4949
- /*--------------------------------------------------------------------------*/
4950
-
4951
- // some AMD build optimizers like r.js check for condition patterns like the following:
4952
- if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
4953
- // Expose Lo-Dash to the global object even when an AMD loader is present in
4954
- // case Lo-Dash is loaded with a RequireJS shim config.
4955
- // See http://requirejs.org/docs/api.html#config-shim
4956
- root._ = lodash;
4957
-
4958
- // define as an anonymous module so, through path mapping, it can be
4959
- // referenced as the "underscore" module
4960
- define(function() {
4961
- return lodash;
4962
- });
4963
- }
4964
- // check for `exports` after `define` in case a build optimizer adds an `exports` object
4965
- else if (freeExports && freeModule) {
4966
- // in Node.js or RingoJS
4967
- if (moduleExports) {
4968
- (freeModule.exports = lodash)._ = lodash;
4969
- }
4970
- // in Narwhal or Rhino -require
4971
- else {
4972
- freeExports._ = lodash;
4973
- }
4974
- }
4975
- else {
4976
- // in a browser or Rhino
4977
- root._ = lodash;
4978
- }
4979
- }.call(this));