lodash-rails 0.7.0 → 0.8.1
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.
- data/README.md +1 -1
- data/lib/lodash/rails/version.rb +1 -1
- data/vendor/assets/javascripts/lodash.js +610 -869
- data/vendor/assets/javascripts/lodash.min.js +37 -40
- metadata +3 -3
data/README.md
CHANGED
data/lib/lodash/rails/version.rb
CHANGED
@@ -1,38 +1,13 @@
|
|
1
1
|
/*!
|
2
|
-
* Lo-Dash v0.
|
3
|
-
*
|
4
|
-
* Based on Underscore.js 1.
|
5
|
-
*
|
2
|
+
* Lo-Dash v0.8.1 <http://lodash.com>
|
3
|
+
* (c) 2012 John-David Dalton <http://allyoucanleet.com/>
|
4
|
+
* Based on Underscore.js 1.4.1 <http://underscorejs.org>
|
5
|
+
* (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
6
6
|
* Available under MIT license <http://lodash.com/license>
|
7
7
|
*/
|
8
8
|
;(function(window, undefined) {
|
9
9
|
'use strict';
|
10
10
|
|
11
|
-
/**
|
12
|
-
* Used to cache the last `_.templateSettings.evaluate` delimiter to avoid
|
13
|
-
* unnecessarily assigning `reEvaluateDelimiter` a new generated regexp.
|
14
|
-
* Assigned in `_.template`.
|
15
|
-
*/
|
16
|
-
var lastEvaluateDelimiter;
|
17
|
-
|
18
|
-
/**
|
19
|
-
* Used to cache the last template `options.variable` to avoid unnecessarily
|
20
|
-
* assigning `reDoubleVariable` a new generated regexp. Assigned in `_.template`.
|
21
|
-
*/
|
22
|
-
var lastVariable;
|
23
|
-
|
24
|
-
/**
|
25
|
-
* Used to match potentially incorrect data object references, like `obj.obj`,
|
26
|
-
* in compiled templates. Assigned in `_.template`.
|
27
|
-
*/
|
28
|
-
var reDoubleVariable;
|
29
|
-
|
30
|
-
/**
|
31
|
-
* Used to match "evaluate" delimiters, including internal delimiters,
|
32
|
-
* in template text. Assigned in `_.template`.
|
33
|
-
*/
|
34
|
-
var reEvaluateDelimiter;
|
35
|
-
|
36
11
|
/** Detect free variable `exports` */
|
37
12
|
var freeExports = typeof exports == 'object' && exports &&
|
38
13
|
(typeof global == 'object' && global && global == global.global && (window = global), exports);
|
@@ -77,8 +52,8 @@
|
|
77
52
|
.replace(/valueOf|for [^\]]+/g, '.+?') + '$'
|
78
53
|
);
|
79
54
|
|
80
|
-
/** Used to
|
81
|
-
var
|
55
|
+
/** Used to ensure capturing order and avoid matches for undefined delimiters */
|
56
|
+
var reNoMatch = /($^)/;
|
82
57
|
|
83
58
|
/** Used to match HTML characters */
|
84
59
|
var reUnescapedHtml = /[&<>"']/g;
|
@@ -95,13 +70,6 @@
|
|
95
70
|
/** Used to make template sourceURLs easier to identify */
|
96
71
|
var templateCounter = 0;
|
97
72
|
|
98
|
-
/** Used to replace template delimiters */
|
99
|
-
var tokenHead = '__token',
|
100
|
-
tokenFoot = '__';
|
101
|
-
|
102
|
-
/** Used to store tokenized template text snippets */
|
103
|
-
var tokenized = [];
|
104
|
-
|
105
73
|
/** Native method shortcuts */
|
106
74
|
var concat = ArrayProto.concat,
|
107
75
|
hasOwnProperty = ObjectProto.hasOwnProperty,
|
@@ -113,6 +81,7 @@
|
|
113
81
|
/* Native method shortcuts for methods with the same name as other `lodash` methods */
|
114
82
|
var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
|
115
83
|
nativeFloor = Math.floor,
|
84
|
+
nativeGetPrototypeOf = reNative.test(nativeGetPrototypeOf = Object.getPrototypeOf) && nativeGetPrototypeOf,
|
116
85
|
nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
|
117
86
|
nativeIsFinite = window.isFinite,
|
118
87
|
nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
|
@@ -237,31 +206,6 @@
|
|
237
206
|
cloneableClasses[numberClass] = cloneableClasses[objectClass] = cloneableClasses[regexpClass] =
|
238
207
|
cloneableClasses[stringClass] = true;
|
239
208
|
|
240
|
-
/**
|
241
|
-
* Used to convert characters to HTML entities:
|
242
|
-
*
|
243
|
-
* Though the `>` character is escaped for symmetry, characters like `>` and `/`
|
244
|
-
* don't require escaping in HTML and have no special meaning unless they're part
|
245
|
-
* of a tag or an unquoted attribute value.
|
246
|
-
* http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
|
247
|
-
*/
|
248
|
-
var htmlEscapes = {
|
249
|
-
'&': '&',
|
250
|
-
'<': '<',
|
251
|
-
'>': '>',
|
252
|
-
'"': '"',
|
253
|
-
"'": '''
|
254
|
-
};
|
255
|
-
|
256
|
-
/** Used to convert HTML entities to characters */
|
257
|
-
var htmlUnescapes = {
|
258
|
-
'&': '&',
|
259
|
-
'<': '<',
|
260
|
-
'>': '>',
|
261
|
-
'"': '"',
|
262
|
-
''': "'"
|
263
|
-
};
|
264
|
-
|
265
209
|
/** Used to determine if values are of the language type Object */
|
266
210
|
var objectTypes = {
|
267
211
|
'boolean': false,
|
@@ -291,26 +235,18 @@
|
|
291
235
|
*
|
292
236
|
* @name _
|
293
237
|
* @constructor
|
294
|
-
* @param {Mixed} value The value to wrap in a `
|
295
|
-
* @returns {Object} Returns a `
|
238
|
+
* @param {Mixed} value The value to wrap in a `lodash` instance.
|
239
|
+
* @returns {Object} Returns a `lodash` instance.
|
296
240
|
*/
|
297
241
|
function lodash(value) {
|
298
|
-
// allow invoking `lodash` without the `new` operator
|
299
|
-
return new LoDash(value);
|
300
|
-
}
|
301
|
-
|
302
|
-
/**
|
303
|
-
* Creates a `LoDash` instance that wraps a value to allow chaining.
|
304
|
-
*
|
305
|
-
* @private
|
306
|
-
* @constructor
|
307
|
-
* @param {Mixed} value The value to wrap.
|
308
|
-
*/
|
309
|
-
function LoDash(value) {
|
310
242
|
// exit early if already wrapped
|
311
243
|
if (value && value.__wrapped__) {
|
312
244
|
return value;
|
313
245
|
}
|
246
|
+
// allow invoking `lodash` without the `new` operator
|
247
|
+
if (!(this instanceof lodash)) {
|
248
|
+
return new lodash(value);
|
249
|
+
}
|
314
250
|
this.__wrapped__ = value;
|
315
251
|
}
|
316
252
|
|
@@ -379,15 +315,15 @@
|
|
379
315
|
'var index, value, iteratee = <%= firstArg %>, ' +
|
380
316
|
// assign the `result` variable an initial value
|
381
317
|
'result<% if (init) { %> = <%= init %><% } %>;\n' +
|
382
|
-
//
|
383
|
-
'
|
384
|
-
// add code
|
318
|
+
// exit early if the first argument is falsey
|
319
|
+
'if (!<%= firstArg %>) return result;\n' +
|
320
|
+
// add code before the iteration branches
|
385
321
|
'<%= top %>;\n' +
|
386
322
|
|
387
323
|
// the following branch is for iterating arrays and array-like objects
|
388
324
|
'<% if (arrayBranch) { %>' +
|
389
325
|
'var length = iteratee.length; index = -1;' +
|
390
|
-
' <% if (objectBranch) { %>\nif (length
|
326
|
+
' <% if (objectBranch) { %>\nif (length === +length) {<% } %>' +
|
391
327
|
|
392
328
|
// add support for accessing string characters by index if needed
|
393
329
|
' <% if (noCharByIndex) { %>\n' +
|
@@ -455,8 +391,8 @@
|
|
455
391
|
' %>) {' +
|
456
392
|
' <% } %>\n' +
|
457
393
|
' value = iteratee[index];\n' +
|
458
|
-
' <%= objectBranch.inLoop
|
459
|
-
' <% if (!hasDontEnumBug || useHas) {
|
394
|
+
' <%= objectBranch.inLoop %>;' +
|
395
|
+
' <% if (!hasDontEnumBug || useHas) { %>\n }<% } %>\n' +
|
460
396
|
' }' +
|
461
397
|
' <% } %>' +
|
462
398
|
|
@@ -488,36 +424,22 @@
|
|
488
424
|
|
489
425
|
/**
|
490
426
|
* Reusable iterator options shared by
|
491
|
-
* `every`, `filter`, `find`, `forEach`, `forIn`, `forOwn`, `groupBy`,
|
492
|
-
* `reject`, `some`, and `sortBy`.
|
427
|
+
* `countBy`, `every`, `filter`, `find`, `forEach`, `forIn`, `forOwn`, `groupBy`,
|
428
|
+
* `map`, `reject`, `some`, and `sortBy`.
|
493
429
|
*/
|
494
430
|
var baseIteratorOptions = {
|
495
431
|
'args': 'collection, callback, thisArg',
|
496
432
|
'init': 'collection',
|
497
|
-
'top':
|
498
|
-
'if (!callback) {\n' +
|
499
|
-
' callback = identity\n' +
|
500
|
-
'}\n' +
|
501
|
-
'else if (thisArg) {\n' +
|
502
|
-
' callback = iteratorBind(callback, thisArg)\n' +
|
503
|
-
'}',
|
433
|
+
'top': 'callback = createCallback(callback, thisArg)',
|
504
434
|
'inLoop': 'if (callback(value, index, collection) === false) return result'
|
505
435
|
};
|
506
436
|
|
507
437
|
/** Reusable iterator options for `countBy`, `groupBy`, and `sortBy` */
|
508
438
|
var countByIteratorOptions = {
|
509
439
|
'init': '{}',
|
510
|
-
'top':
|
511
|
-
'var prop;\n' +
|
512
|
-
'if (typeof callback != \'function\') {\n' +
|
513
|
-
' var valueProp = callback;\n' +
|
514
|
-
' callback = function(value) { return value[valueProp] }\n' +
|
515
|
-
'}\n' +
|
516
|
-
'else if (thisArg) {\n' +
|
517
|
-
' callback = iteratorBind(callback, thisArg)\n' +
|
518
|
-
'}',
|
440
|
+
'top': 'callback = createCallback(callback, thisArg)',
|
519
441
|
'inLoop':
|
520
|
-
'prop = callback(value, index, collection);\n' +
|
442
|
+
'var prop = callback(value, index, collection);\n' +
|
521
443
|
'(hasOwnProperty.call(result, prop) ? result[prop]++ : result[prop] = 1)'
|
522
444
|
};
|
523
445
|
|
@@ -548,7 +470,7 @@
|
|
548
470
|
|
549
471
|
/** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */
|
550
472
|
var forEachIteratorOptions = {
|
551
|
-
'top': '
|
473
|
+
'top': 'callback = createCallback(callback, thisArg)'
|
552
474
|
};
|
553
475
|
|
554
476
|
/** Reusable iterator options for `forIn` and `forOwn` */
|
@@ -560,8 +482,7 @@
|
|
560
482
|
|
561
483
|
/** Reusable iterator options for `invoke`, `map`, `pluck`, and `sortBy` */
|
562
484
|
var mapIteratorOptions = {
|
563
|
-
'init':
|
564
|
-
'exit': 'if (!collection) return []',
|
485
|
+
'init': false,
|
565
486
|
'beforeLoop': {
|
566
487
|
'array': 'result = Array(length)',
|
567
488
|
'object': 'result = ' + (isKeysFast ? 'Array(length)' : '[]')
|
@@ -579,11 +500,8 @@
|
|
579
500
|
'init': '{}',
|
580
501
|
'top':
|
581
502
|
'var isFunc = typeof callback == \'function\';\n' +
|
582
|
-
'if (
|
583
|
-
'
|
584
|
-
'} else if (thisArg) {\n' +
|
585
|
-
' callback = iteratorBind(callback, thisArg)\n' +
|
586
|
-
'}',
|
503
|
+
'if (isFunc) callback = createCallback(callback, thisArg);\n' +
|
504
|
+
'else var props = concat.apply(ArrayProto, arguments)',
|
587
505
|
'inLoop':
|
588
506
|
'if (isFunc\n' +
|
589
507
|
' ? !callback(value, index, object)\n' +
|
@@ -594,7 +512,7 @@
|
|
594
512
|
/*--------------------------------------------------------------------------*/
|
595
513
|
|
596
514
|
/**
|
597
|
-
* Creates a
|
515
|
+
* Creates a function optimized for searching large arrays for a given `value`,
|
598
516
|
* starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
|
599
517
|
*
|
600
518
|
* @private
|
@@ -632,6 +550,114 @@
|
|
632
550
|
}
|
633
551
|
}
|
634
552
|
|
553
|
+
/**
|
554
|
+
* Used by `sortBy` to compare transformed `collection` values, stable sorting
|
555
|
+
* them in ascending order.
|
556
|
+
*
|
557
|
+
* @private
|
558
|
+
* @param {Object} a The object to compare to `b`.
|
559
|
+
* @param {Object} b The object to compare to `a`.
|
560
|
+
* @returns {Number} Returns the sort order indicator of `1` or `-1`.
|
561
|
+
*/
|
562
|
+
function compareAscending(a, b) {
|
563
|
+
var ai = a.index,
|
564
|
+
bi = b.index;
|
565
|
+
|
566
|
+
a = a.criteria;
|
567
|
+
b = b.criteria;
|
568
|
+
|
569
|
+
// ensure a stable sort in V8 and other engines
|
570
|
+
// http://code.google.com/p/v8/issues/detail?id=90
|
571
|
+
if (a !== b) {
|
572
|
+
if (a > b || a === undefined) {
|
573
|
+
return 1;
|
574
|
+
}
|
575
|
+
if (a < b || b === undefined) {
|
576
|
+
return -1;
|
577
|
+
}
|
578
|
+
}
|
579
|
+
return ai < bi ? -1 : 1;
|
580
|
+
}
|
581
|
+
|
582
|
+
/**
|
583
|
+
* Creates a function that, when called, invokes `func` with the `this`
|
584
|
+
* binding of `thisArg` and prepends any `partailArgs` to the arguments passed
|
585
|
+
* to the bound function.
|
586
|
+
*
|
587
|
+
* @private
|
588
|
+
* @param {Function|String} func The function to bind or the method name.
|
589
|
+
* @param {Mixed} [thisArg] The `this` binding of `func`.
|
590
|
+
* @param {Array} partialArgs An array of arguments to be partially applied.
|
591
|
+
* @returns {Function} Returns the new bound function.
|
592
|
+
*/
|
593
|
+
function createBound(func, thisArg, partialArgs) {
|
594
|
+
var isFunc = isFunction(func),
|
595
|
+
isPartial = !partialArgs,
|
596
|
+
methodName = func;
|
597
|
+
|
598
|
+
// juggle arguments
|
599
|
+
if (isPartial) {
|
600
|
+
partialArgs = thisArg;
|
601
|
+
}
|
602
|
+
|
603
|
+
function bound() {
|
604
|
+
// `Function#bind` spec
|
605
|
+
// http://es5.github.com/#x15.3.4.5
|
606
|
+
var args = arguments,
|
607
|
+
thisBinding = isPartial ? this : thisArg;
|
608
|
+
|
609
|
+
if (!isFunc) {
|
610
|
+
func = thisArg[methodName];
|
611
|
+
}
|
612
|
+
if (partialArgs.length) {
|
613
|
+
args = args.length
|
614
|
+
? partialArgs.concat(slice.call(args))
|
615
|
+
: partialArgs;
|
616
|
+
}
|
617
|
+
if (this instanceof bound) {
|
618
|
+
// get `func` instance if `bound` is invoked in a `new` expression
|
619
|
+
noop.prototype = func.prototype;
|
620
|
+
thisBinding = new noop;
|
621
|
+
|
622
|
+
// mimic the constructor's `return` behavior
|
623
|
+
// http://es5.github.com/#x13.2.2
|
624
|
+
var result = func.apply(thisBinding, args);
|
625
|
+
return result && objectTypes[typeof result]
|
626
|
+
? result
|
627
|
+
: thisBinding
|
628
|
+
}
|
629
|
+
return func.apply(thisBinding, args);
|
630
|
+
}
|
631
|
+
return bound;
|
632
|
+
}
|
633
|
+
|
634
|
+
/**
|
635
|
+
* Produces an iteration callback bound to an optional `thisArg`. If `func` is
|
636
|
+
* a property name, the callback will return the property value for a given element.
|
637
|
+
*
|
638
|
+
* @private
|
639
|
+
* @param {Function|String} [func=identity|property] The function called per
|
640
|
+
* iteration or property name to query.
|
641
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
642
|
+
* @returns {Function} Returns a callback function.
|
643
|
+
*/
|
644
|
+
function createCallback(func, thisArg) {
|
645
|
+
if (!func) {
|
646
|
+
return identity;
|
647
|
+
}
|
648
|
+
if (typeof func != 'function') {
|
649
|
+
return function(object) {
|
650
|
+
return object[func];
|
651
|
+
};
|
652
|
+
}
|
653
|
+
if (thisArg !== undefined) {
|
654
|
+
return function(value, index, object) {
|
655
|
+
return func.call(thisArg, value, index, object);
|
656
|
+
};
|
657
|
+
}
|
658
|
+
return func;
|
659
|
+
}
|
660
|
+
|
635
661
|
/**
|
636
662
|
* Creates compiled iteration functions. The iteration function will be created
|
637
663
|
* to iterate over only objects if the first argument of `options.args` is
|
@@ -646,16 +672,11 @@
|
|
646
672
|
* useStrict - A boolean to specify whether or not to include the ES5
|
647
673
|
* "use strict" directive.
|
648
674
|
*
|
649
|
-
* args - A string of comma separated arguments the iteration function will
|
650
|
-
* accept.
|
675
|
+
* args - A string of comma separated arguments the iteration function will accept.
|
651
676
|
*
|
652
677
|
* init - A string to specify the initial value of the `result` variable.
|
653
678
|
*
|
654
|
-
*
|
655
|
-
* of `if (!arguments[0]) return result`.
|
656
|
-
*
|
657
|
-
* top - A string of code to execute after the exit-early check but before
|
658
|
-
* the iteration branches.
|
679
|
+
* top - A string of code to execute before the iteration branches.
|
659
680
|
*
|
660
681
|
* beforeLoop - A string or object containing an "array" or "object" property
|
661
682
|
* of code to execute before the array or object loops.
|
@@ -669,33 +690,35 @@
|
|
669
690
|
* @returns {Function} Returns the compiled function.
|
670
691
|
*/
|
671
692
|
function createIterator() {
|
672
|
-
var
|
673
|
-
prop,
|
674
|
-
value,
|
675
|
-
index = -1,
|
693
|
+
var index = -1,
|
676
694
|
length = arguments.length;
|
677
695
|
|
678
696
|
// merge options into a template data object
|
679
697
|
var data = {
|
680
698
|
'bottom': '',
|
681
|
-
'
|
682
|
-
'
|
699
|
+
'hasDontEnumBug': hasDontEnumBug,
|
700
|
+
'isKeysFast': isKeysFast,
|
701
|
+
'noArgsEnum': noArgsEnum,
|
702
|
+
'noCharByIndex': noCharByIndex,
|
703
|
+
'shadowed': shadowed,
|
683
704
|
'top': '',
|
684
|
-
'
|
685
|
-
'
|
705
|
+
'useHas': true,
|
706
|
+
'useStrict': isStrictFast,
|
707
|
+
'arrayBranch': {},
|
708
|
+
'objectBranch': {}
|
686
709
|
};
|
687
710
|
|
688
711
|
while (++index < length) {
|
689
|
-
object = arguments[index];
|
690
|
-
for (prop in object) {
|
691
|
-
|
712
|
+
var object = arguments[index];
|
713
|
+
for (var prop in object) {
|
714
|
+
var value = object[prop];
|
692
715
|
// keep this regexp explicit for the build pre-process
|
693
716
|
if (/beforeLoop|inLoop/.test(prop)) {
|
694
717
|
if (typeof value == 'string') {
|
695
718
|
value = { 'array': value, 'object': value };
|
696
719
|
}
|
697
|
-
data.arrayBranch[prop] = value.array
|
698
|
-
data.objectBranch[prop] = value.object
|
720
|
+
data.arrayBranch[prop] = value.array;
|
721
|
+
data.objectBranch[prop] = value.object;
|
699
722
|
} else {
|
700
723
|
data[prop] = value;
|
701
724
|
}
|
@@ -704,84 +727,32 @@
|
|
704
727
|
// set additional template `data` values
|
705
728
|
var args = data.args,
|
706
729
|
firstArg = /^[^,]+/.exec(args)[0],
|
707
|
-
|
730
|
+
init = data.init;
|
708
731
|
|
709
732
|
data.firstArg = firstArg;
|
710
|
-
data.
|
711
|
-
|
712
|
-
data.noArgsEnum = noArgsEnum;
|
713
|
-
data.shadowed = shadowed;
|
714
|
-
data.useHas = data.useHas !== false;
|
715
|
-
data.useStrict = useStrict == null ? isStrictFast : useStrict;
|
716
|
-
|
717
|
-
if (data.noCharByIndex == null) {
|
718
|
-
data.noCharByIndex = noCharByIndex;
|
719
|
-
}
|
720
|
-
if (!data.exit) {
|
721
|
-
data.exit = 'if (!' + firstArg + ') return result';
|
722
|
-
}
|
733
|
+
data.init = init == null ? firstArg : init;
|
734
|
+
|
723
735
|
if (firstArg != 'collection' || !data.arrayBranch.inLoop) {
|
724
736
|
data.arrayBranch = null;
|
725
737
|
}
|
726
738
|
// create the function factory
|
727
739
|
var factory = Function(
|
728
|
-
'arrayLikeClasses, ArrayProto, bind, compareAscending, concat,
|
729
|
-
'
|
730
|
-
'isPlainObject,
|
731
|
-
'
|
740
|
+
'arrayLikeClasses, ArrayProto, bind, compareAscending, concat, createCallback, ' +
|
741
|
+
'forIn, hasOwnProperty, indexOf, isArguments, isArray, isFunction, ' +
|
742
|
+
'isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, ' +
|
743
|
+
'slice, stringClass, toString, undefined',
|
732
744
|
'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' +
|
733
745
|
'return callee'
|
734
746
|
);
|
735
747
|
// return the compiled function
|
736
748
|
return factory(
|
737
|
-
arrayLikeClasses, ArrayProto, bind, compareAscending, concat,
|
738
|
-
|
739
|
-
isPlainObject,
|
740
|
-
|
749
|
+
arrayLikeClasses, ArrayProto, bind, compareAscending, concat, createCallback,
|
750
|
+
forIn, hasOwnProperty, indexOf, isArguments, isArray, isFunction,
|
751
|
+
isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable,
|
752
|
+
slice, stringClass, toString
|
741
753
|
);
|
742
754
|
}
|
743
755
|
|
744
|
-
/**
|
745
|
-
* Used by `sortBy` to compare transformed `collection` values, stable sorting
|
746
|
-
* them in ascending order.
|
747
|
-
*
|
748
|
-
* @private
|
749
|
-
* @param {Object} a The object to compare to `b`.
|
750
|
-
* @param {Object} b The object to compare to `a`.
|
751
|
-
* @returns {Number} Returns the sort order indicator of `1` or `-1`.
|
752
|
-
*/
|
753
|
-
function compareAscending(a, b) {
|
754
|
-
var ai = a.index,
|
755
|
-
bi = b.index;
|
756
|
-
|
757
|
-
a = a.criteria;
|
758
|
-
b = b.criteria;
|
759
|
-
|
760
|
-
// ensure a stable sort in V8 and other engines
|
761
|
-
// http://code.google.com/p/v8/issues/detail?id=90
|
762
|
-
if (a !== b) {
|
763
|
-
if (a > b || a === undefined) {
|
764
|
-
return 1;
|
765
|
-
}
|
766
|
-
if (a < b || b === undefined) {
|
767
|
-
return -1;
|
768
|
-
}
|
769
|
-
}
|
770
|
-
return ai < bi ? -1 : 1;
|
771
|
-
}
|
772
|
-
|
773
|
-
/**
|
774
|
-
* Used by `template` to replace tokens with their corresponding code snippets.
|
775
|
-
*
|
776
|
-
* @private
|
777
|
-
* @param {String} match The matched token.
|
778
|
-
* @param {String} index The `tokenized` index of the code snippet.
|
779
|
-
* @returns {String} Returns the code snippet.
|
780
|
-
*/
|
781
|
-
function detokenize(match, index) {
|
782
|
-
return tokenized[index];
|
783
|
-
}
|
784
|
-
|
785
756
|
/**
|
786
757
|
* Used by `template` to escape characters for inclusion in compiled
|
787
758
|
* string literals.
|
@@ -805,21 +776,6 @@
|
|
805
776
|
return htmlEscapes[match];
|
806
777
|
}
|
807
778
|
|
808
|
-
/**
|
809
|
-
* Creates a new function that, when called, invokes `func` with the `this`
|
810
|
-
* binding of `thisArg` and the arguments (value, index, object).
|
811
|
-
*
|
812
|
-
* @private
|
813
|
-
* @param {Function} func The function to bind.
|
814
|
-
* @param {Mixed} [thisArg] The `this` binding of `func`.
|
815
|
-
* @returns {Function} Returns the new bound function.
|
816
|
-
*/
|
817
|
-
function iteratorBind(func, thisArg) {
|
818
|
-
return function(value, index, object) {
|
819
|
-
return func.call(thisArg, value, index, object);
|
820
|
-
};
|
821
|
-
}
|
822
|
-
|
823
779
|
/**
|
824
780
|
* A no-operation function.
|
825
781
|
*
|
@@ -829,62 +785,6 @@
|
|
829
785
|
// no operation performed
|
830
786
|
}
|
831
787
|
|
832
|
-
/**
|
833
|
-
* Used by `template` to replace "escape" template delimiters with tokens.
|
834
|
-
*
|
835
|
-
* @private
|
836
|
-
* @param {String} match The matched template delimiter.
|
837
|
-
* @param {String} value The delimiter value.
|
838
|
-
* @returns {String} Returns a token.
|
839
|
-
*/
|
840
|
-
function tokenizeEscape(match, value) {
|
841
|
-
if (match && reComplexDelimiter.test(value)) {
|
842
|
-
return '<e%-' + value + '%>';
|
843
|
-
}
|
844
|
-
var index = tokenized.length;
|
845
|
-
tokenized[index] = "' +\n__e(" + value + ") +\n'";
|
846
|
-
return tokenHead + index + tokenFoot;
|
847
|
-
}
|
848
|
-
|
849
|
-
/**
|
850
|
-
* Used by `template` to replace "evaluate" template delimiters, or complex
|
851
|
-
* "escape" and "interpolate" delimiters, with tokens.
|
852
|
-
*
|
853
|
-
* @private
|
854
|
-
* @param {String} match The matched template delimiter.
|
855
|
-
* @param {String} escapeValue The complex "escape" delimiter value.
|
856
|
-
* @param {String} interpolateValue The complex "interpolate" delimiter value.
|
857
|
-
* @param {String} [evaluateValue] The "evaluate" delimiter value.
|
858
|
-
* @returns {String} Returns a token.
|
859
|
-
*/
|
860
|
-
function tokenizeEvaluate(match, escapeValue, interpolateValue, evaluateValue) {
|
861
|
-
if (evaluateValue) {
|
862
|
-
var index = tokenized.length;
|
863
|
-
tokenized[index] = "';\n" + evaluateValue + ";\n__p += '";
|
864
|
-
return tokenHead + index + tokenFoot;
|
865
|
-
}
|
866
|
-
return escapeValue
|
867
|
-
? tokenizeEscape(null, escapeValue)
|
868
|
-
: tokenizeInterpolate(null, interpolateValue);
|
869
|
-
}
|
870
|
-
|
871
|
-
/**
|
872
|
-
* Used by `template` to replace "interpolate" template delimiters with tokens.
|
873
|
-
*
|
874
|
-
* @private
|
875
|
-
* @param {String} match The matched template delimiter.
|
876
|
-
* @param {String} value The delimiter value.
|
877
|
-
* @returns {String} Returns a token.
|
878
|
-
*/
|
879
|
-
function tokenizeInterpolate(match, value) {
|
880
|
-
if (match && reComplexDelimiter.test(value)) {
|
881
|
-
return '<e%=' + value + '%>';
|
882
|
-
}
|
883
|
-
var index = tokenized.length;
|
884
|
-
tokenized[index] = "' +\n((__t = (" + value + ")) == null ? '' : __t) +\n'";
|
885
|
-
return tokenHead + index + tokenFoot;
|
886
|
-
}
|
887
|
-
|
888
788
|
/**
|
889
789
|
* Used by `unescape` to convert HTML entities to characters.
|
890
790
|
*
|
@@ -898,6 +798,25 @@
|
|
898
798
|
|
899
799
|
/*--------------------------------------------------------------------------*/
|
900
800
|
|
801
|
+
/**
|
802
|
+
* Creates an object composed of the inverted keys and values of the given `object`.
|
803
|
+
*
|
804
|
+
* @static
|
805
|
+
* @memberOf _
|
806
|
+
* @category Objects
|
807
|
+
* @param {Object} object The object to invert.
|
808
|
+
* @returns {Object} Returns the created inverted object.
|
809
|
+
* @example
|
810
|
+
*
|
811
|
+
* _.invert({ 'first': 'Moe', 'second': 'Larry', 'third': 'Curly' });
|
812
|
+
* // => { 'Moe': 'first', 'Larry': 'second', 'Curly': 'third' } (order is not guaranteed)
|
813
|
+
*/
|
814
|
+
var invert = createIterator({
|
815
|
+
'args': 'object',
|
816
|
+
'init': '{}',
|
817
|
+
'inLoop': 'result[value] = index'
|
818
|
+
});
|
819
|
+
|
901
820
|
/**
|
902
821
|
* Checks if `value` is an `arguments` object.
|
903
822
|
*
|
@@ -920,7 +839,7 @@
|
|
920
839
|
// fallback for browsers that can't detect `arguments` objects by [[Class]]
|
921
840
|
if (noArgsClass) {
|
922
841
|
isArguments = function(value) {
|
923
|
-
return
|
842
|
+
return value ? hasOwnProperty.call(value, 'callee') : false;
|
924
843
|
};
|
925
844
|
}
|
926
845
|
|
@@ -954,7 +873,7 @@
|
|
954
873
|
* @returns {Boolean} Returns `true` if the `value` is a function, else `false`.
|
955
874
|
* @example
|
956
875
|
*
|
957
|
-
* _.isFunction(
|
876
|
+
* _.isFunction(_);
|
958
877
|
* // => true
|
959
878
|
*/
|
960
879
|
function isFunction(value) {
|
@@ -967,6 +886,42 @@
|
|
967
886
|
};
|
968
887
|
}
|
969
888
|
|
889
|
+
/**
|
890
|
+
* Checks if a given `value` is an object created by the `Object` constructor.
|
891
|
+
*
|
892
|
+
* @static
|
893
|
+
* @memberOf _
|
894
|
+
* @category Objects
|
895
|
+
* @param {Mixed} value The value to check.
|
896
|
+
* @returns {Boolean} Returns `true` if `value` is a plain object, else `false`.
|
897
|
+
* @example
|
898
|
+
*
|
899
|
+
* function Stooge(name, age) {
|
900
|
+
* this.name = name;
|
901
|
+
* this.age = age;
|
902
|
+
* }
|
903
|
+
*
|
904
|
+
* _.isPlainObject(new Stooge('moe', 40));
|
905
|
+
* // false
|
906
|
+
*
|
907
|
+
* _.isPlainObject([1, 2, 3]);
|
908
|
+
* // false
|
909
|
+
*
|
910
|
+
* _.isPlainObject({ 'name': 'moe', 'age': 40 });
|
911
|
+
* // => true
|
912
|
+
*/
|
913
|
+
var isPlainObject = !nativeGetPrototypeOf ? isPlainFallback : function(value) {
|
914
|
+
if (!(value && typeof value == 'object')) {
|
915
|
+
return false;
|
916
|
+
}
|
917
|
+
var valueOf = value.valueOf,
|
918
|
+
objProto = typeof valueOf == 'function' && (objProto = nativeGetPrototypeOf(valueOf)) && nativeGetPrototypeOf(objProto);
|
919
|
+
|
920
|
+
return objProto
|
921
|
+
? value == objProto || (nativeGetPrototypeOf(value) == objProto && !isArguments(value))
|
922
|
+
: isPlainFallback(value);
|
923
|
+
};
|
924
|
+
|
970
925
|
/**
|
971
926
|
* A fallback implementation of `isPlainObject` that checks if a given `value`
|
972
927
|
* is an object created by the `Object` constructor, assuming objects created
|
@@ -975,14 +930,12 @@
|
|
975
930
|
*
|
976
931
|
* @private
|
977
932
|
* @param {Mixed} value The value to check.
|
978
|
-
* @param {Boolean} [skipArgsCheck=false] Internally used to skip checks for
|
979
|
-
* `arguments` objects.
|
980
933
|
* @returns {Boolean} Returns `true` if `value` is a plain object, else `false`.
|
981
934
|
*/
|
982
|
-
function isPlainFallback(value
|
935
|
+
function isPlainFallback(value) {
|
983
936
|
// avoid non-objects and false positives for `arguments` objects
|
984
937
|
var result = false;
|
985
|
-
if (!(value && typeof value == 'object') ||
|
938
|
+
if (!(value && typeof value == 'object') || isArguments(value)) {
|
986
939
|
return result;
|
987
940
|
}
|
988
941
|
// IE < 9 presents DOM nodes as `Object` objects except they have `toString`
|
@@ -1012,27 +965,6 @@
|
|
1012
965
|
return result;
|
1013
966
|
}
|
1014
967
|
|
1015
|
-
/**
|
1016
|
-
* Checks if a given `value` is an object created by the `Object` constructor.
|
1017
|
-
*
|
1018
|
-
* @private
|
1019
|
-
* @param {Mixed} value The value to check.
|
1020
|
-
* @param {Boolean} [skipArgsCheck=false] Internally used to skip checks for
|
1021
|
-
* `arguments` objects.
|
1022
|
-
* @returns {Boolean} Returns `true` if `value` is a plain object, else `false`.
|
1023
|
-
*/
|
1024
|
-
var isPlainObject = objectTypes.__proto__ != ObjectProto ? isPlainFallback : function(value, skipArgsCheck) {
|
1025
|
-
if (!value) {
|
1026
|
-
return false;
|
1027
|
-
}
|
1028
|
-
var valueOf = value.valueOf,
|
1029
|
-
objProto = typeof valueOf == 'function' && (objProto = valueOf.__proto__) && objProto.__proto__;
|
1030
|
-
|
1031
|
-
return objProto
|
1032
|
-
? value == objProto || (value.__proto__ == objProto && (skipArgsCheck || !isArguments(value)))
|
1033
|
-
: isPlainFallback(value);
|
1034
|
-
};
|
1035
|
-
|
1036
968
|
/**
|
1037
969
|
* A shim implementation of `Object.keys` that produces an array of the given
|
1038
970
|
* object's own enumerable property names.
|
@@ -1047,25 +979,43 @@
|
|
1047
979
|
'inLoop': 'result.push(index)'
|
1048
980
|
});
|
1049
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
|
+
'&': '&',
|
992
|
+
'<': '<',
|
993
|
+
'>': '>',
|
994
|
+
'"': '"',
|
995
|
+
"'": '''
|
996
|
+
};
|
997
|
+
|
998
|
+
/** Used to convert HTML entities to characters */
|
999
|
+
var htmlUnescapes = invert(htmlEscapes);
|
1000
|
+
|
1050
1001
|
/*--------------------------------------------------------------------------*/
|
1051
1002
|
|
1052
1003
|
/**
|
1053
1004
|
* Creates a clone of `value`. If `deep` is `true`, all nested objects will
|
1054
|
-
* also be cloned otherwise they will be assigned by reference.
|
1055
|
-
*
|
1056
|
-
* `
|
1057
|
-
* are **not** cloned unless they have a custom `clone` method.
|
1005
|
+
* also be cloned otherwise they will be assigned by reference. Functions, DOM
|
1006
|
+
* nodes, `arguments` objects, and objects created by constructors other than
|
1007
|
+
* `Object` are **not** cloned.
|
1058
1008
|
*
|
1059
1009
|
* @static
|
1060
1010
|
* @memberOf _
|
1061
1011
|
* @category Objects
|
1062
1012
|
* @param {Mixed} value The value to clone.
|
1063
1013
|
* @param {Boolean} deep A flag to indicate a deep clone.
|
1064
|
-
* @param {Object} [guard] Internally used to allow this method to work with
|
1014
|
+
* @param- {Object} [guard] Internally used to allow this method to work with
|
1065
1015
|
* others like `_.map` without using their callback `index` argument for `deep`.
|
1066
|
-
* @param {
|
1067
|
-
*
|
1068
|
-
*
|
1016
|
+
* @param- {Array} [stackA=[]] Internally used to track traversed source objects.
|
1017
|
+
* @param- {Array} [stackB=[]] Internally used to associate clones with their
|
1018
|
+
* source counterparts.
|
1069
1019
|
* @returns {Mixed} Returns the cloned `value`.
|
1070
1020
|
* @example
|
1071
1021
|
*
|
@@ -1086,28 +1036,15 @@
|
|
1086
1036
|
* shallow[0] === stooges[0];
|
1087
1037
|
* // => false
|
1088
1038
|
*/
|
1089
|
-
function clone(value, deep, guard,
|
1039
|
+
function clone(value, deep, guard, stackA, stackB) {
|
1090
1040
|
if (value == null) {
|
1091
1041
|
return value;
|
1092
1042
|
}
|
1093
1043
|
if (guard) {
|
1094
1044
|
deep = false;
|
1095
1045
|
}
|
1096
|
-
// init internal data
|
1097
|
-
data || (data = { 'thorough': null });
|
1098
|
-
|
1099
|
-
// avoid slower checks on primitives
|
1100
|
-
if (data.thorough == null) {
|
1101
|
-
// primitives passed from iframes use the primary document's native prototypes
|
1102
|
-
data.thorough = !!(BoolProto.clone || NumberProto.clone || StringProto.clone);
|
1103
|
-
}
|
1104
|
-
// use custom `clone` method if available
|
1105
|
-
var isObj = objectTypes[typeof value];
|
1106
|
-
if ((isObj || data.thorough) && value.clone && isFunction(value.clone)) {
|
1107
|
-
data.thorough = null;
|
1108
|
-
return value.clone(deep);
|
1109
|
-
}
|
1110
1046
|
// inspect [[Class]]
|
1047
|
+
var isObj = objectTypes[typeof value];
|
1111
1048
|
if (isObj) {
|
1112
1049
|
// don't clone `arguments` objects, functions, or non-object Objects
|
1113
1050
|
var className = toString.call(value);
|
@@ -1115,7 +1052,7 @@
|
|
1115
1052
|
return value;
|
1116
1053
|
}
|
1117
1054
|
var isArr = className == arrayClass;
|
1118
|
-
isObj = isArr || (className == objectClass ? isPlainObject(value
|
1055
|
+
isObj = isArr || (className == objectClass ? isPlainObject(value) : isObj);
|
1119
1056
|
}
|
1120
1057
|
// shallow clone
|
1121
1058
|
if (!isObj || !deep) {
|
@@ -1141,33 +1078,34 @@
|
|
1141
1078
|
return ctor(value.source, reFlags.exec(value));
|
1142
1079
|
}
|
1143
1080
|
|
1144
|
-
var clones = data.clones || (data.clones = []),
|
1145
|
-
sources = data.sources || (data.sources = []),
|
1146
|
-
length = clones.length;
|
1147
|
-
|
1148
1081
|
// check for circular references and return corresponding clone
|
1082
|
+
stackA || (stackA = []);
|
1083
|
+
stackB || (stackB = []);
|
1084
|
+
|
1085
|
+
var length = stackA.length;
|
1149
1086
|
while (length--) {
|
1150
|
-
if (
|
1151
|
-
return
|
1087
|
+
if (stackA[length] == value) {
|
1088
|
+
return stackB[length];
|
1152
1089
|
}
|
1153
1090
|
}
|
1154
1091
|
|
1155
1092
|
// init cloned object
|
1156
1093
|
var result = isArr ? ctor(length = value.length) : {};
|
1157
1094
|
|
1158
|
-
// add
|
1159
|
-
|
1160
|
-
|
1095
|
+
// add the source value to the stack of traversed objects
|
1096
|
+
// and associate it with its clone
|
1097
|
+
stackA.push(value);
|
1098
|
+
stackB.push(result);
|
1161
1099
|
|
1162
1100
|
// recursively populate clone (susceptible to call stack limits)
|
1163
1101
|
if (isArr) {
|
1164
1102
|
var index = -1;
|
1165
1103
|
while (++index < length) {
|
1166
|
-
result[index] = clone(value[index], deep, null,
|
1104
|
+
result[index] = clone(value[index], deep, null, stackA, stackB);
|
1167
1105
|
}
|
1168
1106
|
} else {
|
1169
1107
|
forOwn(value, function(objValue, key) {
|
1170
|
-
result[key] = clone(objValue, deep, null,
|
1108
|
+
result[key] = clone(objValue, deep, null, stackA, stackB);
|
1171
1109
|
});
|
1172
1110
|
}
|
1173
1111
|
return result;
|
@@ -1216,7 +1154,7 @@
|
|
1216
1154
|
/**
|
1217
1155
|
* Iterates over `object`'s own and inherited enumerable properties, executing
|
1218
1156
|
* the `callback` for each property. The `callback` is bound to `thisArg` and
|
1219
|
-
* invoked with
|
1157
|
+
* invoked with three arguments; (value, key, object). Callbacks may exit iteration
|
1220
1158
|
* early by explicitly returning `false`.
|
1221
1159
|
*
|
1222
1160
|
* @static
|
@@ -1224,7 +1162,7 @@
|
|
1224
1162
|
* @category Objects
|
1225
1163
|
* @param {Object} object The object to iterate over.
|
1226
1164
|
* @param {Function} callback The function called per iteration.
|
1227
|
-
* @param {Mixed} [thisArg] The `this` binding
|
1165
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1228
1166
|
* @returns {Object} Returns `object`.
|
1229
1167
|
* @example
|
1230
1168
|
*
|
@@ -1247,16 +1185,16 @@
|
|
1247
1185
|
|
1248
1186
|
/**
|
1249
1187
|
* Iterates over `object`'s own enumerable properties, executing the `callback`
|
1250
|
-
* for each property. The `callback` is bound to `thisArg` and invoked with
|
1251
|
-
* arguments; (value, key, object). Callbacks may exit iteration early by
|
1252
|
-
*
|
1188
|
+
* for each property. The `callback` is bound to `thisArg` and invoked with three
|
1189
|
+
* arguments; (value, key, object). Callbacks may exit iteration early by explicitly
|
1190
|
+
* returning `false`.
|
1253
1191
|
*
|
1254
1192
|
* @static
|
1255
1193
|
* @memberOf _
|
1256
1194
|
* @category Objects
|
1257
1195
|
* @param {Object} object The object to iterate over.
|
1258
1196
|
* @param {Function} callback The function called per iteration.
|
1259
|
-
* @param {Mixed} [thisArg] The `this` binding
|
1197
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1260
1198
|
* @returns {Object} Returns `object`.
|
1261
1199
|
* @example
|
1262
1200
|
*
|
@@ -1298,35 +1236,16 @@
|
|
1298
1236
|
* @memberOf _
|
1299
1237
|
* @category Objects
|
1300
1238
|
* @param {Object} object The object to check.
|
1301
|
-
* @param {String} property The property to check for.
|
1302
|
-
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
|
1303
|
-
* @example
|
1304
|
-
*
|
1305
|
-
* _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
|
1306
|
-
* // => true
|
1307
|
-
*/
|
1308
|
-
function has(object, property) {
|
1309
|
-
return object ? hasOwnProperty.call(object, property) : false;
|
1310
|
-
}
|
1311
|
-
|
1312
|
-
/**
|
1313
|
-
* Creates an object composed of the inverted keys and values of the given `object`.
|
1314
|
-
*
|
1315
|
-
* @static
|
1316
|
-
* @memberOf _
|
1317
|
-
* @category Objects
|
1318
|
-
* @param {Object} object The object to invert.
|
1319
|
-
* @returns {Object} Returns the created inverted object.
|
1239
|
+
* @param {String} property The property to check for.
|
1240
|
+
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
|
1320
1241
|
* @example
|
1321
1242
|
*
|
1322
|
-
*
|
1323
|
-
* // =>
|
1243
|
+
* _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
|
1244
|
+
* // => true
|
1324
1245
|
*/
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
'inLoop': 'result[value] = index'
|
1329
|
-
});
|
1246
|
+
function has(object, property) {
|
1247
|
+
return object ? hasOwnProperty.call(object, property) : false;
|
1248
|
+
}
|
1330
1249
|
|
1331
1250
|
/**
|
1332
1251
|
* Checks if `value` is a boolean (`true` or `false`) value.
|
@@ -1408,7 +1327,7 @@
|
|
1408
1327
|
' length = value.length;\n' +
|
1409
1328
|
'if (arrayLikeClasses[className]' +
|
1410
1329
|
(noArgsClass ? ' || isArguments(value)' : '') + ' ||\n' +
|
1411
|
-
' (className == objectClass && length
|
1330
|
+
' (className == objectClass && length === +length &&\n' +
|
1412
1331
|
' isFunction(value.splice))' +
|
1413
1332
|
') return !length',
|
1414
1333
|
'inLoop': {
|
@@ -1418,17 +1337,15 @@
|
|
1418
1337
|
|
1419
1338
|
/**
|
1420
1339
|
* Performs a deep comparison between two values to determine if they are
|
1421
|
-
* equivalent to each other.
|
1422
|
-
* used to perform the comparison.
|
1340
|
+
* equivalent to each other.
|
1423
1341
|
*
|
1424
1342
|
* @static
|
1425
1343
|
* @memberOf _
|
1426
1344
|
* @category Objects
|
1427
1345
|
* @param {Mixed} a The value to compare.
|
1428
1346
|
* @param {Mixed} b The other value to compare.
|
1429
|
-
* @param {Object} [
|
1430
|
-
*
|
1431
|
-
* of non-object values.
|
1347
|
+
* @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
|
1348
|
+
* @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
|
1432
1349
|
* @returns {Boolean} Returns `true` if the values are equvalent, else `false`.
|
1433
1350
|
* @example
|
1434
1351
|
*
|
@@ -1441,39 +1358,21 @@
|
|
1441
1358
|
* _.isEqual(moe, clone);
|
1442
1359
|
* // => true
|
1443
1360
|
*/
|
1444
|
-
function isEqual(a, b,
|
1361
|
+
function isEqual(a, b, stackA, stackB) {
|
1445
1362
|
// a strict comparison is necessary because `null == undefined`
|
1446
1363
|
if (a == null || b == null) {
|
1447
1364
|
return a === b;
|
1448
1365
|
}
|
1449
|
-
// init internal data
|
1450
|
-
data || (data = { 'thorough': null });
|
1451
|
-
|
1452
|
-
// avoid slower checks on non-objects
|
1453
|
-
if (data.thorough == null) {
|
1454
|
-
// primitives passed from iframes use the primary document's native prototypes
|
1455
|
-
data.thorough = !!(BoolProto.isEqual || NumberProto.isEqual || StringProto.isEqual);
|
1456
|
-
}
|
1457
|
-
if (objectTypes[typeof a] || objectTypes[typeof b] || data.thorough) {
|
1458
|
-
// unwrap any LoDash wrapped values
|
1459
|
-
a = a.__wrapped__ || a;
|
1460
|
-
b = b.__wrapped__ || b;
|
1461
|
-
|
1462
|
-
// use custom `isEqual` method if available
|
1463
|
-
if (a.isEqual && isFunction(a.isEqual)) {
|
1464
|
-
data.thorough = null;
|
1465
|
-
return a.isEqual(b);
|
1466
|
-
}
|
1467
|
-
if (b.isEqual && isFunction(b.isEqual)) {
|
1468
|
-
data.thorough = null;
|
1469
|
-
return b.isEqual(a);
|
1470
|
-
}
|
1471
|
-
}
|
1472
1366
|
// exit early for identical values
|
1473
1367
|
if (a === b) {
|
1474
1368
|
// treat `+0` vs. `-0` as not equal
|
1475
1369
|
return a !== 0 || (1 / a == 1 / b);
|
1476
1370
|
}
|
1371
|
+
// unwrap any `lodash` wrapped values
|
1372
|
+
if (objectTypes[typeof a] || objectTypes[typeof b]) {
|
1373
|
+
a = a.__wrapped__ || a;
|
1374
|
+
b = b.__wrapped__ || b;
|
1375
|
+
}
|
1477
1376
|
// compare [[Class]] names
|
1478
1377
|
var className = toString.call(a);
|
1479
1378
|
if (className != toString.call(b)) {
|
@@ -1514,10 +1413,10 @@
|
|
1514
1413
|
// assume cyclic structures are equal
|
1515
1414
|
// the algorithm for detecting cyclic structures is adapted from ES 5.1
|
1516
1415
|
// section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
|
1517
|
-
|
1518
|
-
|
1519
|
-
length = stackA.length;
|
1416
|
+
stackA || (stackA = []);
|
1417
|
+
stackB || (stackB = []);
|
1520
1418
|
|
1419
|
+
var length = stackA.length;
|
1521
1420
|
while (length--) {
|
1522
1421
|
if (stackA[length] == a) {
|
1523
1422
|
return stackB[length] == b;
|
@@ -1541,7 +1440,7 @@
|
|
1541
1440
|
if (result) {
|
1542
1441
|
// deep compare the contents, ignoring non-numeric properties
|
1543
1442
|
while (size--) {
|
1544
|
-
if (!(result = isEqual(a[size], b[size],
|
1443
|
+
if (!(result = isEqual(a[size], b[size], stackA, stackB))) {
|
1545
1444
|
break;
|
1546
1445
|
}
|
1547
1446
|
}
|
@@ -1565,7 +1464,7 @@
|
|
1565
1464
|
// count the number of properties.
|
1566
1465
|
size++;
|
1567
1466
|
// deep compare each property value.
|
1568
|
-
if (!(hasOwnProperty.call(b, prop) && isEqual(a[prop], b[prop],
|
1467
|
+
if (!(hasOwnProperty.call(b, prop) && isEqual(a[prop], b[prop], stackA, stackB))) {
|
1569
1468
|
return false;
|
1570
1469
|
}
|
1571
1470
|
}
|
@@ -1585,7 +1484,7 @@
|
|
1585
1484
|
while (++index < 7) {
|
1586
1485
|
prop = shadowed[index];
|
1587
1486
|
if (hasOwnProperty.call(a, prop) &&
|
1588
|
-
!(hasOwnProperty.call(b, prop) && isEqual(a[prop], b[prop],
|
1487
|
+
!(hasOwnProperty.call(b, prop) && isEqual(a[prop], b[prop], stackA, stackB))) {
|
1589
1488
|
return false;
|
1590
1489
|
}
|
1591
1490
|
}
|
@@ -1634,6 +1533,9 @@
|
|
1634
1533
|
* _.isObject({});
|
1635
1534
|
* // => true
|
1636
1535
|
*
|
1536
|
+
* _.isObject([1, 2, 3]);
|
1537
|
+
* // => true
|
1538
|
+
*
|
1637
1539
|
* _.isObject(1);
|
1638
1540
|
* // => false
|
1639
1541
|
*/
|
@@ -1708,7 +1610,7 @@
|
|
1708
1610
|
* @returns {Boolean} Returns `true` if the `value` is a number, else `false`.
|
1709
1611
|
* @example
|
1710
1612
|
*
|
1711
|
-
* _.isNumber(8.4 * 5;
|
1613
|
+
* _.isNumber(8.4 * 5);
|
1712
1614
|
* // => true
|
1713
1615
|
*/
|
1714
1616
|
function isNumber(value) {
|
@@ -1789,7 +1691,7 @@
|
|
1789
1691
|
}
|
1790
1692
|
return object && objectTypes[type]
|
1791
1693
|
? nativeKeys(object)
|
1792
|
-
|
1694
|
+
: [];
|
1793
1695
|
};
|
1794
1696
|
|
1795
1697
|
/**
|
@@ -1802,10 +1704,11 @@
|
|
1802
1704
|
* @category Objects
|
1803
1705
|
* @param {Object} object The destination object.
|
1804
1706
|
* @param {Object} [source1, source2, ...] The source objects.
|
1805
|
-
* @param {Object} [indicator] Internally used to indicate that the `stack`
|
1707
|
+
* @param- {Object} [indicator] Internally used to indicate that the `stack`
|
1806
1708
|
* argument is an array of traversed objects instead of another source object.
|
1807
|
-
* @param {
|
1808
|
-
*
|
1709
|
+
* @param- {Array} [stackA=[]] Internally used to track traversed source objects.
|
1710
|
+
* @param- {Array} [stackB=[]] Internally used to associate clones with their
|
1711
|
+
* source counterparts.
|
1809
1712
|
* @returns {Object} Returns the destination object.
|
1810
1713
|
* @example
|
1811
1714
|
*
|
@@ -1825,25 +1728,29 @@
|
|
1825
1728
|
var merge = createIterator(extendIteratorOptions, {
|
1826
1729
|
'args': 'object, source, indicator',
|
1827
1730
|
'top':
|
1828
|
-
'var isArr,
|
1829
|
-
'
|
1830
|
-
'
|
1831
|
-
'
|
1731
|
+
'var isArr, args = arguments, argsIndex = 0;\n' +
|
1732
|
+
'if (indicator == compareAscending) {\n' +
|
1733
|
+
' var argsLength = 2, stackA = args[3], stackB = args[4]\n' +
|
1734
|
+
'} else {\n' +
|
1735
|
+
' var argsLength = args.length, stackA = [], stackB = []\n' +
|
1736
|
+
'}\n' +
|
1737
|
+
'while (++argsIndex < argsLength) {\n' +
|
1738
|
+
' if (iteratee = args[argsIndex]) {',
|
1832
1739
|
'inLoop':
|
1833
1740
|
'if ((source = value) && ((isArr = isArray(source)) || isPlainObject(source))) {\n' +
|
1834
|
-
' var found = false,
|
1741
|
+
' var found = false, stackLength = stackA.length;\n' +
|
1835
1742
|
' while (stackLength--) {\n' +
|
1836
|
-
' if (found =
|
1743
|
+
' if (found = stackA[stackLength] == source) break\n' +
|
1837
1744
|
' }\n' +
|
1838
1745
|
' if (found) {\n' +
|
1839
|
-
' result[index] =
|
1746
|
+
' result[index] = stackB[stackLength]\n' +
|
1840
1747
|
' } else {\n' +
|
1841
|
-
'
|
1748
|
+
' stackA.push(source);\n' +
|
1749
|
+
' stackB.push(value = (value = result[index]) && isArr\n' +
|
1842
1750
|
' ? (isArray(value) ? value : [])\n' +
|
1843
1751
|
' : (isPlainObject(value) ? value : {})\n' +
|
1844
1752
|
' );\n' +
|
1845
|
-
'
|
1846
|
-
' result[index] = callee(value, source, isPlainObject, data)\n' +
|
1753
|
+
' result[index] = callee(value, source, compareAscending, stackA, stackB)\n' +
|
1847
1754
|
' }\n' +
|
1848
1755
|
'} else if (source != null) {\n' +
|
1849
1756
|
' result[index] = source\n' +
|
@@ -1855,7 +1762,7 @@
|
|
1855
1762
|
* Property names may be specified as individual arguments or as arrays of
|
1856
1763
|
* property names. If `callback` is passed, it will be executed for each property
|
1857
1764
|
* in the `object`, omitting the properties `callback` returns truthy for. The
|
1858
|
-
* `callback` is bound to `thisArg` and invoked with
|
1765
|
+
* `callback` is bound to `thisArg` and invoked with three arguments; (value, key, object).
|
1859
1766
|
*
|
1860
1767
|
* @static
|
1861
1768
|
* @memberOf _
|
@@ -1863,7 +1770,7 @@
|
|
1863
1770
|
* @param {Object} object The source object.
|
1864
1771
|
* @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
|
1865
1772
|
* or the function called per iteration.
|
1866
|
-
* @param {Mixed} [thisArg] The `this` binding
|
1773
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1867
1774
|
* @returns {Object} Returns an object without the omitted properties.
|
1868
1775
|
* @example
|
1869
1776
|
*
|
@@ -1902,7 +1809,7 @@
|
|
1902
1809
|
* Property names may be specified as individual arguments or as arrays of
|
1903
1810
|
* property names. If `callback` is passed, it will be executed for each property
|
1904
1811
|
* in the `object`, picking the properties `callback` returns truthy for. The
|
1905
|
-
* `callback` is bound to `thisArg` and invoked with
|
1812
|
+
* `callback` is bound to `thisArg` and invoked with three arguments; (value, key, object).
|
1906
1813
|
*
|
1907
1814
|
* @static
|
1908
1815
|
* @memberOf _
|
@@ -1910,7 +1817,7 @@
|
|
1910
1817
|
* @param {Object} object The source object.
|
1911
1818
|
* @param {Function|String} callback|[prop1, prop2, ...] The properties to pick
|
1912
1819
|
* or the function called per iteration.
|
1913
|
-
* @param {Mixed} [thisArg] The `this` binding
|
1820
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1914
1821
|
* @returns {Object} Returns an object composed of the picked properties.
|
1915
1822
|
* @example
|
1916
1823
|
*
|
@@ -1933,7 +1840,7 @@
|
|
1933
1840
|
' if (prop in object) result[prop] = object[prop]\n' +
|
1934
1841
|
' }\n' +
|
1935
1842
|
'} else {\n' +
|
1936
|
-
'
|
1843
|
+
' callback = createCallback(callback, thisArg)',
|
1937
1844
|
'inLoop':
|
1938
1845
|
'if (callback(value, index, object)) result[index] = value',
|
1939
1846
|
'bottom': '}'
|
@@ -1996,7 +1903,7 @@
|
|
1996
1903
|
* Creates an object composed of keys returned from running each element of
|
1997
1904
|
* `collection` through a `callback`. The corresponding value of each key is
|
1998
1905
|
* the number of times the key was returned by `callback`. The `callback` is
|
1999
|
-
* bound to `thisArg` and invoked with
|
1906
|
+
* bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2000
1907
|
* The `callback` argument may also be the name of a property to count by (e.g. 'length').
|
2001
1908
|
*
|
2002
1909
|
* @static
|
@@ -2005,7 +1912,7 @@
|
|
2005
1912
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2006
1913
|
* @param {Function|String} callback|property The function called per iteration
|
2007
1914
|
* or property name to count by.
|
2008
|
-
* @param {Mixed} [thisArg] The `this` binding
|
1915
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2009
1916
|
* @returns {Object} Returns the composed aggregate object.
|
2010
1917
|
* @example
|
2011
1918
|
*
|
@@ -2022,7 +1929,7 @@
|
|
2022
1929
|
|
2023
1930
|
/**
|
2024
1931
|
* Checks if the `callback` returns a truthy value for **all** elements of a
|
2025
|
-
* `collection`. The `callback` is bound to `thisArg` and invoked with
|
1932
|
+
* `collection`. The `callback` is bound to `thisArg` and invoked with three
|
2026
1933
|
* arguments; (value, index|key, collection).
|
2027
1934
|
*
|
2028
1935
|
* @static
|
@@ -2031,8 +1938,9 @@
|
|
2031
1938
|
* @category Collections
|
2032
1939
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2033
1940
|
* @param {Function} [callback=identity] The function called per iteration.
|
2034
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2035
|
-
* @returns {Boolean} Returns `true` if all elements pass the callback check,
|
1941
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1942
|
+
* @returns {Boolean} Returns `true` if all elements pass the callback check,
|
1943
|
+
* else `false`.
|
2036
1944
|
* @example
|
2037
1945
|
*
|
2038
1946
|
* _.every([true, 1, null, 'yes'], Boolean);
|
@@ -2043,7 +1951,7 @@
|
|
2043
1951
|
/**
|
2044
1952
|
* Examines each element in a `collection`, returning an array of all elements
|
2045
1953
|
* the `callback` returns truthy for. The `callback` is bound to `thisArg` and
|
2046
|
-
* invoked with
|
1954
|
+
* invoked with three arguments; (value, index|key, collection).
|
2047
1955
|
*
|
2048
1956
|
* @static
|
2049
1957
|
* @memberOf _
|
@@ -2051,8 +1959,8 @@
|
|
2051
1959
|
* @category Collections
|
2052
1960
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2053
1961
|
* @param {Function} [callback=identity] The function called per iteration.
|
2054
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2055
|
-
* @returns {Array} Returns a new array of elements that passed callback check.
|
1962
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1963
|
+
* @returns {Array} Returns a new array of elements that passed the callback check.
|
2056
1964
|
* @example
|
2057
1965
|
*
|
2058
1966
|
* var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
@@ -2064,7 +1972,7 @@
|
|
2064
1972
|
* Examines each element in a `collection`, returning the first one the `callback`
|
2065
1973
|
* returns truthy for. The function returns as soon as it finds an acceptable
|
2066
1974
|
* element, and does not iterate over the entire `collection`. The `callback` is
|
2067
|
-
* bound to `thisArg` and invoked with
|
1975
|
+
* bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2068
1976
|
*
|
2069
1977
|
* @static
|
2070
1978
|
* @memberOf _
|
@@ -2072,23 +1980,24 @@
|
|
2072
1980
|
* @category Collections
|
2073
1981
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2074
1982
|
* @param {Function} callback The function called per iteration.
|
2075
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2076
|
-
* @returns {Mixed} Returns the element that passed the callback check,
|
1983
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1984
|
+
* @returns {Mixed} Returns the element that passed the callback check,
|
1985
|
+
* else `undefined`.
|
2077
1986
|
* @example
|
2078
1987
|
*
|
2079
1988
|
* var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
2080
1989
|
* // => 2
|
2081
1990
|
*/
|
2082
1991
|
var find = createIterator(baseIteratorOptions, forEachIteratorOptions, {
|
2083
|
-
'init':
|
1992
|
+
'init': false,
|
2084
1993
|
'inLoop': 'if (callback(value, index, collection)) return value'
|
2085
1994
|
});
|
2086
1995
|
|
2087
1996
|
/**
|
2088
1997
|
* Iterates over a `collection`, executing the `callback` for each element in
|
2089
|
-
* the `collection`. The `callback` is bound to `thisArg` and invoked with
|
2090
|
-
* arguments; (value, index|key, collection). Callbacks may exit iteration
|
2091
|
-
*
|
1998
|
+
* the `collection`. The `callback` is bound to `thisArg` and invoked with three
|
1999
|
+
* arguments; (value, index|key, collection). Callbacks may exit iteration early
|
2000
|
+
* by explicitly returning `false`.
|
2092
2001
|
*
|
2093
2002
|
* @static
|
2094
2003
|
* @memberOf _
|
@@ -2096,8 +2005,8 @@
|
|
2096
2005
|
* @category Collections
|
2097
2006
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2098
2007
|
* @param {Function} callback The function called per iteration.
|
2099
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2100
|
-
* @returns {Array|Object} Returns `collection`.
|
2008
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2009
|
+
* @returns {Array|Object|String} Returns `collection`.
|
2101
2010
|
* @example
|
2102
2011
|
*
|
2103
2012
|
* _([1, 2, 3]).forEach(alert).join(',');
|
@@ -2112,7 +2021,7 @@
|
|
2112
2021
|
* Creates an object composed of keys returned from running each element of
|
2113
2022
|
* `collection` through a `callback`. The corresponding value of each key is an
|
2114
2023
|
* array of elements passed to `callback` that returned the key. The `callback`
|
2115
|
-
* is bound to `thisArg` and invoked with
|
2024
|
+
* is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2116
2025
|
* The `callback` argument may also be the name of a property to count by (e.g. 'length').
|
2117
2026
|
*
|
2118
2027
|
* @static
|
@@ -2121,7 +2030,7 @@
|
|
2121
2030
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2122
2031
|
* @param {Function|String} callback|property The function called per iteration
|
2123
2032
|
* or property name to group by.
|
2124
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2033
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2125
2034
|
* @returns {Object} Returns the composed aggregate object.
|
2126
2035
|
* @example
|
2127
2036
|
*
|
@@ -2136,15 +2045,15 @@
|
|
2136
2045
|
*/
|
2137
2046
|
var groupBy = createIterator(baseIteratorOptions, countByIteratorOptions, {
|
2138
2047
|
'inLoop':
|
2139
|
-
'prop = callback(value, index, collection);\n' +
|
2048
|
+
'var prop = callback(value, index, collection);\n' +
|
2140
2049
|
'(hasOwnProperty.call(result, prop) ? result[prop] : result[prop] = []).push(value)'
|
2141
2050
|
});
|
2142
2051
|
|
2143
2052
|
/**
|
2144
|
-
* Invokes the method named by `methodName` on each element in the `collection
|
2145
|
-
*
|
2146
|
-
*
|
2147
|
-
* in the `collection`.
|
2053
|
+
* Invokes the method named by `methodName` on each element in the `collection`,
|
2054
|
+
* returning an array of the results of each invoked method. Additional arguments
|
2055
|
+
* will be passed to each invoked method. If `methodName` is a function it will
|
2056
|
+
* be invoked for, and `this` bound to, each element in the `collection`.
|
2148
2057
|
*
|
2149
2058
|
* @static
|
2150
2059
|
* @memberOf _
|
@@ -2153,7 +2062,7 @@
|
|
2153
2062
|
* @param {Function|String} methodName The name of the method to invoke or
|
2154
2063
|
* the function invoked per iteration.
|
2155
2064
|
* @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
|
2156
|
-
* @returns {Array} Returns a new array of
|
2065
|
+
* @returns {Array} Returns a new array of the results of each invoked method.
|
2157
2066
|
* @example
|
2158
2067
|
*
|
2159
2068
|
* _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
|
@@ -2177,9 +2086,9 @@
|
|
2177
2086
|
});
|
2178
2087
|
|
2179
2088
|
/**
|
2180
|
-
* Creates
|
2089
|
+
* Creates an array of values by running each element in the `collection`
|
2181
2090
|
* through a `callback`. The `callback` is bound to `thisArg` and invoked with
|
2182
|
-
*
|
2091
|
+
* three arguments; (value, index|key, collection).
|
2183
2092
|
*
|
2184
2093
|
* @static
|
2185
2094
|
* @memberOf _
|
@@ -2187,8 +2096,8 @@
|
|
2187
2096
|
* @category Collections
|
2188
2097
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2189
2098
|
* @param {Function} [callback=identity] The function called per iteration.
|
2190
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2191
|
-
* @returns {Array} Returns a new array of
|
2099
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2100
|
+
* @returns {Array} Returns a new array of the results of each `callback` execution.
|
2192
2101
|
* @example
|
2193
2102
|
*
|
2194
2103
|
* _.map([1, 2, 3], function(num) { return num * 3; });
|
@@ -2241,7 +2150,7 @@
|
|
2241
2150
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2242
2151
|
* @param {Function} callback The function called per iteration.
|
2243
2152
|
* @param {Mixed} [accumulator] Initial value of the accumulator.
|
2244
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2153
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2245
2154
|
* @returns {Mixed} Returns the accumulated value.
|
2246
2155
|
* @example
|
2247
2156
|
*
|
@@ -2253,7 +2162,7 @@
|
|
2253
2162
|
'init': 'accumulator',
|
2254
2163
|
'top':
|
2255
2164
|
'var noaccum = arguments.length < 3;\n' +
|
2256
|
-
'
|
2165
|
+
'callback = createCallback(callback, thisArg)',
|
2257
2166
|
'beforeLoop': {
|
2258
2167
|
'array': 'if (noaccum) result = iteratee[++index]'
|
2259
2168
|
},
|
@@ -2277,7 +2186,7 @@
|
|
2277
2186
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2278
2187
|
* @param {Function} callback The function called per iteration.
|
2279
2188
|
* @param {Mixed} [accumulator] Initial value of the accumulator.
|
2280
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2189
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2281
2190
|
* @returns {Mixed} Returns the accumulated value.
|
2282
2191
|
* @example
|
2283
2192
|
*
|
@@ -2286,42 +2195,22 @@
|
|
2286
2195
|
* // => [4, 5, 2, 3, 0, 1]
|
2287
2196
|
*/
|
2288
2197
|
function reduceRight(collection, callback, accumulator, thisArg) {
|
2289
|
-
|
2290
|
-
|
2291
|
-
}
|
2292
|
-
|
2293
|
-
var length = collection.length,
|
2198
|
+
var iteratee = collection,
|
2199
|
+
length = collection ? collection.length : 0,
|
2294
2200
|
noaccum = arguments.length < 3;
|
2295
2201
|
|
2296
|
-
if(
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
var iteratee = noCharByIndex && toString.call(collection) == stringClass
|
2302
|
-
? collection.split('')
|
2303
|
-
: collection;
|
2304
|
-
|
2305
|
-
if (length && noaccum) {
|
2306
|
-
accumulator = iteratee[--length];
|
2307
|
-
}
|
2308
|
-
while (length--) {
|
2309
|
-
accumulator = callback(accumulator, iteratee[length], length, collection);
|
2310
|
-
}
|
2311
|
-
return accumulator;
|
2312
|
-
}
|
2313
|
-
|
2314
|
-
var prop,
|
2315
|
-
props = keys(collection);
|
2316
|
-
|
2317
|
-
length = props.length;
|
2318
|
-
if (length && noaccum) {
|
2319
|
-
accumulator = collection[props[--length]];
|
2320
|
-
}
|
2321
|
-
while (length--) {
|
2322
|
-
prop = props[length];
|
2323
|
-
accumulator = callback(accumulator, collection[prop], prop, collection);
|
2202
|
+
if (length !== +length) {
|
2203
|
+
var props = keys(collection);
|
2204
|
+
length = props.length;
|
2205
|
+
} else if (noCharByIndex && toString.call(collection) == stringClass) {
|
2206
|
+
iteratee = collection.split('');
|
2324
2207
|
}
|
2208
|
+
forEach(collection, function(value, index, object) {
|
2209
|
+
index = props ? props[--length] : --length;
|
2210
|
+
accumulator = noaccum
|
2211
|
+
? (noaccum = false, iteratee[index])
|
2212
|
+
: callback.call(thisArg, accumulator, iteratee[index], index, object);
|
2213
|
+
});
|
2325
2214
|
return accumulator;
|
2326
2215
|
}
|
2327
2216
|
|
@@ -2334,8 +2223,9 @@
|
|
2334
2223
|
* @category Collections
|
2335
2224
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2336
2225
|
* @param {Function} [callback=identity] The function called per iteration.
|
2337
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2338
|
-
* @returns {Array} Returns a new array of elements that did **not** pass the
|
2226
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2227
|
+
* @returns {Array} Returns a new array of elements that did **not** pass the
|
2228
|
+
* callback check.
|
2339
2229
|
* @example
|
2340
2230
|
*
|
2341
2231
|
* var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
@@ -2366,18 +2256,15 @@
|
|
2366
2256
|
* // => 5
|
2367
2257
|
*/
|
2368
2258
|
function size(collection) {
|
2369
|
-
|
2370
|
-
|
2371
|
-
}
|
2372
|
-
var length = collection.length;
|
2373
|
-
return length > -1 && length === length >>> 0 ? length : keys(collection).length;
|
2259
|
+
var length = collection ? collection.length : 0;
|
2260
|
+
return length === +length ? length : keys(collection).length;
|
2374
2261
|
}
|
2375
2262
|
|
2376
2263
|
/**
|
2377
2264
|
* Checks if the `callback` returns a truthy value for **any** element of a
|
2378
2265
|
* `collection`. The function returns as soon as it finds passing value, and
|
2379
2266
|
* does not iterate over the entire `collection`. The `callback` is bound to
|
2380
|
-
* `thisArg` and invoked with
|
2267
|
+
* `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2381
2268
|
*
|
2382
2269
|
* @static
|
2383
2270
|
* @memberOf _
|
@@ -2385,8 +2272,9 @@
|
|
2385
2272
|
* @category Collections
|
2386
2273
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2387
2274
|
* @param {Function} [callback=identity] The function called per iteration.
|
2388
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2389
|
-
* @returns {Boolean} Returns `true` if any element passes the callback check,
|
2275
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2276
|
+
* @returns {Boolean} Returns `true` if any element passes the callback check,
|
2277
|
+
* else `false`.
|
2390
2278
|
* @example
|
2391
2279
|
*
|
2392
2280
|
* _.some([null, 0, 'yes', false]);
|
@@ -2398,9 +2286,9 @@
|
|
2398
2286
|
});
|
2399
2287
|
|
2400
2288
|
/**
|
2401
|
-
* Creates
|
2289
|
+
* Creates an array, stable sorted in ascending order by the results of
|
2402
2290
|
* running each element of `collection` through a `callback`. The `callback`
|
2403
|
-
* is bound to `thisArg` and invoked with
|
2291
|
+
* is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2404
2292
|
* The `callback` argument may also be the name of a property to sort by (e.g. 'length').
|
2405
2293
|
*
|
2406
2294
|
* @static
|
@@ -2409,7 +2297,7 @@
|
|
2409
2297
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2410
2298
|
* @param {Function|String} callback|property The function called per iteration
|
2411
2299
|
* or property name to sort by.
|
2412
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2300
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2413
2301
|
* @returns {Array} Returns a new array of sorted elements.
|
2414
2302
|
* @example
|
2415
2303
|
*
|
@@ -2446,8 +2334,7 @@
|
|
2446
2334
|
});
|
2447
2335
|
|
2448
2336
|
/**
|
2449
|
-
* Converts the `collection`, to an array.
|
2450
|
-
* `arguments` object.
|
2337
|
+
* Converts the `collection`, to an array.
|
2451
2338
|
*
|
2452
2339
|
* @static
|
2453
2340
|
* @memberOf _
|
@@ -2463,11 +2350,8 @@
|
|
2463
2350
|
if (!collection) {
|
2464
2351
|
return [];
|
2465
2352
|
}
|
2466
|
-
if (collection.toArray && isFunction(collection.toArray)) {
|
2467
|
-
return collection.toArray();
|
2468
|
-
}
|
2469
2353
|
var length = collection.length;
|
2470
|
-
if (length
|
2354
|
+
if (length === +length) {
|
2471
2355
|
return (noArraySliceOnStrings ? toString.call(collection) == stringClass : typeof collection == 'string')
|
2472
2356
|
? collection.split('')
|
2473
2357
|
: slice.call(collection);
|
@@ -2513,7 +2397,7 @@
|
|
2513
2397
|
/*--------------------------------------------------------------------------*/
|
2514
2398
|
|
2515
2399
|
/**
|
2516
|
-
* Creates
|
2400
|
+
* Creates an array with all falsey values of `array` removed. The values
|
2517
2401
|
* `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
|
2518
2402
|
*
|
2519
2403
|
* @static
|
@@ -2527,12 +2411,9 @@
|
|
2527
2411
|
* // => [1, 2, 3]
|
2528
2412
|
*/
|
2529
2413
|
function compact(array) {
|
2530
|
-
var result = [];
|
2531
|
-
if (!array) {
|
2532
|
-
return result;
|
2533
|
-
}
|
2534
2414
|
var index = -1,
|
2535
|
-
length = array.length
|
2415
|
+
length = array ? array.length : 0,
|
2416
|
+
result = [];
|
2536
2417
|
|
2537
2418
|
while (++index < length) {
|
2538
2419
|
if (array[index]) {
|
@@ -2543,7 +2424,7 @@
|
|
2543
2424
|
}
|
2544
2425
|
|
2545
2426
|
/**
|
2546
|
-
* Creates
|
2427
|
+
* Creates an array of `array` elements not present in the other arrays
|
2547
2428
|
* using strict equality for comparisons, i.e. `===`.
|
2548
2429
|
*
|
2549
2430
|
* @static
|
@@ -2565,12 +2446,13 @@
|
|
2565
2446
|
}
|
2566
2447
|
var index = -1,
|
2567
2448
|
length = array.length,
|
2568
|
-
flattened = concat.apply(
|
2449
|
+
flattened = concat.apply(ArrayProto, arguments),
|
2569
2450
|
contains = cachedContains(flattened, length);
|
2570
2451
|
|
2571
2452
|
while (++index < length) {
|
2572
|
-
|
2573
|
-
|
2453
|
+
var value = array[index];
|
2454
|
+
if (!contains(value)) {
|
2455
|
+
result.push(value);
|
2574
2456
|
}
|
2575
2457
|
}
|
2576
2458
|
return result;
|
@@ -2586,7 +2468,7 @@
|
|
2586
2468
|
* @category Arrays
|
2587
2469
|
* @param {Array} array The array to query.
|
2588
2470
|
* @param {Number} [n] The number of elements to return.
|
2589
|
-
* @param {Object} [guard] Internally used to allow this method to work with
|
2471
|
+
* @param- {Object} [guard] Internally used to allow this method to work with
|
2590
2472
|
* others like `_.map` without using their callback `index` argument for `n`.
|
2591
2473
|
* @returns {Mixed} Returns the first element or an array of the first `n`
|
2592
2474
|
* elements of `array`.
|
@@ -2620,16 +2502,15 @@
|
|
2620
2502
|
* // => [1, 2, 3, [[4]]];
|
2621
2503
|
*/
|
2622
2504
|
function flatten(array, shallow) {
|
2623
|
-
var result = [];
|
2624
|
-
if (!array) {
|
2625
|
-
return result;
|
2626
|
-
}
|
2627
2505
|
var value,
|
2628
2506
|
index = -1,
|
2629
|
-
length = array.length
|
2507
|
+
length = array ? array.length : 0,
|
2508
|
+
result = [];
|
2630
2509
|
|
2631
2510
|
while (++index < length) {
|
2632
2511
|
value = array[index];
|
2512
|
+
|
2513
|
+
// recursively flatten arrays (susceptible to call stack limits)
|
2633
2514
|
if (isArray(value)) {
|
2634
2515
|
push.apply(result, shallow ? value : flatten(value));
|
2635
2516
|
} else {
|
@@ -2664,19 +2545,14 @@
|
|
2664
2545
|
* // => 2
|
2665
2546
|
*/
|
2666
2547
|
function indexOf(array, value, fromIndex) {
|
2667
|
-
if (!array) {
|
2668
|
-
return -1;
|
2669
|
-
}
|
2670
2548
|
var index = -1,
|
2671
|
-
length = array.length;
|
2549
|
+
length = array ? array.length : 0;
|
2672
2550
|
|
2673
|
-
if (fromIndex) {
|
2674
|
-
|
2675
|
-
|
2676
|
-
|
2677
|
-
|
2678
|
-
return array[index] === value ? index : -1;
|
2679
|
-
}
|
2551
|
+
if (typeof fromIndex == 'number') {
|
2552
|
+
index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
|
2553
|
+
} else if (fromIndex) {
|
2554
|
+
index = sortedIndex(array, value);
|
2555
|
+
return array[index] === value ? index : -1;
|
2680
2556
|
}
|
2681
2557
|
while (++index < length) {
|
2682
2558
|
if (array[index] === value) {
|
@@ -2695,7 +2571,7 @@
|
|
2695
2571
|
* @category Arrays
|
2696
2572
|
* @param {Array} array The array to query.
|
2697
2573
|
* @param {Number} [n] The number of elements to return.
|
2698
|
-
* @param {Object} [guard] Internally used to allow this method to work with
|
2574
|
+
* @param- {Object} [guard] Internally used to allow this method to work with
|
2699
2575
|
* others like `_.map` without using their callback `index` argument for `n`.
|
2700
2576
|
* @returns {Array} Returns all but the last element or `n` elements of `array`.
|
2701
2577
|
* @example
|
@@ -2704,10 +2580,9 @@
|
|
2704
2580
|
* // => [3, 2]
|
2705
2581
|
*/
|
2706
2582
|
function initial(array, n, guard) {
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
return slice.call(array, 0, -((n == null || guard) ? 1 : n));
|
2583
|
+
return array
|
2584
|
+
? slice.call(array, 0, -((n == null || guard) ? 1 : n))
|
2585
|
+
: [];
|
2711
2586
|
}
|
2712
2587
|
|
2713
2588
|
/**
|
@@ -2726,18 +2601,14 @@
|
|
2726
2601
|
* // => [1, 2]
|
2727
2602
|
*/
|
2728
2603
|
function intersection(array) {
|
2729
|
-
var
|
2730
|
-
if (!array) {
|
2731
|
-
return result;
|
2732
|
-
}
|
2733
|
-
var value,
|
2734
|
-
argsLength = arguments.length,
|
2604
|
+
var argsLength = arguments.length,
|
2735
2605
|
cache = [],
|
2736
2606
|
index = -1,
|
2737
|
-
length = array.length
|
2607
|
+
length = array ? array.length : 0,
|
2608
|
+
result = [];
|
2738
2609
|
|
2739
2610
|
array: while (++index < length) {
|
2740
|
-
value = array[index];
|
2611
|
+
var value = array[index];
|
2741
2612
|
if (indexOf(result, value) < 0) {
|
2742
2613
|
for (var argsIndex = 1; argsIndex < argsLength; argsIndex++) {
|
2743
2614
|
if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(arguments[argsIndex])))(value)) {
|
@@ -2751,15 +2622,15 @@
|
|
2751
2622
|
}
|
2752
2623
|
|
2753
2624
|
/**
|
2754
|
-
* Gets the last element of the `array`. Pass `n` to return the
|
2755
|
-
*
|
2625
|
+
* Gets the last element of the `array`. Pass `n` to return the last `n`
|
2626
|
+
* elements of the `array`.
|
2756
2627
|
*
|
2757
2628
|
* @static
|
2758
2629
|
* @memberOf _
|
2759
2630
|
* @category Arrays
|
2760
2631
|
* @param {Array} array The array to query.
|
2761
2632
|
* @param {Number} [n] The number of elements to return.
|
2762
|
-
* @param {Object} [guard] Internally used to allow this method to work with
|
2633
|
+
* @param- {Object} [guard] Internally used to allow this method to work with
|
2763
2634
|
* others like `_.map` without using their callback `index` argument for `n`.
|
2764
2635
|
* @returns {Mixed} Returns the last element or an array of the last `n`
|
2765
2636
|
* elements of `array`.
|
@@ -2795,11 +2666,8 @@
|
|
2795
2666
|
* // => 1
|
2796
2667
|
*/
|
2797
2668
|
function lastIndexOf(array, value, fromIndex) {
|
2798
|
-
|
2799
|
-
|
2800
|
-
}
|
2801
|
-
var index = array.length;
|
2802
|
-
if (fromIndex && typeof fromIndex == 'number') {
|
2669
|
+
var index = array ? array.length : 0;
|
2670
|
+
if (typeof fromIndex == 'number') {
|
2803
2671
|
index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
|
2804
2672
|
}
|
2805
2673
|
while (index--) {
|
@@ -2814,14 +2682,14 @@
|
|
2814
2682
|
* Retrieves the maximum value of an `array`. If `callback` is passed,
|
2815
2683
|
* it will be executed for each value in the `array` to generate the
|
2816
2684
|
* criterion by which the value is ranked. The `callback` is bound to
|
2817
|
-
* `thisArg` and invoked with
|
2685
|
+
* `thisArg` and invoked with three arguments; (value, index, array).
|
2818
2686
|
*
|
2819
2687
|
* @static
|
2820
2688
|
* @memberOf _
|
2821
2689
|
* @category Arrays
|
2822
2690
|
* @param {Array} array The array to iterate over.
|
2823
2691
|
* @param {Function} [callback] The function called per iteration.
|
2824
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2692
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2825
2693
|
* @returns {Mixed} Returns the maximum value.
|
2826
2694
|
* @example
|
2827
2695
|
*
|
@@ -2835,27 +2703,13 @@
|
|
2835
2703
|
* // => { 'name': 'curly', 'age': 60 };
|
2836
2704
|
*/
|
2837
2705
|
function max(array, callback, thisArg) {
|
2838
|
-
var computed = -Infinity,
|
2839
|
-
result = computed;
|
2840
|
-
|
2841
|
-
if (!array) {
|
2842
|
-
return result;
|
2843
|
-
}
|
2844
2706
|
var current,
|
2707
|
+
computed = -Infinity,
|
2845
2708
|
index = -1,
|
2846
|
-
length = array.length
|
2709
|
+
length = array ? array.length : 0,
|
2710
|
+
result = computed;
|
2847
2711
|
|
2848
|
-
|
2849
|
-
while (++index < length) {
|
2850
|
-
if (array[index] > result) {
|
2851
|
-
result = array[index];
|
2852
|
-
}
|
2853
|
-
}
|
2854
|
-
return result;
|
2855
|
-
}
|
2856
|
-
if (thisArg) {
|
2857
|
-
callback = iteratorBind(callback, thisArg);
|
2858
|
-
}
|
2712
|
+
callback = createCallback(callback, thisArg);
|
2859
2713
|
while (++index < length) {
|
2860
2714
|
current = callback(array[index], index, array);
|
2861
2715
|
if (current > computed) {
|
@@ -2870,14 +2724,14 @@
|
|
2870
2724
|
* Retrieves the minimum value of an `array`. If `callback` is passed,
|
2871
2725
|
* it will be executed for each value in the `array` to generate the
|
2872
2726
|
* criterion by which the value is ranked. The `callback` is bound to `thisArg`
|
2873
|
-
* and invoked with
|
2727
|
+
* and invoked with three arguments; (value, index, array).
|
2874
2728
|
*
|
2875
2729
|
* @static
|
2876
2730
|
* @memberOf _
|
2877
2731
|
* @category Arrays
|
2878
2732
|
* @param {Array} array The array to iterate over.
|
2879
2733
|
* @param {Function} [callback] The function called per iteration.
|
2880
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2734
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2881
2735
|
* @returns {Mixed} Returns the minimum value.
|
2882
2736
|
* @example
|
2883
2737
|
*
|
@@ -2885,27 +2739,13 @@
|
|
2885
2739
|
* // => 2
|
2886
2740
|
*/
|
2887
2741
|
function min(array, callback, thisArg) {
|
2888
|
-
var computed = Infinity,
|
2889
|
-
result = computed;
|
2890
|
-
|
2891
|
-
if (!array) {
|
2892
|
-
return result;
|
2893
|
-
}
|
2894
2742
|
var current,
|
2743
|
+
computed = Infinity,
|
2895
2744
|
index = -1,
|
2896
|
-
length = array.length
|
2745
|
+
length = array ? array.length : 0,
|
2746
|
+
result = computed;
|
2897
2747
|
|
2898
|
-
|
2899
|
-
while (++index < length) {
|
2900
|
-
if (array[index] < result) {
|
2901
|
-
result = array[index];
|
2902
|
-
}
|
2903
|
-
}
|
2904
|
-
return result;
|
2905
|
-
}
|
2906
|
-
if (thisArg) {
|
2907
|
-
callback = iteratorBind(callback, thisArg);
|
2908
|
-
}
|
2748
|
+
callback = createCallback(callback, thisArg);
|
2909
2749
|
while (++index < length) {
|
2910
2750
|
current = callback(array[index], index, array);
|
2911
2751
|
if (current < computed) {
|
@@ -2934,11 +2774,8 @@
|
|
2934
2774
|
* // => { 'moe': 30, 'larry': 40, 'curly': 50 }
|
2935
2775
|
*/
|
2936
2776
|
function object(keys, values) {
|
2937
|
-
if (!keys) {
|
2938
|
-
return {};
|
2939
|
-
}
|
2940
2777
|
var index = -1,
|
2941
|
-
length = keys.length,
|
2778
|
+
length = keys ? keys.length : 0,
|
2942
2779
|
result = {};
|
2943
2780
|
|
2944
2781
|
while (++index < length) {
|
@@ -3011,7 +2848,7 @@
|
|
3011
2848
|
* @category Arrays
|
3012
2849
|
* @param {Array} array The array to query.
|
3013
2850
|
* @param {Number} [n] The number of elements to return.
|
3014
|
-
* @param {Object} [guard] Internally used to allow this method to work with
|
2851
|
+
* @param- {Object} [guard] Internally used to allow this method to work with
|
3015
2852
|
* others like `_.map` without using their callback `index` argument for `n`.
|
3016
2853
|
* @returns {Array} Returns all but the first value or `n` values of `array`.
|
3017
2854
|
* @example
|
@@ -3020,14 +2857,13 @@
|
|
3020
2857
|
* // => [2, 1]
|
3021
2858
|
*/
|
3022
2859
|
function rest(array, n, guard) {
|
3023
|
-
|
3024
|
-
|
3025
|
-
|
3026
|
-
return slice.call(array, (n == null || guard) ? 1 : n);
|
2860
|
+
return array
|
2861
|
+
? slice.call(array, (n == null || guard) ? 1 : n)
|
2862
|
+
: [];
|
3027
2863
|
}
|
3028
2864
|
|
3029
2865
|
/**
|
3030
|
-
* Creates
|
2866
|
+
* Creates an array of shuffled `array` values, using a version of the
|
3031
2867
|
* Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
|
3032
2868
|
*
|
3033
2869
|
* @static
|
@@ -3041,16 +2877,12 @@
|
|
3041
2877
|
* // => [4, 1, 6, 3, 5, 2]
|
3042
2878
|
*/
|
3043
2879
|
function shuffle(array) {
|
3044
|
-
|
3045
|
-
|
3046
|
-
}
|
3047
|
-
var rand,
|
3048
|
-
index = -1,
|
3049
|
-
length = array.length,
|
2880
|
+
var index = -1,
|
2881
|
+
length = array ? array.length : 0,
|
3050
2882
|
result = Array(length);
|
3051
2883
|
|
3052
2884
|
while (++index < length) {
|
3053
|
-
rand = nativeFloor(nativeRandom() * (index + 1));
|
2885
|
+
var rand = nativeFloor(nativeRandom() * (index + 1));
|
3054
2886
|
result[index] = result[rand];
|
3055
2887
|
result[rand] = array[index];
|
3056
2888
|
}
|
@@ -3062,58 +2894,50 @@
|
|
3062
2894
|
* should be inserted into `array` in order to maintain the sort order of the
|
3063
2895
|
* sorted `array`. If `callback` is passed, it will be executed for `value` and
|
3064
2896
|
* each element in `array` to compute their sort ranking. The `callback` is
|
3065
|
-
* bound to `thisArg` and invoked with
|
2897
|
+
* bound to `thisArg` and invoked with one argument; (value). The `callback`
|
2898
|
+
* argument may also be the name of a property to order by.
|
3066
2899
|
*
|
3067
2900
|
* @static
|
3068
2901
|
* @memberOf _
|
3069
2902
|
* @category Arrays
|
3070
2903
|
* @param {Array} array The array to iterate over.
|
3071
2904
|
* @param {Mixed} value The value to evaluate.
|
3072
|
-
* @param {Function} [callback=identity] The function called
|
3073
|
-
*
|
2905
|
+
* @param {Function|String} [callback=identity|property] The function called
|
2906
|
+
* per iteration or property name to order by.
|
2907
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3074
2908
|
* @returns {Number} Returns the index at which the value should be inserted
|
3075
2909
|
* into `array`.
|
3076
2910
|
* @example
|
3077
2911
|
*
|
3078
|
-
* _.sortedIndex([20, 30,
|
2912
|
+
* _.sortedIndex([20, 30, 50], 40);
|
2913
|
+
* // => 2
|
2914
|
+
*
|
2915
|
+
* _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
|
3079
2916
|
* // => 2
|
3080
2917
|
*
|
3081
2918
|
* var dict = {
|
3082
|
-
* 'wordToNumber': { 'twenty': 20, 'thirty': 30, '
|
2919
|
+
* 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
|
3083
2920
|
* };
|
3084
2921
|
*
|
3085
|
-
* _.sortedIndex(['twenty', 'thirty', '
|
2922
|
+
* _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
|
3086
2923
|
* return dict.wordToNumber[word];
|
3087
2924
|
* });
|
3088
2925
|
* // => 2
|
3089
2926
|
*
|
3090
|
-
* _.sortedIndex(['twenty', 'thirty', '
|
2927
|
+
* _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
|
3091
2928
|
* return this.wordToNumber[word];
|
3092
2929
|
* }, dict);
|
3093
2930
|
* // => 2
|
3094
2931
|
*/
|
3095
2932
|
function sortedIndex(array, value, callback, thisArg) {
|
3096
|
-
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3100
|
-
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
if (thisArg) {
|
3105
|
-
callback = bind(callback, thisArg);
|
3106
|
-
}
|
3107
|
-
value = callback(value);
|
3108
|
-
while (low < high) {
|
3109
|
-
mid = (low + high) >>> 1;
|
3110
|
-
callback(array[mid]) < value ? low = mid + 1 : high = mid;
|
3111
|
-
}
|
3112
|
-
} else {
|
3113
|
-
while (low < high) {
|
3114
|
-
mid = (low + high) >>> 1;
|
3115
|
-
array[mid] < value ? low = mid + 1 : high = mid;
|
3116
|
-
}
|
2933
|
+
var low = 0,
|
2934
|
+
high = array ? array.length : low;
|
2935
|
+
|
2936
|
+
callback = createCallback(callback, thisArg);
|
2937
|
+
value = callback(value);
|
2938
|
+
while (low < high) {
|
2939
|
+
var mid = (low + high) >>> 1;
|
2940
|
+
callback(array[mid]) < value ? low = mid + 1 : high = mid;
|
3117
2941
|
}
|
3118
2942
|
return low;
|
3119
2943
|
}
|
@@ -3135,9 +2959,9 @@
|
|
3135
2959
|
*/
|
3136
2960
|
function union() {
|
3137
2961
|
var index = -1,
|
3138
|
-
|
3139
|
-
|
3140
|
-
|
2962
|
+
flattened = concat.apply(ArrayProto, arguments),
|
2963
|
+
length = flattened.length,
|
2964
|
+
result = [];
|
3141
2965
|
|
3142
2966
|
while (++index < length) {
|
3143
2967
|
if (indexOf(result, flattened[index]) < 0) {
|
@@ -3152,7 +2976,7 @@
|
|
3152
2976
|
* for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
|
3153
2977
|
* for `isSorted` will run a faster algorithm. If `callback` is passed, each
|
3154
2978
|
* element of `array` is passed through a callback` before uniqueness is computed.
|
3155
|
-
* The `callback` is bound to `thisArg` and invoked with
|
2979
|
+
* The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
|
3156
2980
|
*
|
3157
2981
|
* @static
|
3158
2982
|
* @memberOf _
|
@@ -3161,7 +2985,7 @@
|
|
3161
2985
|
* @param {Array} array The array to process.
|
3162
2986
|
* @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
|
3163
2987
|
* @param {Function} [callback=identity] The function called per iteration.
|
3164
|
-
* @param {Mixed} [thisArg] The `this` binding
|
2988
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3165
2989
|
* @returns {Array} Returns a duplicate-value-free array.
|
3166
2990
|
* @example
|
3167
2991
|
*
|
@@ -3178,13 +3002,9 @@
|
|
3178
3002
|
* // => [1, 2, 3]
|
3179
3003
|
*/
|
3180
3004
|
function uniq(array, isSorted, callback, thisArg) {
|
3181
|
-
var
|
3182
|
-
|
3183
|
-
|
3184
|
-
}
|
3185
|
-
var computed,
|
3186
|
-
index = -1,
|
3187
|
-
length = array.length,
|
3005
|
+
var index = -1,
|
3006
|
+
length = array ? array.length : 0,
|
3007
|
+
result = [],
|
3188
3008
|
seen = [];
|
3189
3009
|
|
3190
3010
|
// juggle arguments
|
@@ -3193,13 +3013,9 @@
|
|
3193
3013
|
callback = isSorted;
|
3194
3014
|
isSorted = false;
|
3195
3015
|
}
|
3196
|
-
|
3197
|
-
callback = identity;
|
3198
|
-
} else if (thisArg) {
|
3199
|
-
callback = iteratorBind(callback, thisArg);
|
3200
|
-
}
|
3016
|
+
callback = createCallback(callback, thisArg);
|
3201
3017
|
while (++index < length) {
|
3202
|
-
computed = callback(array[index], index, array);
|
3018
|
+
var computed = callback(array[index], index, array);
|
3203
3019
|
if (isSorted
|
3204
3020
|
? !index || seen[seen.length - 1] !== computed
|
3205
3021
|
: indexOf(seen, computed) < 0
|
@@ -3212,7 +3028,7 @@
|
|
3212
3028
|
}
|
3213
3029
|
|
3214
3030
|
/**
|
3215
|
-
* Creates
|
3031
|
+
* Creates an array with all occurrences of the passed values removed using
|
3216
3032
|
* strict equality for comparisons, i.e. `===`.
|
3217
3033
|
*
|
3218
3034
|
* @static
|
@@ -3227,17 +3043,15 @@
|
|
3227
3043
|
* // => [2, 3, 4]
|
3228
3044
|
*/
|
3229
3045
|
function without(array) {
|
3230
|
-
var result = [];
|
3231
|
-
if (!array) {
|
3232
|
-
return result;
|
3233
|
-
}
|
3234
3046
|
var index = -1,
|
3235
|
-
length = array.length,
|
3236
|
-
contains = cachedContains(arguments, 1, 20)
|
3047
|
+
length = array ? array.length : 0,
|
3048
|
+
contains = cachedContains(arguments, 1, 20),
|
3049
|
+
result = [];
|
3237
3050
|
|
3238
3051
|
while (++index < length) {
|
3239
|
-
|
3240
|
-
|
3052
|
+
var value = array[index];
|
3053
|
+
if (!contains(value)) {
|
3054
|
+
result.push(value);
|
3241
3055
|
}
|
3242
3056
|
}
|
3243
3057
|
return result;
|
@@ -3260,11 +3074,8 @@
|
|
3260
3074
|
* // => [['moe', 30, true], ['larry', 40, false], ['curly', 50, false]]
|
3261
3075
|
*/
|
3262
3076
|
function zip(array) {
|
3263
|
-
if (!array) {
|
3264
|
-
return [];
|
3265
|
-
}
|
3266
3077
|
var index = -1,
|
3267
|
-
length = max(pluck(arguments, 'length')),
|
3078
|
+
length = array ? max(pluck(arguments, 'length')) : 0,
|
3268
3079
|
result = Array(length);
|
3269
3080
|
|
3270
3081
|
while (++index < length) {
|
@@ -3276,7 +3087,7 @@
|
|
3276
3087
|
/*--------------------------------------------------------------------------*/
|
3277
3088
|
|
3278
3089
|
/**
|
3279
|
-
* Creates a
|
3090
|
+
* Creates a function that is restricted to executing only after it is
|
3280
3091
|
* called `n` times.
|
3281
3092
|
*
|
3282
3093
|
* @static
|
@@ -3306,21 +3117,19 @@
|
|
3306
3117
|
}
|
3307
3118
|
|
3308
3119
|
/**
|
3309
|
-
* Creates a
|
3120
|
+
* Creates a function that, when called, invokes `func` with the `this`
|
3310
3121
|
* binding of `thisArg` and prepends any additional `bind` arguments to those
|
3311
|
-
* passed to the bound function.
|
3312
|
-
* the object they are bound to as `func` and the method name as `thisArg`.
|
3122
|
+
* passed to the bound function.
|
3313
3123
|
*
|
3314
3124
|
* @static
|
3315
3125
|
* @memberOf _
|
3316
3126
|
* @category Functions
|
3317
|
-
* @param {Function
|
3318
|
-
* @param {Mixed} [thisArg] The `this` binding of `func
|
3127
|
+
* @param {Function} func The function to bind.
|
3128
|
+
* @param {Mixed} [thisArg] The `this` binding of `func`.
|
3319
3129
|
* @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
|
3320
3130
|
* @returns {Function} Returns the new bound function.
|
3321
3131
|
* @example
|
3322
3132
|
*
|
3323
|
-
* // basic bind
|
3324
3133
|
* var func = function(greeting) {
|
3325
3134
|
* return greeting + ' ' + this.name;
|
3326
3135
|
* };
|
@@ -3328,72 +3137,13 @@
|
|
3328
3137
|
* func = _.bind(func, { 'name': 'moe' }, 'hi');
|
3329
3138
|
* func();
|
3330
3139
|
* // => 'hi moe'
|
3331
|
-
*
|
3332
|
-
* // lazy bind
|
3333
|
-
* var object = {
|
3334
|
-
* 'name': 'moe',
|
3335
|
-
* 'greet': function(greeting) {
|
3336
|
-
* return greeting + ' ' + this.name;
|
3337
|
-
* }
|
3338
|
-
* };
|
3339
|
-
*
|
3340
|
-
* var func = _.bind(object, 'greet', 'hi');
|
3341
|
-
* func();
|
3342
|
-
* // => 'hi moe'
|
3343
|
-
*
|
3344
|
-
* object.greet = function(greeting) {
|
3345
|
-
* return greeting + ', ' + this.name + '!';
|
3346
|
-
* };
|
3347
|
-
*
|
3348
|
-
* func();
|
3349
|
-
* // => 'hi, moe!'
|
3350
3140
|
*/
|
3351
3141
|
function bind(func, thisArg) {
|
3352
|
-
var methodName,
|
3353
|
-
isFunc = isFunction(func);
|
3354
|
-
|
3355
|
-
// juggle arguments
|
3356
|
-
if (!isFunc) {
|
3357
|
-
methodName = thisArg;
|
3358
|
-
thisArg = func;
|
3359
|
-
}
|
3360
3142
|
// use `Function#bind` if it exists and is fast
|
3361
3143
|
// (in V8 `Function#bind` is slower except when partially applied)
|
3362
|
-
|
3363
|
-
|
3364
|
-
|
3365
|
-
|
3366
|
-
var partialArgs = slice.call(arguments, 2);
|
3367
|
-
|
3368
|
-
function bound() {
|
3369
|
-
// `Function#bind` spec
|
3370
|
-
// http://es5.github.com/#x15.3.4.5
|
3371
|
-
var args = arguments,
|
3372
|
-
thisBinding = thisArg;
|
3373
|
-
|
3374
|
-
if (!isFunc) {
|
3375
|
-
func = thisArg[methodName];
|
3376
|
-
}
|
3377
|
-
if (partialArgs.length) {
|
3378
|
-
args = args.length
|
3379
|
-
? partialArgs.concat(slice.call(args))
|
3380
|
-
: partialArgs;
|
3381
|
-
}
|
3382
|
-
if (this instanceof bound) {
|
3383
|
-
// get `func` instance if `bound` is invoked in a `new` expression
|
3384
|
-
noop.prototype = func.prototype;
|
3385
|
-
thisBinding = new noop;
|
3386
|
-
|
3387
|
-
// mimic the constructor's `return` behavior
|
3388
|
-
// http://es5.github.com/#x13.2.2
|
3389
|
-
var result = func.apply(thisBinding, args);
|
3390
|
-
return result && objectTypes[typeof result]
|
3391
|
-
? result
|
3392
|
-
: thisBinding
|
3393
|
-
}
|
3394
|
-
return func.apply(thisBinding, args);
|
3395
|
-
}
|
3396
|
-
return bound;
|
3144
|
+
return isBindFast || (nativeBind && arguments.length > 2)
|
3145
|
+
? nativeBind.call.apply(nativeBind, arguments)
|
3146
|
+
: createBound(func, thisArg, slice.call(arguments, 2));
|
3397
3147
|
}
|
3398
3148
|
|
3399
3149
|
/**
|
@@ -3422,7 +3172,6 @@
|
|
3422
3172
|
'useHas': false,
|
3423
3173
|
'useStrict': false,
|
3424
3174
|
'args': 'object',
|
3425
|
-
'init': 'object',
|
3426
3175
|
'top':
|
3427
3176
|
'var funcs = arguments,\n' +
|
3428
3177
|
' length = funcs.length;\n' +
|
@@ -3433,13 +3182,13 @@
|
|
3433
3182
|
' return result\n' +
|
3434
3183
|
'}',
|
3435
3184
|
'inLoop':
|
3436
|
-
'if (isFunction(
|
3437
|
-
' result[index] = bind(
|
3185
|
+
'if (isFunction(value)) {\n' +
|
3186
|
+
' result[index] = bind(value, result)\n' +
|
3438
3187
|
'}'
|
3439
3188
|
});
|
3440
3189
|
|
3441
3190
|
/**
|
3442
|
-
* Creates a
|
3191
|
+
* Creates a function that is the composition of the passed functions,
|
3443
3192
|
* where each function consumes the return value of the function that follows.
|
3444
3193
|
* In math terms, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
|
3445
3194
|
*
|
@@ -3470,7 +3219,7 @@
|
|
3470
3219
|
}
|
3471
3220
|
|
3472
3221
|
/**
|
3473
|
-
* Creates a
|
3222
|
+
* Creates a function that will delay the execution of `func` until after
|
3474
3223
|
* `wait` milliseconds have elapsed since the last time it was invoked. Pass
|
3475
3224
|
* `true` for `immediate` to cause debounce to invoke `func` on the leading,
|
3476
3225
|
* instead of the trailing, edge of the `wait` timeout. Subsequent calls to
|
@@ -3560,7 +3309,44 @@
|
|
3560
3309
|
}
|
3561
3310
|
|
3562
3311
|
/**
|
3563
|
-
* Creates a
|
3312
|
+
* Creates a function that, when called, invokes `object[methodName]` and
|
3313
|
+
* prepends any additional `lateBind` arguments to those passed to the bound
|
3314
|
+
* function. This method differs from `_.bind` by allowing bound functions to
|
3315
|
+
* reference methods that will be redefined or don't yet exist.
|
3316
|
+
*
|
3317
|
+
* @static
|
3318
|
+
* @memberOf _
|
3319
|
+
* @category Functions
|
3320
|
+
* @param {Object} object The object the method belongs to.
|
3321
|
+
* @param {String} methodName The method name.
|
3322
|
+
* @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
|
3323
|
+
* @returns {Function} Returns the new bound function.
|
3324
|
+
* @example
|
3325
|
+
*
|
3326
|
+
* var object = {
|
3327
|
+
* 'name': 'moe',
|
3328
|
+
* 'greet': function(greeting) {
|
3329
|
+
* return greeting + ' ' + this.name;
|
3330
|
+
* }
|
3331
|
+
* };
|
3332
|
+
*
|
3333
|
+
* var func = _.lateBind(object, 'greet', 'hi');
|
3334
|
+
* func();
|
3335
|
+
* // => 'hi moe'
|
3336
|
+
*
|
3337
|
+
* object.greet = function(greeting) {
|
3338
|
+
* return greeting + ', ' + this.name + '!';
|
3339
|
+
* };
|
3340
|
+
*
|
3341
|
+
* func();
|
3342
|
+
* // => 'hi, moe!'
|
3343
|
+
*/
|
3344
|
+
function lateBind(object, methodName) {
|
3345
|
+
return createBound(methodName, object, slice.call(arguments, 2));
|
3346
|
+
}
|
3347
|
+
|
3348
|
+
/**
|
3349
|
+
* Creates a function that memoizes the result of `func`. If `resolver` is
|
3564
3350
|
* passed, it will be used to determine the cache key for storing the result
|
3565
3351
|
* based on the arguments passed to the memoized function. By default, the first
|
3566
3352
|
* argument passed to the memoized function is used as the cache key.
|
@@ -3588,7 +3374,7 @@
|
|
3588
3374
|
}
|
3589
3375
|
|
3590
3376
|
/**
|
3591
|
-
* Creates a
|
3377
|
+
* Creates a function that is restricted to one execution. Repeat calls to
|
3592
3378
|
* the function will return the value of the first call.
|
3593
3379
|
*
|
3594
3380
|
* @static
|
@@ -3621,9 +3407,9 @@
|
|
3621
3407
|
}
|
3622
3408
|
|
3623
3409
|
/**
|
3624
|
-
* Creates a
|
3410
|
+
* Creates a function that, when called, invokes `func` with any additional
|
3625
3411
|
* `partial` arguments prepended to those passed to the new function. This method
|
3626
|
-
* is similar `bind`, except it does **not** alter the `this` binding.
|
3412
|
+
* is similar to `bind`, except it does **not** alter the `this` binding.
|
3627
3413
|
*
|
3628
3414
|
* @static
|
3629
3415
|
* @memberOf _
|
@@ -3639,25 +3425,11 @@
|
|
3639
3425
|
* // => 'hi: moe'
|
3640
3426
|
*/
|
3641
3427
|
function partial(func) {
|
3642
|
-
|
3643
|
-
argsLength = args.length;
|
3644
|
-
|
3645
|
-
return function() {
|
3646
|
-
var result,
|
3647
|
-
others = arguments;
|
3648
|
-
|
3649
|
-
if (others.length) {
|
3650
|
-
args.length = argsLength;
|
3651
|
-
push.apply(args, others);
|
3652
|
-
}
|
3653
|
-
result = args.length == 1 ? func.call(this, args[0]) : func.apply(this, args);
|
3654
|
-
args.length = argsLength;
|
3655
|
-
return result;
|
3656
|
-
};
|
3428
|
+
return createBound(func, slice.call(arguments, 1));
|
3657
3429
|
}
|
3658
3430
|
|
3659
3431
|
/**
|
3660
|
-
* Creates a
|
3432
|
+
* Creates a function that, when executed, will only call the `func`
|
3661
3433
|
* function at most once per every `wait` milliseconds. If the throttled
|
3662
3434
|
* function is invoked more than once during the `wait` timeout, `func` will
|
3663
3435
|
* also be called on the trailing edge of the timeout. Subsequent calls to the
|
@@ -3706,7 +3478,7 @@
|
|
3706
3478
|
}
|
3707
3479
|
|
3708
3480
|
/**
|
3709
|
-
* Creates a
|
3481
|
+
* Creates a function that passes `value` to the `wrapper` function as its
|
3710
3482
|
* first argument. Additional arguments passed to the new function are appended
|
3711
3483
|
* to those passed to the `wrapper` function.
|
3712
3484
|
*
|
@@ -3801,14 +3573,14 @@
|
|
3801
3573
|
forEach(functions(object), function(methodName) {
|
3802
3574
|
var func = lodash[methodName] = object[methodName];
|
3803
3575
|
|
3804
|
-
|
3576
|
+
lodash.prototype[methodName] = function() {
|
3805
3577
|
var args = [this.__wrapped__];
|
3806
3578
|
if (arguments.length) {
|
3807
3579
|
push.apply(args, arguments);
|
3808
3580
|
}
|
3809
3581
|
var result = func.apply(lodash, args);
|
3810
3582
|
if (this.__chain__) {
|
3811
|
-
result = new
|
3583
|
+
result = new lodash(result);
|
3812
3584
|
result.__chain__ = true;
|
3813
3585
|
}
|
3814
3586
|
return result;
|
@@ -3836,13 +3608,12 @@
|
|
3836
3608
|
/**
|
3837
3609
|
* Produces a random number between `min` and `max` (inclusive). If only one
|
3838
3610
|
* argument is passed, a number between `0` and the given number will be returned.
|
3839
|
-
* If no arguments are passed `_.random` will act as `Math.random`.
|
3840
3611
|
*
|
3841
3612
|
* @static
|
3842
3613
|
* @memberOf _
|
3843
3614
|
* @category Utilities
|
3844
|
-
* @param {Number} min The minimum possible value.
|
3845
|
-
* @param {Number} max The maximum possible value.
|
3615
|
+
* @param {Number} [min=0] The minimum possible value.
|
3616
|
+
* @param {Number} [max=1] The maximum possible value.
|
3846
3617
|
* @returns {Number} Returns a random number.
|
3847
3618
|
* @example
|
3848
3619
|
*
|
@@ -3851,13 +3622,10 @@
|
|
3851
3622
|
*
|
3852
3623
|
* _.random(5);
|
3853
3624
|
* // => also a number between 1 and 5
|
3854
|
-
*
|
3855
|
-
* _.random();
|
3856
|
-
* // => an integer between 0 and less than 1
|
3857
3625
|
*/
|
3858
3626
|
function random(min, max) {
|
3859
3627
|
if (min == null && max == null) {
|
3860
|
-
|
3628
|
+
max = 1;
|
3861
3629
|
}
|
3862
3630
|
min = +min || 0;
|
3863
3631
|
if (max == null) {
|
@@ -3877,7 +3645,7 @@
|
|
3877
3645
|
* @memberOf _
|
3878
3646
|
* @category Utilities
|
3879
3647
|
* @param {Object} object The object to inspect.
|
3880
|
-
* @param {String} property The property to get the
|
3648
|
+
* @param {String} property The property to get the value of.
|
3881
3649
|
* @returns {Mixed} Returns the resolved value.
|
3882
3650
|
* @example
|
3883
3651
|
*
|
@@ -3897,10 +3665,7 @@
|
|
3897
3665
|
function result(object, property) {
|
3898
3666
|
// based on Backbone's private `getValue` function
|
3899
3667
|
// https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L1419-1424
|
3900
|
-
|
3901
|
-
return null;
|
3902
|
-
}
|
3903
|
-
var value = object[property];
|
3668
|
+
var value = object ? object[property] : null;
|
3904
3669
|
return isFunction(value) ? object[property]() : value;
|
3905
3670
|
}
|
3906
3671
|
|
@@ -3930,7 +3695,7 @@
|
|
3930
3695
|
* compiled({ 'name': 'moe' });
|
3931
3696
|
* // => 'hello: moe'
|
3932
3697
|
*
|
3933
|
-
* var list = '<% _.forEach(people, function(name) {
|
3698
|
+
* var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
|
3934
3699
|
* _.template(list, { 'people': ['moe', 'larry', 'curly'] });
|
3935
3700
|
* // => '<li>moe</li><li>larry</li><li>curly</li>'
|
3936
3701
|
*
|
@@ -3939,12 +3704,12 @@
|
|
3939
3704
|
* // => '<b><script></b>'
|
3940
3705
|
*
|
3941
3706
|
* // using the internal `print` function in "evaluate" delimiters
|
3942
|
-
* _.template('<% print("Hello " + epithet);
|
3707
|
+
* _.template('<% print("Hello " + epithet); %>.', { 'epithet': 'stooge' });
|
3943
3708
|
* // => 'Hello stooge.'
|
3944
3709
|
*
|
3945
3710
|
* // using custom template delimiter settings
|
3946
3711
|
* _.templateSettings = {
|
3947
|
-
* 'interpolate': /\{\{(
|
3712
|
+
* 'interpolate': /\{\{([\s\S]+?)\}\}/g
|
3948
3713
|
* };
|
3949
3714
|
*
|
3950
3715
|
* _.template('Hello {{ name }}!', { 'name': 'Mustache' });
|
@@ -3972,90 +3737,64 @@
|
|
3972
3737
|
// http://ejohn.org/blog/javascript-micro-templating/
|
3973
3738
|
// and Laura Doktorova's doT.js
|
3974
3739
|
// https://github.com/olado/doT
|
3975
|
-
options || (options = {});
|
3976
3740
|
text += '';
|
3741
|
+
options || (options = {});
|
3977
3742
|
|
3978
3743
|
var isEvaluating,
|
3979
3744
|
result,
|
3980
|
-
|
3981
|
-
evaluateDelimiter = options.evaluate,
|
3982
|
-
interpolateDelimiter = options.interpolate,
|
3745
|
+
index = 0,
|
3983
3746
|
settings = lodash.templateSettings,
|
3747
|
+
source = "__p += '",
|
3984
3748
|
variable = options.variable || settings.variable,
|
3985
3749
|
hasVariable = variable;
|
3986
3750
|
|
3987
|
-
//
|
3988
|
-
|
3989
|
-
|
3990
|
-
|
3991
|
-
|
3992
|
-
|
3993
|
-
|
3994
|
-
|
3995
|
-
|
3996
|
-
|
3997
|
-
|
3998
|
-
|
3999
|
-
|
4000
|
-
|
4001
|
-
|
4002
|
-
|
4003
|
-
|
4004
|
-
|
4005
|
-
|
4006
|
-
}
|
4007
|
-
if (evaluateDelimiter != lastEvaluateDelimiter) {
|
4008
|
-
// generate `reEvaluateDelimiter` to match `_.templateSettings.evaluate`
|
4009
|
-
// and internal `<e%- %>`, `<e%= %>` delimiters
|
4010
|
-
lastEvaluateDelimiter = evaluateDelimiter;
|
4011
|
-
reEvaluateDelimiter = RegExp(
|
4012
|
-
'<e%-([\\s\\S]+?)%>|<e%=([\\s\\S]+?)%>' +
|
4013
|
-
(evaluateDelimiter ? '|' + evaluateDelimiter.source : '')
|
4014
|
-
, 'g');
|
4015
|
-
}
|
4016
|
-
isEvaluating = tokenized.length;
|
4017
|
-
text = text.replace(reEvaluateDelimiter, tokenizeEvaluate);
|
4018
|
-
isEvaluating = isEvaluating != tokenized.length;
|
4019
|
-
|
4020
|
-
// escape characters that cannot be included in string literals and
|
4021
|
-
// detokenize delimiter code snippets
|
4022
|
-
text = "__p += '" + text
|
4023
|
-
.replace(reUnescapedString, escapeStringChar)
|
4024
|
-
.replace(reToken, detokenize) + "';\n";
|
3751
|
+
// compile regexp to match each delimiter
|
3752
|
+
var reDelimiters = RegExp(
|
3753
|
+
(options.escape || settings.escape || reNoMatch).source + '|' +
|
3754
|
+
(options.interpolate || settings.interpolate || reNoMatch).source + '|' +
|
3755
|
+
(options.evaluate || settings.evaluate || reNoMatch).source + '|$'
|
3756
|
+
, 'g');
|
3757
|
+
|
3758
|
+
text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) {
|
3759
|
+
// escape characters that cannot be included in string literals
|
3760
|
+
source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
|
3761
|
+
|
3762
|
+
// replace delimiters with snippets
|
3763
|
+
source +=
|
3764
|
+
escapeValue ? "' +\n__e(" + escapeValue + ") +\n'" :
|
3765
|
+
evaluateValue ? "';\n" + evaluateValue + ";\n__p += '" :
|
3766
|
+
interpolateValue ? "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'" : '';
|
3767
|
+
|
3768
|
+
isEvaluating || (isEvaluating = evaluateValue || reComplexDelimiter.test(escapeValue || interpolateValue));
|
3769
|
+
index = offset + match.length;
|
3770
|
+
});
|
4025
3771
|
|
4026
|
-
|
4027
|
-
tokenized.length = 0;
|
3772
|
+
source += "';\n";
|
4028
3773
|
|
4029
3774
|
// if `variable` is not specified and the template contains "evaluate"
|
4030
3775
|
// delimiters, wrap a with-statement around the generated code to add the
|
4031
3776
|
// data object to the top of the scope chain
|
4032
3777
|
if (!hasVariable) {
|
4033
|
-
variable =
|
4034
|
-
|
3778
|
+
variable = 'obj';
|
4035
3779
|
if (isEvaluating) {
|
4036
|
-
|
3780
|
+
source = 'with (' + variable + ') {\n' + source + '\n}\n';
|
4037
3781
|
}
|
4038
3782
|
else {
|
4039
|
-
if (variable != lastVariable) {
|
4040
|
-
// generate `reDoubleVariable` to match references like `obj.obj` inside
|
4041
|
-
// transformed "escape" and "interpolate" delimiters
|
4042
|
-
lastVariable = variable;
|
4043
|
-
reDoubleVariable = RegExp('(\\(\\s*)' + variable + '\\.' + variable + '\\b', 'g');
|
4044
|
-
}
|
4045
3783
|
// avoid a with-statement by prepending data object references to property names
|
4046
|
-
|
3784
|
+
var reDoubleVariable = RegExp('(\\(\\s*)' + variable + '\\.' + variable + '\\b', 'g');
|
3785
|
+
source = source
|
4047
3786
|
.replace(reInsertVariable, '$&' + variable + '.')
|
4048
3787
|
.replace(reDoubleVariable, '$1__d');
|
4049
3788
|
}
|
4050
3789
|
}
|
4051
3790
|
|
4052
3791
|
// cleanup code by stripping empty strings
|
4053
|
-
|
3792
|
+
source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
|
4054
3793
|
.replace(reEmptyStringMiddle, '$1')
|
4055
3794
|
.replace(reEmptyStringTrailing, '$1;');
|
4056
3795
|
|
4057
3796
|
// frame code as the function body
|
4058
|
-
|
3797
|
+
source = 'function(' + variable + ') {\n' +
|
4059
3798
|
(hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
|
4060
3799
|
'var __t, __p = \'\', __e = _.escape' +
|
4061
3800
|
(isEvaluating
|
@@ -4063,19 +3802,19 @@
|
|
4063
3802
|
'function print() { __p += __j.call(arguments, \'\') }\n'
|
4064
3803
|
: (hasVariable ? '' : ', __d = ' + variable + '.' + variable + ' || ' + variable) + ';\n'
|
4065
3804
|
) +
|
4066
|
-
|
3805
|
+
source +
|
4067
3806
|
'return __p\n}';
|
4068
3807
|
|
4069
|
-
//
|
3808
|
+
// use a sourceURL for easier debugging
|
4070
3809
|
// http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
|
4071
|
-
|
4072
|
-
|
4073
|
-
|
3810
|
+
var sourceURL = useSourceURL
|
3811
|
+
? '\n//@ sourceURL=/lodash/template/source[' + (templateCounter++) + ']'
|
3812
|
+
: '';
|
4074
3813
|
|
4075
3814
|
try {
|
4076
|
-
result = Function('_', 'return ' +
|
3815
|
+
result = Function('_', 'return ' + source + sourceURL)(lodash);
|
4077
3816
|
} catch(e) {
|
4078
|
-
e.source =
|
3817
|
+
e.source = source;
|
4079
3818
|
throw e;
|
4080
3819
|
}
|
4081
3820
|
|
@@ -4085,39 +3824,42 @@
|
|
4085
3824
|
// provide the compiled function's source via its `toString` method, in
|
4086
3825
|
// supported environments, or the `source` property as a convenience for
|
4087
3826
|
// inlining compiled templates during the build process
|
4088
|
-
result.source =
|
3827
|
+
result.source = source;
|
4089
3828
|
return result;
|
4090
3829
|
}
|
4091
3830
|
|
4092
3831
|
/**
|
4093
|
-
* Executes the `callback` function `n` times
|
4094
|
-
* `
|
3832
|
+
* Executes the `callback` function `n` times, returning an array of the results
|
3833
|
+
* of each `callback` execution. The `callback` is bound to `thisArg` and invoked
|
3834
|
+
* with one argument; (index).
|
4095
3835
|
*
|
4096
3836
|
* @static
|
4097
3837
|
* @memberOf _
|
4098
3838
|
* @category Utilities
|
4099
3839
|
* @param {Number} n The number of times to execute the callback.
|
4100
3840
|
* @param {Function} callback The function called per iteration.
|
4101
|
-
* @param {Mixed} [thisArg] The `this` binding
|
3841
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3842
|
+
* @returns {Array} Returns a new array of the results of each `callback` execution.
|
4102
3843
|
* @example
|
4103
3844
|
*
|
4104
|
-
* _.times(3,
|
4105
|
-
* // =>
|
3845
|
+
* var diceRolls = _.times(3, _.partial(_.random, 1, 6));
|
3846
|
+
* // => [3, 6, 4]
|
4106
3847
|
*
|
4107
|
-
* _.times(3, function(n) {
|
4108
|
-
* // =>
|
3848
|
+
* _.times(3, function(n) { mage.castSpell(n); });
|
3849
|
+
* // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
|
3850
|
+
*
|
3851
|
+
* _.times(3, function(n) { this.cast(n); }, mage);
|
3852
|
+
* // => also calls `mage.castSpell(n)` three times
|
4109
3853
|
*/
|
4110
3854
|
function times(n, callback, thisArg) {
|
4111
|
-
|
4112
|
-
|
4113
|
-
|
4114
|
-
|
4115
|
-
|
4116
|
-
|
4117
|
-
while (++index < n) {
|
4118
|
-
callback(index);
|
4119
|
-
}
|
3855
|
+
n = +n || 0;
|
3856
|
+
var index = -1,
|
3857
|
+
result = Array(n);
|
3858
|
+
|
3859
|
+
while (++index < n) {
|
3860
|
+
result[index] = callback.call(thisArg, index);
|
4120
3861
|
}
|
3862
|
+
return result;
|
4121
3863
|
}
|
4122
3864
|
|
4123
3865
|
/**
|
@@ -4183,7 +3925,7 @@
|
|
4183
3925
|
* // => 'moe is 40'
|
4184
3926
|
*/
|
4185
3927
|
function chain(value) {
|
4186
|
-
value = new
|
3928
|
+
value = new lodash(value);
|
4187
3929
|
value.__chain__ = true;
|
4188
3930
|
return value;
|
4189
3931
|
}
|
@@ -4201,7 +3943,7 @@
|
|
4201
3943
|
* @returns {Mixed} Returns `value`.
|
4202
3944
|
* @example
|
4203
3945
|
*
|
4204
|
-
* _.chain([1,2,3,200])
|
3946
|
+
* _.chain([1, 2, 3, 200])
|
4205
3947
|
* .filter(function(num) { return num % 2 == 0; })
|
4206
3948
|
* .tap(alert)
|
4207
3949
|
* .map(function(num) { return num * num })
|
@@ -4257,7 +3999,7 @@
|
|
4257
3999
|
* @memberOf _
|
4258
4000
|
* @type String
|
4259
4001
|
*/
|
4260
|
-
lodash.VERSION = '0.
|
4002
|
+
lodash.VERSION = '0.8.1';
|
4261
4003
|
|
4262
4004
|
// assign static methods
|
4263
4005
|
lodash.after = after;
|
@@ -4306,12 +4048,14 @@
|
|
4306
4048
|
lodash.isNull = isNull;
|
4307
4049
|
lodash.isNumber = isNumber;
|
4308
4050
|
lodash.isObject = isObject;
|
4051
|
+
lodash.isPlainObject = isPlainObject;
|
4309
4052
|
lodash.isRegExp = isRegExp;
|
4310
4053
|
lodash.isString = isString;
|
4311
4054
|
lodash.isUndefined = isUndefined;
|
4312
4055
|
lodash.keys = keys;
|
4313
4056
|
lodash.last = last;
|
4314
4057
|
lodash.lastIndexOf = lastIndexOf;
|
4058
|
+
lodash.lateBind = lateBind;
|
4315
4059
|
lodash.map = map;
|
4316
4060
|
lodash.max = max;
|
4317
4061
|
lodash.memoize = memoize;
|
@@ -4377,22 +4121,19 @@
|
|
4377
4121
|
|
4378
4122
|
/*--------------------------------------------------------------------------*/
|
4379
4123
|
|
4380
|
-
//
|
4381
|
-
LoDash.prototype = lodash.prototype;
|
4382
|
-
|
4383
|
-
// add all static functions to `LoDash.prototype`
|
4124
|
+
// add all static functions to `lodash.prototype`
|
4384
4125
|
mixin(lodash);
|
4385
4126
|
|
4386
|
-
// add `
|
4127
|
+
// add `lodash.prototype.chain` after calling `mixin()` to avoid overwriting
|
4387
4128
|
// it with the wrapped `lodash.chain`
|
4388
|
-
|
4389
|
-
|
4129
|
+
lodash.prototype.chain = wrapperChain;
|
4130
|
+
lodash.prototype.value = wrapperValue;
|
4390
4131
|
|
4391
4132
|
// add all mutator Array functions to the wrapper.
|
4392
4133
|
forEach(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
|
4393
4134
|
var func = ArrayProto[methodName];
|
4394
4135
|
|
4395
|
-
|
4136
|
+
lodash.prototype[methodName] = function() {
|
4396
4137
|
var value = this.__wrapped__;
|
4397
4138
|
func.apply(value, arguments);
|
4398
4139
|
|
@@ -4402,7 +4143,7 @@
|
|
4402
4143
|
delete value[0];
|
4403
4144
|
}
|
4404
4145
|
if (this.__chain__) {
|
4405
|
-
value = new
|
4146
|
+
value = new lodash(value);
|
4406
4147
|
value.__chain__ = true;
|
4407
4148
|
}
|
4408
4149
|
return value;
|
@@ -4413,12 +4154,12 @@
|
|
4413
4154
|
forEach(['concat', 'join', 'slice'], function(methodName) {
|
4414
4155
|
var func = ArrayProto[methodName];
|
4415
4156
|
|
4416
|
-
|
4157
|
+
lodash.prototype[methodName] = function() {
|
4417
4158
|
var value = this.__wrapped__,
|
4418
4159
|
result = func.apply(value, arguments);
|
4419
4160
|
|
4420
4161
|
if (this.__chain__) {
|
4421
|
-
result = new
|
4162
|
+
result = new lodash(result);
|
4422
4163
|
result.__chain__ = true;
|
4423
4164
|
}
|
4424
4165
|
return result;
|