lodash-rails 0.8.2 → 0.9.0
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 +616 -640
- data/vendor/assets/javascripts/lodash.min.js +36 -36
- metadata +2 -2
data/README.md
CHANGED
data/lib/lodash/rails/version.rb
CHANGED
@@ -1,27 +1,31 @@
|
|
1
1
|
/*!
|
2
|
-
* Lo-Dash v0.
|
2
|
+
* Lo-Dash v0.9.0 <http://lodash.com>
|
3
3
|
* (c) 2012 John-David Dalton <http://allyoucanleet.com/>
|
4
4
|
* Based on Underscore.js 1.4.2 <http://underscorejs.org>
|
5
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
|
-
'use strict';
|
10
9
|
|
11
10
|
/** Detect free variable `exports` */
|
12
|
-
var freeExports = typeof exports == 'object' && exports
|
13
|
-
(typeof global == 'object' && global && global == global.global && (window = global), exports);
|
11
|
+
var freeExports = typeof exports == 'object' && exports;
|
14
12
|
|
15
|
-
/**
|
16
|
-
var
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
/** Detect free variable `global` and use it as `window` */
|
14
|
+
var freeGlobal = typeof global == 'object' && global;
|
15
|
+
if (freeGlobal.global === freeGlobal) {
|
16
|
+
window = freeGlobal;
|
17
|
+
}
|
18
|
+
|
19
|
+
/** Used for array and object method references */
|
20
|
+
var arrayRef = [],
|
21
|
+
objectRef = {};
|
21
22
|
|
22
23
|
/** Used to generate unique IDs */
|
23
24
|
var idCounter = 0;
|
24
25
|
|
26
|
+
/** Used internally to indicate various things */
|
27
|
+
var indicatorObject = {};
|
28
|
+
|
25
29
|
/** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */
|
26
30
|
var largeArraySize = 30;
|
27
31
|
|
@@ -47,7 +51,7 @@
|
|
47
51
|
|
48
52
|
/** Used to detect if a method is native */
|
49
53
|
var reNative = RegExp('^' +
|
50
|
-
(
|
54
|
+
(objectRef.valueOf + '')
|
51
55
|
.replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&')
|
52
56
|
.replace(/valueOf|for [^\]]+/g, '.+?') + '$'
|
53
57
|
);
|
@@ -72,14 +76,14 @@
|
|
72
76
|
|
73
77
|
/** Native method shortcuts */
|
74
78
|
var ceil = Math.ceil,
|
75
|
-
concat =
|
79
|
+
concat = arrayRef.concat,
|
76
80
|
floor = Math.floor,
|
77
81
|
getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
|
78
|
-
hasOwnProperty =
|
79
|
-
push =
|
80
|
-
propertyIsEnumerable =
|
81
|
-
slice =
|
82
|
-
toString =
|
82
|
+
hasOwnProperty = objectRef.hasOwnProperty,
|
83
|
+
push = arrayRef.push,
|
84
|
+
propertyIsEnumerable = objectRef.propertyIsEnumerable,
|
85
|
+
slice = arrayRef.slice,
|
86
|
+
toString = objectRef.toString;
|
83
87
|
|
84
88
|
/* Native method shortcuts for methods with the same name as other `lodash` methods */
|
85
89
|
var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
|
@@ -101,10 +105,6 @@
|
|
101
105
|
regexpClass = '[object RegExp]',
|
102
106
|
stringClass = '[object String]';
|
103
107
|
|
104
|
-
/** Timer shortcuts */
|
105
|
-
var clearTimeout = window.clearTimeout,
|
106
|
-
setTimeout = window.setTimeout;
|
107
|
-
|
108
108
|
/**
|
109
109
|
* Detect the JScript [[DontEnum]] bug:
|
110
110
|
*
|
@@ -113,6 +113,9 @@
|
|
113
113
|
*/
|
114
114
|
var hasDontEnumBug;
|
115
115
|
|
116
|
+
/** Detect if own properties are iterated after inherited properties (IE < 9) */
|
117
|
+
var iteratesOwnLast;
|
118
|
+
|
116
119
|
/**
|
117
120
|
* Detect if `Array#shift` and `Array#splice` augment array-like objects
|
118
121
|
* incorrectly:
|
@@ -123,26 +126,21 @@
|
|
123
126
|
* The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
|
124
127
|
* is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
|
125
128
|
*/
|
126
|
-
var hasObjectSpliceBug
|
127
|
-
|
128
|
-
/** Detect if own properties are iterated after inherited properties (IE < 9) */
|
129
|
-
var iteratesOwnLast;
|
129
|
+
var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 },
|
130
|
+
arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]);
|
130
131
|
|
131
132
|
/** Detect if an `arguments` object's indexes are non-enumerable (IE < 9) */
|
132
133
|
var noArgsEnum = true;
|
133
134
|
|
134
135
|
(function() {
|
135
|
-
var
|
136
|
-
props = [];
|
137
|
-
|
136
|
+
var props = [];
|
138
137
|
function ctor() { this.x = 1; }
|
139
138
|
ctor.prototype = { 'valueOf': 1, 'y': 1 };
|
140
139
|
for (var prop in new ctor) { props.push(prop); }
|
141
140
|
for (prop in arguments) { noArgsEnum = !prop; }
|
142
141
|
|
143
|
-
hasDontEnumBug = (props
|
142
|
+
hasDontEnumBug = !/valueOf/.test(props);
|
144
143
|
iteratesOwnLast = props[0] != 'x';
|
145
|
-
hasObjectSpliceBug = (props.splice.call(object, 0, 1), object[0]);
|
146
144
|
}(1));
|
147
145
|
|
148
146
|
/** Detect if an `arguments` object's [[Class]] is unresolvable (Firefox < 4, IE < 9) */
|
@@ -174,9 +172,6 @@
|
|
174
172
|
/* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */
|
175
173
|
var isKeysFast = nativeKeys && /^.+$|true/.test(nativeKeys + !!window.attachEvent);
|
176
174
|
|
177
|
-
/* Detect if strict mode, "use strict", is inferred to be fast (V8) */
|
178
|
-
var isStrictFast = !isBindFast;
|
179
|
-
|
180
175
|
/**
|
181
176
|
* Detect if sourceURL syntax is usable without erroring:
|
182
177
|
*
|
@@ -194,12 +189,6 @@
|
|
194
189
|
var useSourceURL = (Function('//@')(), !window.attachEvent);
|
195
190
|
} catch(e) { }
|
196
191
|
|
197
|
-
/** Used to identify object classifications that are array-like */
|
198
|
-
var arrayLikeClasses = {};
|
199
|
-
arrayLikeClasses[boolClass] = arrayLikeClasses[dateClass] = arrayLikeClasses[funcClass] =
|
200
|
-
arrayLikeClasses[numberClass] = arrayLikeClasses[objectClass] = arrayLikeClasses[regexpClass] = false;
|
201
|
-
arrayLikeClasses[argsClass] = arrayLikeClasses[arrayClass] = arrayLikeClasses[stringClass] = true;
|
202
|
-
|
203
192
|
/** Used to identify object classifications that `_.clone` supports */
|
204
193
|
var cloneableClasses = {};
|
205
194
|
cloneableClasses[argsClass] = cloneableClasses[funcClass] = false;
|
@@ -214,8 +203,7 @@
|
|
214
203
|
'object': true,
|
215
204
|
'number': false,
|
216
205
|
'string': false,
|
217
|
-
'undefined': false
|
218
|
-
'unknown': true
|
206
|
+
'undefined': false
|
219
207
|
};
|
220
208
|
|
221
209
|
/** Used to escape characters for inclusion in compiled string literals */
|
@@ -311,21 +299,21 @@
|
|
311
299
|
*/
|
312
300
|
var iteratorTemplate = template(
|
313
301
|
// conditional strict mode
|
314
|
-
'<% if (useStrict) { %>\'use strict\';\n<% } %>' +
|
302
|
+
'<% if (obj.useStrict) { %>\'use strict\';\n<% } %>' +
|
315
303
|
|
316
304
|
// the `iteratee` may be reassigned by the `top` snippet
|
317
305
|
'var index, value, iteratee = <%= firstArg %>, ' +
|
318
306
|
// assign the `result` variable an initial value
|
319
|
-
'result = <%=
|
307
|
+
'result = <%= firstArg %>;\n' +
|
320
308
|
// exit early if the first argument is falsey
|
321
309
|
'if (!<%= firstArg %>) return result;\n' +
|
322
310
|
// add code before the iteration branches
|
323
311
|
'<%= top %>;\n' +
|
324
312
|
|
325
|
-
//
|
326
|
-
'<% if (
|
327
|
-
'var length = iteratee.length; index = -1
|
328
|
-
'
|
313
|
+
// array-like iteration:
|
314
|
+
'<% if (arrayLoop) { %>' +
|
315
|
+
'var length = iteratee.length; index = -1;\n' +
|
316
|
+
'if (typeof length == \'number\') {' +
|
329
317
|
|
330
318
|
// add support for accessing string characters by index if needed
|
331
319
|
' <% if (noCharByIndex) { %>\n' +
|
@@ -334,25 +322,22 @@
|
|
334
322
|
' }' +
|
335
323
|
' <% } %>\n' +
|
336
324
|
|
337
|
-
|
325
|
+
// iterate over the array-like value
|
338
326
|
' while (++index < length) {\n' +
|
339
327
|
' value = iteratee[index];\n' +
|
340
|
-
' <%=
|
341
|
-
' }' +
|
342
|
-
'
|
343
|
-
'
|
344
|
-
|
345
|
-
// the following branch is for iterating an object's own/inherited properties
|
346
|
-
'<% if (objectBranch) { %>' +
|
347
|
-
' <% if (arrayBranch) { %>\nelse {' +
|
328
|
+
' <%= arrayLoop %>\n' +
|
329
|
+
' }\n' +
|
330
|
+
'}\n' +
|
331
|
+
'else {' +
|
348
332
|
|
333
|
+
// object iteration:
|
349
334
|
// add support for iterating over `arguments` objects if needed
|
350
335
|
' <% } else if (noArgsEnum) { %>\n' +
|
351
336
|
' var length = iteratee.length; index = -1;\n' +
|
352
337
|
' if (length && isArguments(iteratee)) {\n' +
|
353
338
|
' while (++index < length) {\n' +
|
354
339
|
' value = iteratee[index += \'\'];\n' +
|
355
|
-
' <%=
|
340
|
+
' <%= objectLoop %>\n' +
|
356
341
|
' }\n' +
|
357
342
|
' } else {' +
|
358
343
|
' <% } %>' +
|
@@ -373,18 +358,16 @@
|
|
373
358
|
' var ownIndex = -1,\n' +
|
374
359
|
' ownProps = objectTypes[typeof iteratee] ? nativeKeys(iteratee) : [],\n' +
|
375
360
|
' length = ownProps.length;\n\n' +
|
376
|
-
' <%= objectBranch.beforeLoop %>;\n' +
|
377
361
|
' while (++ownIndex < length) {\n' +
|
378
362
|
' index = ownProps[ownIndex];\n' +
|
379
363
|
' <% if (!hasDontEnumBug) { %>if (!(skipProto && index == \'prototype\')) {\n <% } %>' +
|
380
364
|
' value = iteratee[index];\n' +
|
381
|
-
' <%=
|
365
|
+
' <%= objectLoop %>\n' +
|
382
366
|
' <% if (!hasDontEnumBug) { %>}\n<% } %>' +
|
383
367
|
' }' +
|
384
368
|
|
385
369
|
// else using a for-in loop
|
386
370
|
' <% } else { %>\n' +
|
387
|
-
' <%= objectBranch.beforeLoop %>;\n' +
|
388
371
|
' for (index in iteratee) {<%' +
|
389
372
|
' if (!hasDontEnumBug || useHas) { %>\n if (<%' +
|
390
373
|
' if (!hasDontEnumBug) { %>!(skipProto && index == \'prototype\')<% }' +
|
@@ -393,7 +376,7 @@
|
|
393
376
|
' %>) {' +
|
394
377
|
' <% } %>\n' +
|
395
378
|
' value = iteratee[index];\n' +
|
396
|
-
' <%=
|
379
|
+
' <%= objectLoop %>;' +
|
397
380
|
' <% if (!hasDontEnumBug || useHas) { %>\n }<% } %>\n' +
|
398
381
|
' }' +
|
399
382
|
' <% } %>' +
|
@@ -411,12 +394,11 @@
|
|
411
394
|
' %>!(ctor && ctor.prototype === iteratee) && <%' +
|
412
395
|
' } %>hasOwnProperty.call(iteratee, index)) {\n' +
|
413
396
|
' value = iteratee[index];\n' +
|
414
|
-
' <%=
|
397
|
+
' <%= objectLoop %>\n' +
|
415
398
|
' }' +
|
416
399
|
' <% } %>' +
|
417
400
|
' <% } %>' +
|
418
|
-
' <% if (
|
419
|
-
'<% } %>\n' +
|
401
|
+
' <% if (arrayLoop || noArgsEnum) { %>\n}<% } %>\n' +
|
420
402
|
|
421
403
|
// add code to the bottom of the iteration function
|
422
404
|
'<%= bottom %>;\n' +
|
@@ -425,88 +407,29 @@
|
|
425
407
|
);
|
426
408
|
|
427
409
|
/**
|
428
|
-
* Reusable iterator options shared by
|
429
|
-
* `countBy`, `every`, `filter`, `find`, `forEach`, `forIn`, `forOwn`, `groupBy`,
|
430
|
-
* `map`, `reject`, `some`, and `sortBy`.
|
410
|
+
* Reusable iterator options shared by `forEach`, `forIn`, and `forOwn`.
|
431
411
|
*/
|
432
|
-
var
|
412
|
+
var forEachIteratorOptions = {
|
433
413
|
'args': 'collection, callback, thisArg',
|
434
414
|
'top': 'callback = createCallback(callback, thisArg)',
|
435
|
-
'
|
415
|
+
'arrayLoop': 'if (callback(value, index, collection) === false) return result',
|
416
|
+
'objectLoop': 'if (callback(value, index, collection) === false) return result'
|
436
417
|
};
|
437
418
|
|
438
|
-
/** Reusable iterator options for `
|
439
|
-
var countByIteratorOptions = {
|
440
|
-
'init': '{}',
|
441
|
-
'top': 'callback = createCallback(callback, thisArg)',
|
442
|
-
'inLoop':
|
443
|
-
'var prop = callback(value, index, collection);\n' +
|
444
|
-
'(hasOwnProperty.call(result, prop) ? result[prop]++ : result[prop] = 1)'
|
445
|
-
};
|
446
|
-
|
447
|
-
/** Reusable iterator options for `every` and `some` */
|
448
|
-
var everyIteratorOptions = {
|
449
|
-
'init': 'true',
|
450
|
-
'inLoop': 'if (!callback(value, index, collection)) return !result'
|
451
|
-
};
|
452
|
-
|
453
|
-
/** Reusable iterator options for `defaults` and `extend` */
|
419
|
+
/** Reusable iterator options for `defaults`, and `extend` */
|
454
420
|
var extendIteratorOptions = {
|
455
421
|
'useHas': false,
|
456
|
-
'useStrict': false,
|
457
422
|
'args': 'object',
|
458
423
|
'top':
|
459
424
|
'for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {\n' +
|
460
425
|
' if (iteratee = arguments[argsIndex]) {',
|
461
|
-
'
|
426
|
+
'objectLoop': 'result[index] = value',
|
462
427
|
'bottom': ' }\n}'
|
463
428
|
};
|
464
429
|
|
465
|
-
/** Reusable iterator options for `filter`, `reject`, and `where` */
|
466
|
-
var filterIteratorOptions = {
|
467
|
-
'init': '[]',
|
468
|
-
'inLoop': 'callback(value, index, collection) && result.push(value)'
|
469
|
-
};
|
470
|
-
|
471
|
-
/** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */
|
472
|
-
var forEachIteratorOptions = {
|
473
|
-
'top': 'callback = createCallback(callback, thisArg)'
|
474
|
-
};
|
475
|
-
|
476
430
|
/** Reusable iterator options for `forIn` and `forOwn` */
|
477
431
|
var forOwnIteratorOptions = {
|
478
|
-
'
|
479
|
-
'object': baseIteratorOptions.inLoop
|
480
|
-
}
|
481
|
-
};
|
482
|
-
|
483
|
-
/** Reusable iterator options for `invoke`, `map`, `pluck`, and `sortBy` */
|
484
|
-
var mapIteratorOptions = {
|
485
|
-
'init': 'collection || []',
|
486
|
-
'beforeLoop': {
|
487
|
-
'array': 'result = Array(length)',
|
488
|
-
'object': 'result = ' + (isKeysFast ? 'Array(length)' : '[]')
|
489
|
-
},
|
490
|
-
'inLoop': {
|
491
|
-
'array': 'result[index] = callback(value, index, collection)',
|
492
|
-
'object': 'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '(callback(value, index, collection))'
|
493
|
-
}
|
494
|
-
};
|
495
|
-
|
496
|
-
/** Reusable iterator options for `omit` and `pick` */
|
497
|
-
var omitIteratorOptions = {
|
498
|
-
'useHas': false,
|
499
|
-
'args': 'object, callback, thisArg',
|
500
|
-
'init': '{}',
|
501
|
-
'top':
|
502
|
-
'var isFunc = typeof callback == \'function\';\n' +
|
503
|
-
'if (isFunc) callback = createCallback(callback, thisArg);\n' +
|
504
|
-
'else var props = concat.apply(ArrayProto, arguments)',
|
505
|
-
'inLoop':
|
506
|
-
'if (isFunc\n' +
|
507
|
-
' ? !callback(value, index, object)\n' +
|
508
|
-
' : indexOf(props, index) < 0\n' +
|
509
|
-
') result[index] = value'
|
432
|
+
'arrayLoop': null
|
510
433
|
};
|
511
434
|
|
512
435
|
/*--------------------------------------------------------------------------*/
|
@@ -657,89 +580,52 @@
|
|
657
580
|
}
|
658
581
|
|
659
582
|
/**
|
660
|
-
* Creates compiled iteration functions.
|
661
|
-
* to iterate over only objects if the first argument of `options.args` is
|
662
|
-
* "object" or `options.inLoop.array` is falsey.
|
583
|
+
* Creates compiled iteration functions.
|
663
584
|
*
|
664
585
|
* @private
|
665
|
-
* @param {Object} [options1, options2, ...] The compile options
|
666
|
-
*
|
586
|
+
* @param {Object} [options1, options2, ...] The compile options object(s).
|
667
587
|
* useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
|
668
|
-
*
|
669
|
-
* useStrict - A boolean to specify including the "use strict" directive.
|
670
|
-
*
|
671
588
|
* args - A string of comma separated arguments the iteration function will accept.
|
672
|
-
*
|
673
|
-
* init - A string to specify the initial value of the `result` variable.
|
674
|
-
*
|
675
589
|
* top - A string of code to execute before the iteration branches.
|
676
|
-
*
|
677
|
-
*
|
678
|
-
*
|
679
|
-
*
|
680
|
-
* inLoop - A string or object containing an "array" or "object" property
|
681
|
-
* of code to execute in the array or object loops.
|
682
|
-
*
|
683
|
-
* bottom - A string of code to execute after the iteration branches but
|
684
|
-
* before the `result` is returned.
|
590
|
+
* arrayLoop - A string of code to execute in the array loop.
|
591
|
+
* objectLoop - A string of code to execute in the object loop.
|
592
|
+
* bottom - A string of code to execute after the iteration branches.
|
685
593
|
*
|
686
594
|
* @returns {Function} Returns the compiled function.
|
687
595
|
*/
|
688
596
|
function createIterator() {
|
689
597
|
var data = {
|
598
|
+
'arrayLoop': '',
|
690
599
|
'bottom': '',
|
691
600
|
'hasDontEnumBug': hasDontEnumBug,
|
692
|
-
'init': '',
|
693
601
|
'isKeysFast': isKeysFast,
|
602
|
+
'objectLoop': '',
|
694
603
|
'noArgsEnum': noArgsEnum,
|
695
604
|
'noCharByIndex': noCharByIndex,
|
696
605
|
'shadowed': shadowed,
|
697
606
|
'top': '',
|
698
|
-
'useHas': true
|
699
|
-
'useStrict': isStrictFast,
|
700
|
-
'arrayBranch': { 'beforeLoop': '' },
|
701
|
-
'objectBranch': { 'beforeLoop': '' }
|
607
|
+
'useHas': true
|
702
608
|
};
|
703
609
|
|
704
|
-
var object,
|
705
|
-
index = -1;
|
706
|
-
|
707
610
|
// merge options into a template data object
|
708
|
-
|
709
|
-
for (var
|
710
|
-
|
711
|
-
// keep this regexp explicit for the build pre-process
|
712
|
-
if (/beforeLoop|inLoop/.test(prop)) {
|
713
|
-
if (typeof value == 'string') {
|
714
|
-
value = { 'array': value, 'object': value };
|
715
|
-
}
|
716
|
-
data.arrayBranch[prop] = value.array;
|
717
|
-
data.objectBranch[prop] = value.object;
|
718
|
-
} else {
|
719
|
-
data[prop] = value;
|
720
|
-
}
|
611
|
+
for (var object, index = 0; object = arguments[index]; index++) {
|
612
|
+
for (var key in object) {
|
613
|
+
data[key] = object[key];
|
721
614
|
}
|
722
615
|
}
|
723
|
-
// set additional template `data` properties
|
724
616
|
var args = data.args;
|
725
|
-
|
726
|
-
|
727
|
-
}
|
617
|
+
data.firstArg = /^[^,]+/.exec(args)[0];
|
618
|
+
|
728
619
|
// create the function factory
|
729
620
|
var factory = Function(
|
730
|
-
'
|
731
|
-
'
|
732
|
-
|
733
|
-
'slice, stringClass, toString, undefined',
|
734
|
-
'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' +
|
735
|
-
'return callee'
|
621
|
+
'createCallback, hasOwnProperty, isArguments, objectTypes, nativeKeys, ' +
|
622
|
+
'propertyIsEnumerable, stringClass, toString',
|
623
|
+
'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
|
736
624
|
);
|
737
625
|
// return the compiled function
|
738
626
|
return factory(
|
739
|
-
|
740
|
-
|
741
|
-
isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable,
|
742
|
-
slice, stringClass, toString
|
627
|
+
createCallback, hasOwnProperty, isArguments, objectTypes, nativeKeys,
|
628
|
+
propertyIsEnumerable, stringClass, toString
|
743
629
|
);
|
744
630
|
}
|
745
631
|
|
@@ -788,25 +674,6 @@
|
|
788
674
|
|
789
675
|
/*--------------------------------------------------------------------------*/
|
790
676
|
|
791
|
-
/**
|
792
|
-
* Creates an object composed of the inverted keys and values of the given `object`.
|
793
|
-
*
|
794
|
-
* @static
|
795
|
-
* @memberOf _
|
796
|
-
* @category Objects
|
797
|
-
* @param {Object} object The object to invert.
|
798
|
-
* @returns {Object} Returns the created inverted object.
|
799
|
-
* @example
|
800
|
-
*
|
801
|
-
* _.invert({ 'first': 'Moe', 'second': 'Larry', 'third': 'Curly' });
|
802
|
-
* // => { 'Moe': 'first', 'Larry': 'second', 'Curly': 'third' } (order is not guaranteed)
|
803
|
-
*/
|
804
|
-
var invert = createIterator({
|
805
|
-
'args': 'object',
|
806
|
-
'init': '{}',
|
807
|
-
'inLoop': 'result[value] = index'
|
808
|
-
});
|
809
|
-
|
810
677
|
/**
|
811
678
|
* Checks if `value` is an `arguments` object.
|
812
679
|
*
|
@@ -834,83 +701,58 @@
|
|
834
701
|
}
|
835
702
|
|
836
703
|
/**
|
837
|
-
*
|
704
|
+
* Iterates over `object`'s own and inherited enumerable properties, executing
|
705
|
+
* the `callback` for each property. The `callback` is bound to `thisArg` and
|
706
|
+
* invoked with three arguments; (value, key, object). Callbacks may exit iteration
|
707
|
+
* early by explicitly returning `false`.
|
838
708
|
*
|
839
709
|
* @static
|
840
710
|
* @memberOf _
|
841
711
|
* @category Objects
|
842
|
-
* @param {
|
843
|
-
* @
|
712
|
+
* @param {Object} object The object to iterate over.
|
713
|
+
* @param {Function} callback The function called per iteration.
|
714
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
715
|
+
* @returns {Object} Returns `object`.
|
844
716
|
* @example
|
845
717
|
*
|
846
|
-
*
|
847
|
-
*
|
848
|
-
*
|
849
|
-
* _.isArray([1, 2, 3]);
|
850
|
-
* // => true
|
851
|
-
*/
|
852
|
-
var isArray = nativeIsArray || function(value) {
|
853
|
-
return toString.call(value) == arrayClass;
|
854
|
-
};
|
855
|
-
|
856
|
-
/**
|
857
|
-
* Checks if `value` is a function.
|
718
|
+
* function Dog(name) {
|
719
|
+
* this.name = name;
|
720
|
+
* }
|
858
721
|
*
|
859
|
-
*
|
860
|
-
*
|
861
|
-
*
|
862
|
-
* @param {Mixed} value The value to check.
|
863
|
-
* @returns {Boolean} Returns `true` if the `value` is a function, else `false`.
|
864
|
-
* @example
|
722
|
+
* Dog.prototype.bark = function() {
|
723
|
+
* alert('Woof, woof!');
|
724
|
+
* };
|
865
725
|
*
|
866
|
-
* _.
|
867
|
-
*
|
726
|
+
* _.forIn(new Dog('Dagny'), function(value, key) {
|
727
|
+
* alert(key);
|
728
|
+
* });
|
729
|
+
* // => alerts 'name' and 'bark' (order is not guaranteed)
|
868
730
|
*/
|
869
|
-
|
870
|
-
|
871
|
-
}
|
872
|
-
// fallback for older versions of Chrome and Safari
|
873
|
-
if (isFunction(/x/)) {
|
874
|
-
isFunction = function(value) {
|
875
|
-
return toString.call(value) == funcClass;
|
876
|
-
};
|
877
|
-
}
|
731
|
+
var forIn = createIterator(forEachIteratorOptions, forOwnIteratorOptions, {
|
732
|
+
'useHas': false
|
733
|
+
});
|
878
734
|
|
879
735
|
/**
|
880
|
-
*
|
736
|
+
* Iterates over `object`'s own enumerable properties, executing the `callback`
|
737
|
+
* for each property. The `callback` is bound to `thisArg` and invoked with three
|
738
|
+
* arguments; (value, key, object). Callbacks may exit iteration early by explicitly
|
739
|
+
* returning `false`.
|
881
740
|
*
|
882
741
|
* @static
|
883
742
|
* @memberOf _
|
884
743
|
* @category Objects
|
885
|
-
* @param {
|
886
|
-
* @
|
744
|
+
* @param {Object} object The object to iterate over.
|
745
|
+
* @param {Function} callback The function called per iteration.
|
746
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
747
|
+
* @returns {Object} Returns `object`.
|
887
748
|
* @example
|
888
749
|
*
|
889
|
-
* function
|
890
|
-
*
|
891
|
-
*
|
892
|
-
*
|
893
|
-
*
|
894
|
-
* _.isPlainObject(new Stooge('moe', 40));
|
895
|
-
* // false
|
896
|
-
*
|
897
|
-
* _.isPlainObject([1, 2, 3]);
|
898
|
-
* // false
|
899
|
-
*
|
900
|
-
* _.isPlainObject({ 'name': 'moe', 'age': 40 });
|
901
|
-
* // => true
|
750
|
+
* _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
|
751
|
+
* alert(key);
|
752
|
+
* });
|
753
|
+
* // => alerts '0', '1', and 'length' (order is not guaranteed)
|
902
754
|
*/
|
903
|
-
var
|
904
|
-
if (!(value && typeof value == 'object')) {
|
905
|
-
return false;
|
906
|
-
}
|
907
|
-
var valueOf = value.valueOf,
|
908
|
-
objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
|
909
|
-
|
910
|
-
return objProto
|
911
|
-
? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value))
|
912
|
-
: isPlainFallback(value);
|
913
|
-
};
|
755
|
+
var forOwn = createIterator(forEachIteratorOptions, forOwnIteratorOptions);
|
914
756
|
|
915
757
|
/**
|
916
758
|
* A fallback implementation of `isPlainObject` that checks if a given `value`
|
@@ -922,7 +764,7 @@
|
|
922
764
|
* @param {Mixed} value The value to check.
|
923
765
|
* @returns {Boolean} Returns `true` if `value` is a plain object, else `false`.
|
924
766
|
*/
|
925
|
-
function
|
767
|
+
function shimIsPlainObject(value) {
|
926
768
|
// avoid non-objects and false positives for `arguments` objects
|
927
769
|
var result = false;
|
928
770
|
if (!(value && typeof value == 'object') || isArguments(value)) {
|
@@ -956,18 +798,20 @@
|
|
956
798
|
}
|
957
799
|
|
958
800
|
/**
|
959
|
-
* A
|
960
|
-
* object's own enumerable property names.
|
801
|
+
* A fallback implementation of `Object.keys` that produces an array of the
|
802
|
+
* given object's own enumerable property names.
|
961
803
|
*
|
962
804
|
* @private
|
963
805
|
* @param {Object} object The object to inspect.
|
964
806
|
* @returns {Array} Returns a new array of property names.
|
965
807
|
*/
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
808
|
+
function shimKeys(object) {
|
809
|
+
var result = [];
|
810
|
+
forOwn(object, function(value, key) {
|
811
|
+
result.push(key);
|
812
|
+
});
|
813
|
+
return result;
|
814
|
+
}
|
971
815
|
|
972
816
|
/**
|
973
817
|
* Used to convert characters to HTML entities:
|
@@ -1110,7 +954,7 @@
|
|
1110
954
|
* // => { 'flavor': 'chocolate', 'sprinkles': 'rainbow' }
|
1111
955
|
*/
|
1112
956
|
var defaults = createIterator(extendIteratorOptions, {
|
1113
|
-
'
|
957
|
+
'objectLoop': 'if (result[index] == null) ' + extendIteratorOptions.objectLoop
|
1114
958
|
});
|
1115
959
|
|
1116
960
|
/**
|
@@ -1132,100 +976,89 @@
|
|
1132
976
|
var extend = createIterator(extendIteratorOptions);
|
1133
977
|
|
1134
978
|
/**
|
1135
|
-
*
|
1136
|
-
*
|
1137
|
-
* invoked with three arguments; (value, key, object). Callbacks may exit iteration
|
1138
|
-
* early by explicitly returning `false`.
|
979
|
+
* Creates a sorted array of all enumerable properties, own and inherited,
|
980
|
+
* of `object` that have function values.
|
1139
981
|
*
|
1140
982
|
* @static
|
1141
983
|
* @memberOf _
|
984
|
+
* @alias methods
|
1142
985
|
* @category Objects
|
1143
|
-
* @param {Object} object The object to
|
1144
|
-
* @
|
1145
|
-
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1146
|
-
* @returns {Object} Returns `object`.
|
986
|
+
* @param {Object} object The object to inspect.
|
987
|
+
* @returns {Array} Returns a new array of property names that have function values.
|
1147
988
|
* @example
|
1148
989
|
*
|
1149
|
-
*
|
1150
|
-
*
|
1151
|
-
* }
|
1152
|
-
*
|
1153
|
-
* Dog.prototype.bark = function() {
|
1154
|
-
* alert('Woof, woof!');
|
1155
|
-
* };
|
1156
|
-
*
|
1157
|
-
* _.forIn(new Dog('Dagny'), function(value, key) {
|
1158
|
-
* alert(key);
|
1159
|
-
* });
|
1160
|
-
* // => alerts 'name' and 'bark' (order is not guaranteed)
|
990
|
+
* _.functions(_);
|
991
|
+
* // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
|
1161
992
|
*/
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
993
|
+
function functions(object) {
|
994
|
+
var result = [];
|
995
|
+
forIn(object, function(value, key) {
|
996
|
+
if (isFunction(value)) {
|
997
|
+
result.push(key);
|
998
|
+
}
|
999
|
+
});
|
1000
|
+
return result.sort();
|
1001
|
+
}
|
1165
1002
|
|
1166
1003
|
/**
|
1167
|
-
*
|
1168
|
-
*
|
1169
|
-
* arguments; (value, key, object). Callbacks may exit iteration early by explicitly
|
1170
|
-
* returning `false`.
|
1004
|
+
* Checks if the specified object `property` exists and is a direct property,
|
1005
|
+
* instead of an inherited property.
|
1171
1006
|
*
|
1172
1007
|
* @static
|
1173
1008
|
* @memberOf _
|
1174
1009
|
* @category Objects
|
1175
|
-
* @param {Object} object The object to
|
1176
|
-
* @param {
|
1177
|
-
* @
|
1178
|
-
* @returns {Object} Returns `object`.
|
1010
|
+
* @param {Object} object The object to check.
|
1011
|
+
* @param {String} property The property to check for.
|
1012
|
+
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
|
1179
1013
|
* @example
|
1180
1014
|
*
|
1181
|
-
* _.
|
1182
|
-
*
|
1183
|
-
* });
|
1184
|
-
* // => alerts '0', '1', and 'length' (order is not guaranteed)
|
1015
|
+
* _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
|
1016
|
+
* // => true
|
1185
1017
|
*/
|
1186
|
-
|
1018
|
+
function has(object, property) {
|
1019
|
+
return object ? hasOwnProperty.call(object, property) : false;
|
1020
|
+
}
|
1187
1021
|
|
1188
1022
|
/**
|
1189
|
-
* Creates
|
1190
|
-
* of `object` that have function values.
|
1023
|
+
* Creates an object composed of the inverted keys and values of the given `object`.
|
1191
1024
|
*
|
1192
1025
|
* @static
|
1193
1026
|
* @memberOf _
|
1194
|
-
* @alias methods
|
1195
1027
|
* @category Objects
|
1196
|
-
* @param {Object} object The object to
|
1197
|
-
* @returns {
|
1028
|
+
* @param {Object} object The object to invert.
|
1029
|
+
* @returns {Object} Returns the created inverted object.
|
1198
1030
|
* @example
|
1199
1031
|
*
|
1200
|
-
*
|
1201
|
-
* // =>
|
1032
|
+
* _.invert({ 'first': 'Moe', 'second': 'Larry', 'third': 'Curly' });
|
1033
|
+
* // => { 'Moe': 'first', 'Larry': 'second', 'Curly': 'third' } (order is not guaranteed)
|
1202
1034
|
*/
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
}
|
1035
|
+
function invert(object) {
|
1036
|
+
var result = {};
|
1037
|
+
forOwn(object, function(value, key) {
|
1038
|
+
result[value] = key;
|
1039
|
+
});
|
1040
|
+
return result;
|
1041
|
+
}
|
1210
1042
|
|
1211
1043
|
/**
|
1212
|
-
* Checks if
|
1213
|
-
* instead of an inherited property.
|
1044
|
+
* Checks if `value` is an array.
|
1214
1045
|
*
|
1215
1046
|
* @static
|
1216
1047
|
* @memberOf _
|
1217
1048
|
* @category Objects
|
1218
|
-
* @param {
|
1219
|
-
* @
|
1220
|
-
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
|
1049
|
+
* @param {Mixed} value The value to check.
|
1050
|
+
* @returns {Boolean} Returns `true` if the `value` is an array, else `false`.
|
1221
1051
|
* @example
|
1222
1052
|
*
|
1223
|
-
*
|
1053
|
+
* (function() { return _.isArray(arguments); })();
|
1054
|
+
* // => false
|
1055
|
+
*
|
1056
|
+
* _.isArray([1, 2, 3]);
|
1224
1057
|
* // => true
|
1225
1058
|
*/
|
1226
|
-
function
|
1227
|
-
return
|
1228
|
-
}
|
1059
|
+
var isArray = nativeIsArray || function(value) {
|
1060
|
+
return toString.call(value) == arrayClass;
|
1061
|
+
};
|
1229
1062
|
|
1230
1063
|
/**
|
1231
1064
|
* Checks if `value` is a boolean (`true` or `false`) value.
|
@@ -1299,21 +1132,24 @@
|
|
1299
1132
|
* _.isEmpty('');
|
1300
1133
|
* // => true
|
1301
1134
|
*/
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
'var className = toString.call(value),\n' +
|
1307
|
-
' length = value.length;\n' +
|
1308
|
-
'if (arrayLikeClasses[className]' +
|
1309
|
-
(noArgsClass ? ' || isArguments(value)' : '') + ' ||\n' +
|
1310
|
-
' (className == objectClass && length === +length &&\n' +
|
1311
|
-
' isFunction(value.splice))' +
|
1312
|
-
') return !length',
|
1313
|
-
'inLoop': {
|
1314
|
-
'object': 'return false'
|
1135
|
+
function isEmpty(value) {
|
1136
|
+
var result = true;
|
1137
|
+
if (!value) {
|
1138
|
+
return result;
|
1315
1139
|
}
|
1316
|
-
|
1140
|
+
var className = toString.call(value),
|
1141
|
+
length = value.length;
|
1142
|
+
|
1143
|
+
if ((className == arrayClass || className == stringClass ||
|
1144
|
+
className == argsClass || (noArgsClass && isArguments(value))) ||
|
1145
|
+
(className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
|
1146
|
+
return !length;
|
1147
|
+
}
|
1148
|
+
forOwn(value, function() {
|
1149
|
+
return (result = false);
|
1150
|
+
});
|
1151
|
+
return result;
|
1152
|
+
}
|
1317
1153
|
|
1318
1154
|
/**
|
1319
1155
|
* Performs a deep comparison between two values to determine if they are
|
@@ -1339,19 +1175,14 @@
|
|
1339
1175
|
* // => true
|
1340
1176
|
*/
|
1341
1177
|
function isEqual(a, b, stackA, stackB) {
|
1342
|
-
// a strict comparison is necessary because `null == undefined`
|
1343
|
-
if (a == null || b == null) {
|
1344
|
-
return a === b;
|
1345
|
-
}
|
1346
1178
|
// exit early for identical values
|
1347
1179
|
if (a === b) {
|
1348
1180
|
// treat `+0` vs. `-0` as not equal
|
1349
1181
|
return a !== 0 || (1 / a == 1 / b);
|
1350
1182
|
}
|
1351
|
-
//
|
1352
|
-
if (
|
1353
|
-
|
1354
|
-
b = b.__wrapped__ || b;
|
1183
|
+
// a strict comparison is necessary because `null == undefined`
|
1184
|
+
if (a == null || b == null) {
|
1185
|
+
return a === b;
|
1355
1186
|
}
|
1356
1187
|
// compare [[Class]] names
|
1357
1188
|
var className = toString.call(a);
|
@@ -1379,17 +1210,32 @@
|
|
1379
1210
|
return a == b + '';
|
1380
1211
|
}
|
1381
1212
|
// exit early, in older browsers, if `a` is array-like but not `b`
|
1382
|
-
var isArr =
|
1213
|
+
var isArr = className == arrayClass || className == argsClass;
|
1383
1214
|
if (noArgsClass && !isArr && (isArr = isArguments(a)) && !isArguments(b)) {
|
1384
1215
|
return false;
|
1385
1216
|
}
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
(
|
1390
|
-
|
1217
|
+
if (!isArr) {
|
1218
|
+
// unwrap any `lodash` wrapped values
|
1219
|
+
if (a.__wrapped__ || b.__wrapped__) {
|
1220
|
+
return isEqual(a.__wrapped__ || a, b.__wrapped__ || b);
|
1221
|
+
}
|
1222
|
+
// exit for functions and DOM nodes
|
1223
|
+
if (className != objectClass || (noNodeClass && (
|
1224
|
+
(typeof a.toString != 'function' && typeof (a + '') == 'string') ||
|
1225
|
+
(typeof b.toString != 'function' && typeof (b + '') == 'string')))) {
|
1226
|
+
return false;
|
1227
|
+
}
|
1228
|
+
var ctorA = a.constructor,
|
1229
|
+
ctorB = b.constructor;
|
1230
|
+
|
1231
|
+
// non `Object` object instances with different constructors are not equal
|
1232
|
+
if (ctorA != ctorB && !(
|
1233
|
+
isFunction(ctorA) && ctorA instanceof ctorA &&
|
1234
|
+
isFunction(ctorB) && ctorB instanceof ctorB
|
1235
|
+
)) {
|
1236
|
+
return false;
|
1237
|
+
}
|
1391
1238
|
}
|
1392
|
-
|
1393
1239
|
// assume cyclic structures are equal
|
1394
1240
|
// the algorithm for detecting cyclic structures is adapted from ES 5.1
|
1395
1241
|
// section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
|
@@ -1427,34 +1273,23 @@
|
|
1427
1273
|
}
|
1428
1274
|
return result;
|
1429
1275
|
}
|
1430
|
-
|
1431
|
-
var ctorA = a.constructor,
|
1432
|
-
ctorB = b.constructor;
|
1433
|
-
|
1434
|
-
// non `Object` object instances with different constructors are not equal
|
1435
|
-
if (ctorA != ctorB && !(
|
1436
|
-
isFunction(ctorA) && ctorA instanceof ctorA &&
|
1437
|
-
isFunction(ctorB) && ctorB instanceof ctorB
|
1438
|
-
)) {
|
1439
|
-
return false;
|
1440
|
-
}
|
1441
1276
|
// deep compare objects
|
1442
|
-
for (var
|
1443
|
-
if (hasOwnProperty.call(a,
|
1277
|
+
for (var key in a) {
|
1278
|
+
if (hasOwnProperty.call(a, key)) {
|
1444
1279
|
// count the number of properties.
|
1445
1280
|
size++;
|
1446
1281
|
// deep compare each property value.
|
1447
|
-
if (!(hasOwnProperty.call(b,
|
1282
|
+
if (!(hasOwnProperty.call(b, key) && isEqual(a[key], b[key], stackA, stackB))) {
|
1448
1283
|
return false;
|
1449
1284
|
}
|
1450
1285
|
}
|
1451
1286
|
}
|
1452
1287
|
// ensure both objects have the same number of properties
|
1453
|
-
for (
|
1288
|
+
for (key in b) {
|
1454
1289
|
// The JS engine in Adobe products, like InDesign, has a bug that causes
|
1455
1290
|
// `!size--` to throw an error so it must be wrapped in parentheses.
|
1456
1291
|
// https://github.com/documentcloud/underscore/issues/355
|
1457
|
-
if (hasOwnProperty.call(b,
|
1292
|
+
if (hasOwnProperty.call(b, key) && !(size--)) {
|
1458
1293
|
// `size` will be `-1` if `b` has more properties than `a`
|
1459
1294
|
return false;
|
1460
1295
|
}
|
@@ -1462,9 +1297,9 @@
|
|
1462
1297
|
// handle JScript [[DontEnum]] bug
|
1463
1298
|
if (hasDontEnumBug) {
|
1464
1299
|
while (++index < 7) {
|
1465
|
-
|
1466
|
-
if (hasOwnProperty.call(a,
|
1467
|
-
!(hasOwnProperty.call(b,
|
1300
|
+
key = shadowed[index];
|
1301
|
+
if (hasOwnProperty.call(a, key) &&
|
1302
|
+
!(hasOwnProperty.call(b, key) && isEqual(a[key], b[key], stackA, stackB))) {
|
1468
1303
|
return false;
|
1469
1304
|
}
|
1470
1305
|
}
|
@@ -1473,10 +1308,10 @@
|
|
1473
1308
|
}
|
1474
1309
|
|
1475
1310
|
/**
|
1476
|
-
* Checks if `value` is a finite number.
|
1311
|
+
* Checks if `value` is, or can be coerced to, a finite number.
|
1477
1312
|
*
|
1478
1313
|
* Note: This is not the same as native `isFinite`, which will return true for
|
1479
|
-
* booleans and
|
1314
|
+
* booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
|
1480
1315
|
*
|
1481
1316
|
* @deprecated
|
1482
1317
|
* @static
|
@@ -1490,13 +1325,42 @@
|
|
1490
1325
|
* // => true
|
1491
1326
|
*
|
1492
1327
|
* _.isFinite('10');
|
1328
|
+
* // => true
|
1329
|
+
*
|
1330
|
+
* _.isFinite(true);
|
1331
|
+
* // => false
|
1332
|
+
*
|
1333
|
+
* _.isFinite('');
|
1493
1334
|
* // => false
|
1494
1335
|
*
|
1495
1336
|
* _.isFinite(Infinity);
|
1496
1337
|
* // => false
|
1497
1338
|
*/
|
1498
1339
|
function isFinite(value) {
|
1499
|
-
return nativeIsFinite(value
|
1340
|
+
return nativeIsFinite(value ? +value : parseFloat(value));
|
1341
|
+
}
|
1342
|
+
|
1343
|
+
/**
|
1344
|
+
* Checks if `value` is a function.
|
1345
|
+
*
|
1346
|
+
* @static
|
1347
|
+
* @memberOf _
|
1348
|
+
* @category Objects
|
1349
|
+
* @param {Mixed} value The value to check.
|
1350
|
+
* @returns {Boolean} Returns `true` if the `value` is a function, else `false`.
|
1351
|
+
* @example
|
1352
|
+
*
|
1353
|
+
* _.isFunction(_);
|
1354
|
+
* // => true
|
1355
|
+
*/
|
1356
|
+
function isFunction(value) {
|
1357
|
+
return typeof value == 'function';
|
1358
|
+
}
|
1359
|
+
// fallback for older versions of Chrome and Safari
|
1360
|
+
if (isFunction(/x/)) {
|
1361
|
+
isFunction = function(value) {
|
1362
|
+
return toString.call(value) == funcClass;
|
1363
|
+
};
|
1500
1364
|
}
|
1501
1365
|
|
1502
1366
|
/**
|
@@ -1597,6 +1461,42 @@
|
|
1597
1461
|
return toString.call(value) == numberClass;
|
1598
1462
|
}
|
1599
1463
|
|
1464
|
+
/**
|
1465
|
+
* Checks if a given `value` is an object created by the `Object` constructor.
|
1466
|
+
*
|
1467
|
+
* @static
|
1468
|
+
* @memberOf _
|
1469
|
+
* @category Objects
|
1470
|
+
* @param {Mixed} value The value to check.
|
1471
|
+
* @returns {Boolean} Returns `true` if `value` is a plain object, else `false`.
|
1472
|
+
* @example
|
1473
|
+
*
|
1474
|
+
* function Stooge(name, age) {
|
1475
|
+
* this.name = name;
|
1476
|
+
* this.age = age;
|
1477
|
+
* }
|
1478
|
+
*
|
1479
|
+
* _.isPlainObject(new Stooge('moe', 40));
|
1480
|
+
* // => false
|
1481
|
+
*
|
1482
|
+
* _.isPlainObject([1, 2, 3]);
|
1483
|
+
* // => false
|
1484
|
+
*
|
1485
|
+
* _.isPlainObject({ 'name': 'moe', 'age': 40 });
|
1486
|
+
* // => true
|
1487
|
+
*/
|
1488
|
+
var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
|
1489
|
+
if (!(value && typeof value == 'object')) {
|
1490
|
+
return false;
|
1491
|
+
}
|
1492
|
+
var valueOf = value.valueOf,
|
1493
|
+
objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
|
1494
|
+
|
1495
|
+
return objProto
|
1496
|
+
? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value))
|
1497
|
+
: shimIsPlainObject(value);
|
1498
|
+
};
|
1499
|
+
|
1600
1500
|
/**
|
1601
1501
|
* Checks if `value` is a regular expression.
|
1602
1502
|
*
|
@@ -1687,7 +1587,7 @@
|
|
1687
1587
|
* @param- {Object} [indicator] Internally used to indicate that the `stack`
|
1688
1588
|
* argument is an array of traversed objects instead of another source object.
|
1689
1589
|
* @param- {Array} [stackA=[]] Internally used to track traversed source objects.
|
1690
|
-
* @param- {Array} [stackB=[]] Internally used to associate
|
1590
|
+
* @param- {Array} [stackB=[]] Internally used to associate values with their
|
1691
1591
|
* source counterparts.
|
1692
1592
|
* @returns {Object} Returns the destination object.
|
1693
1593
|
* @example
|
@@ -1705,37 +1605,50 @@
|
|
1705
1605
|
* _.merge(stooges, ages);
|
1706
1606
|
* // => [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }]
|
1707
1607
|
*/
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1608
|
+
function merge(object, source, indicator) {
|
1609
|
+
var args = arguments,
|
1610
|
+
index = 0,
|
1611
|
+
length = 2,
|
1612
|
+
stackA = args[3],
|
1613
|
+
stackB = args[4];
|
1614
|
+
|
1615
|
+
if (indicator !== indicatorObject) {
|
1616
|
+
stackA = [];
|
1617
|
+
stackB = [];
|
1618
|
+
length = args.length;
|
1619
|
+
}
|
1620
|
+
while (++index < length) {
|
1621
|
+
forOwn(args[index], function(source, key) {
|
1622
|
+
var found, isArr, value;
|
1623
|
+
if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
|
1624
|
+
// avoid merging previously merged cyclic sources
|
1625
|
+
var stackLength = stackA.length;
|
1626
|
+
while (stackLength--) {
|
1627
|
+
found = stackA[stackLength] == source;
|
1628
|
+
if (found) {
|
1629
|
+
break;
|
1630
|
+
}
|
1631
|
+
}
|
1632
|
+
if (found) {
|
1633
|
+
object[key] = stackB[stackLength];
|
1634
|
+
}
|
1635
|
+
else {
|
1636
|
+
// add `source` and associated `value` to the stack of traversed objects
|
1637
|
+
stackA.push(source);
|
1638
|
+
stackB.push(value = (value = object[key], isArr)
|
1639
|
+
? (isArray(value) ? value : [])
|
1640
|
+
: (isPlainObject(value) ? value : {})
|
1641
|
+
);
|
1642
|
+
// recursively merge objects and arrays (susceptible to call stack limits)
|
1643
|
+
object[key] = merge(value, source, indicatorObject, stackA, stackB);
|
1644
|
+
}
|
1645
|
+
} else if (source != null) {
|
1646
|
+
object[key] = source;
|
1647
|
+
}
|
1648
|
+
});
|
1649
|
+
}
|
1650
|
+
return object;
|
1651
|
+
}
|
1739
1652
|
|
1740
1653
|
/**
|
1741
1654
|
* Creates a shallow clone of `object` excluding the specified properties.
|
@@ -1762,7 +1675,25 @@
|
|
1762
1675
|
* });
|
1763
1676
|
* // => { 'name': 'moe' }
|
1764
1677
|
*/
|
1765
|
-
|
1678
|
+
function omit(object, callback, thisArg) {
|
1679
|
+
var isFunc = typeof callback == 'function',
|
1680
|
+
result = {};
|
1681
|
+
|
1682
|
+
if (isFunc) {
|
1683
|
+
callback = createCallback(callback, thisArg);
|
1684
|
+
} else {
|
1685
|
+
var props = concat.apply(arrayRef, arguments);
|
1686
|
+
}
|
1687
|
+
forIn(object, function(value, key, object) {
|
1688
|
+
if (isFunc
|
1689
|
+
? !callback(value, key, object)
|
1690
|
+
: indexOf(props, key, 1) < 0
|
1691
|
+
) {
|
1692
|
+
result[key] = value;
|
1693
|
+
}
|
1694
|
+
});
|
1695
|
+
return result;
|
1696
|
+
}
|
1766
1697
|
|
1767
1698
|
/**
|
1768
1699
|
* Creates a two dimensional array of the given object's key-value pairs,
|
@@ -1778,11 +1709,13 @@
|
|
1778
1709
|
* _.pairs({ 'moe': 30, 'larry': 40, 'curly': 50 });
|
1779
1710
|
* // => [['moe', 30], ['larry', 40], ['curly', 50]] (order is not guaranteed)
|
1780
1711
|
*/
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1712
|
+
function pairs(object) {
|
1713
|
+
var result = [];
|
1714
|
+
forOwn(object, function(value, key) {
|
1715
|
+
result.push([key, value]);
|
1716
|
+
});
|
1717
|
+
return result;
|
1718
|
+
}
|
1786
1719
|
|
1787
1720
|
/**
|
1788
1721
|
* Creates a shallow clone of `object` composed of the specified properties.
|
@@ -1809,22 +1742,29 @@
|
|
1809
1742
|
* });
|
1810
1743
|
* // => { 'name': 'moe' }
|
1811
1744
|
*/
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1745
|
+
function pick(object, callback, thisArg) {
|
1746
|
+
var result = {};
|
1747
|
+
if (typeof callback != 'function') {
|
1748
|
+
var index = 0,
|
1749
|
+
props = concat.apply(arrayRef, arguments),
|
1750
|
+
length = props.length;
|
1751
|
+
|
1752
|
+
while (++index < length) {
|
1753
|
+
var key = props[index];
|
1754
|
+
if (key in object) {
|
1755
|
+
result[key] = object[key];
|
1756
|
+
}
|
1757
|
+
}
|
1758
|
+
} else {
|
1759
|
+
callback = createCallback(callback, thisArg);
|
1760
|
+
forIn(object, function(value, key, object) {
|
1761
|
+
if (callback(value, key, object)) {
|
1762
|
+
result[key] = value;
|
1763
|
+
}
|
1764
|
+
});
|
1765
|
+
}
|
1766
|
+
return result;
|
1767
|
+
}
|
1828
1768
|
|
1829
1769
|
/**
|
1830
1770
|
* Creates an array composed of the own enumerable property values of `object`.
|
@@ -1839,11 +1779,13 @@
|
|
1839
1779
|
* _.values({ 'one': 1, 'two': 2, 'three': 3 });
|
1840
1780
|
* // => [1, 2, 3]
|
1841
1781
|
*/
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1782
|
+
function values(object) {
|
1783
|
+
var result = [];
|
1784
|
+
forOwn(object, function(value) {
|
1785
|
+
result.push(value);
|
1786
|
+
});
|
1787
|
+
return result;
|
1788
|
+
}
|
1847
1789
|
|
1848
1790
|
/*--------------------------------------------------------------------------*/
|
1849
1791
|
|
@@ -1869,15 +1811,18 @@
|
|
1869
1811
|
* _.contains('curly', 'ur');
|
1870
1812
|
* // => true
|
1871
1813
|
*/
|
1872
|
-
|
1873
|
-
|
1874
|
-
'
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1814
|
+
function contains(collection, target) {
|
1815
|
+
var length = collection ? collection.length : 0;
|
1816
|
+
if (typeof length == 'number') {
|
1817
|
+
return (toString.call(collection) == stringClass
|
1818
|
+
? collection.indexOf(target)
|
1819
|
+
: indexOf(collection, target)
|
1820
|
+
) > -1;
|
1821
|
+
}
|
1822
|
+
return some(collection, function(value) {
|
1823
|
+
return value === target;
|
1824
|
+
});
|
1825
|
+
}
|
1881
1826
|
|
1882
1827
|
/**
|
1883
1828
|
* Creates an object composed of keys returned from running each element of
|
@@ -1905,7 +1850,15 @@
|
|
1905
1850
|
* _.countBy(['one', 'two', 'three'], 'length');
|
1906
1851
|
* // => { '3': 2, '5': 1 }
|
1907
1852
|
*/
|
1908
|
-
|
1853
|
+
function countBy(collection, callback, thisArg) {
|
1854
|
+
var result = {};
|
1855
|
+
callback = createCallback(callback, thisArg);
|
1856
|
+
forEach(collection, function(value, key, collection) {
|
1857
|
+
key = callback(value, key, collection);
|
1858
|
+
(hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
|
1859
|
+
});
|
1860
|
+
return result;
|
1861
|
+
}
|
1909
1862
|
|
1910
1863
|
/**
|
1911
1864
|
* Checks if the `callback` returns a truthy value for **all** elements of a
|
@@ -1926,7 +1879,14 @@
|
|
1926
1879
|
* _.every([true, 1, null, 'yes'], Boolean);
|
1927
1880
|
* // => false
|
1928
1881
|
*/
|
1929
|
-
|
1882
|
+
function every(collection, callback, thisArg) {
|
1883
|
+
var result = true;
|
1884
|
+
callback = createCallback(callback, thisArg);
|
1885
|
+
forEach(collection, function(value, index, collection) {
|
1886
|
+
return (result = callback(value, index, collection));
|
1887
|
+
});
|
1888
|
+
return !!result;
|
1889
|
+
}
|
1930
1890
|
|
1931
1891
|
/**
|
1932
1892
|
* Examines each element in a `collection`, returning an array of all elements
|
@@ -1946,7 +1906,16 @@
|
|
1946
1906
|
* var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
1947
1907
|
* // => [2, 4, 6]
|
1948
1908
|
*/
|
1949
|
-
|
1909
|
+
function filter(collection, callback, thisArg) {
|
1910
|
+
var result = [];
|
1911
|
+
callback = createCallback(callback, thisArg);
|
1912
|
+
forEach(collection, function(value, index, collection) {
|
1913
|
+
if (callback(value, index, collection)) {
|
1914
|
+
result.push(value);
|
1915
|
+
}
|
1916
|
+
});
|
1917
|
+
return result;
|
1918
|
+
}
|
1950
1919
|
|
1951
1920
|
/**
|
1952
1921
|
* Examines each element in a `collection`, returning the first one the `callback`
|
@@ -1968,10 +1937,14 @@
|
|
1968
1937
|
* var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
1969
1938
|
* // => 2
|
1970
1939
|
*/
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1940
|
+
function find(collection, callback, thisArg) {
|
1941
|
+
var result;
|
1942
|
+
callback = createCallback(callback, thisArg);
|
1943
|
+
some(collection, function(value, index, collection) {
|
1944
|
+
return callback(value, index, collection) && (result = value, true);
|
1945
|
+
});
|
1946
|
+
return result;
|
1947
|
+
}
|
1975
1948
|
|
1976
1949
|
/**
|
1977
1950
|
* Iterates over a `collection`, executing the `callback` for each element in
|
@@ -1995,14 +1968,14 @@
|
|
1995
1968
|
* _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);
|
1996
1969
|
* // => alerts each number (order is not guaranteed)
|
1997
1970
|
*/
|
1998
|
-
var forEach = createIterator(
|
1971
|
+
var forEach = createIterator(forEachIteratorOptions);
|
1999
1972
|
|
2000
1973
|
/**
|
2001
1974
|
* Creates an object composed of keys returned from running each element of
|
2002
1975
|
* `collection` through a `callback`. The corresponding value of each key is an
|
2003
1976
|
* array of elements passed to `callback` that returned the key. The `callback`
|
2004
1977
|
* is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2005
|
-
* The `callback` argument may also be the name of a property to
|
1978
|
+
* The `callback` argument may also be the name of a property to group by (e.g. 'length').
|
2006
1979
|
*
|
2007
1980
|
* @static
|
2008
1981
|
* @memberOf _
|
@@ -2023,11 +1996,15 @@
|
|
2023
1996
|
* _.groupBy(['one', 'two', 'three'], 'length');
|
2024
1997
|
* // => { '3': ['one', 'two'], '5': ['three'] }
|
2025
1998
|
*/
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
1999
|
+
function groupBy(collection, callback, thisArg) {
|
2000
|
+
var result = {};
|
2001
|
+
callback = createCallback(callback, thisArg);
|
2002
|
+
forEach(collection, function(value, key, collection) {
|
2003
|
+
key = callback(value, key, collection);
|
2004
|
+
(hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
|
2005
|
+
});
|
2006
|
+
return result;
|
2007
|
+
}
|
2031
2008
|
|
2032
2009
|
/**
|
2033
2010
|
* Invokes the method named by `methodName` on each element in the `collection`,
|
@@ -2051,19 +2028,16 @@
|
|
2051
2028
|
* _.invoke([123, 456], String.prototype.split, '');
|
2052
2029
|
* // => [['1', '2', '3'], ['4', '5', '6']]
|
2053
2030
|
*/
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
'((isFunc ? methodName : value[methodName]).apply(value, args))'
|
2065
|
-
}
|
2066
|
-
});
|
2031
|
+
function invoke(collection, methodName) {
|
2032
|
+
var args = slice.call(arguments, 2),
|
2033
|
+
isFunc = typeof methodName == 'function',
|
2034
|
+
result = [];
|
2035
|
+
|
2036
|
+
forEach(collection, function(value) {
|
2037
|
+
result.push((isFunc ? methodName : value[methodName]).apply(value, args));
|
2038
|
+
});
|
2039
|
+
return result;
|
2040
|
+
}
|
2067
2041
|
|
2068
2042
|
/**
|
2069
2043
|
* Creates an array of values by running each element in the `collection`
|
@@ -2086,7 +2060,23 @@
|
|
2086
2060
|
* _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
|
2087
2061
|
* // => [3, 6, 9] (order is not guaranteed)
|
2088
2062
|
*/
|
2089
|
-
|
2063
|
+
function map(collection, callback, thisArg) {
|
2064
|
+
var index = -1,
|
2065
|
+
length = collection ? collection.length : 0,
|
2066
|
+
result = Array(typeof length == 'number' ? length : 0);
|
2067
|
+
|
2068
|
+
callback = createCallback(callback, thisArg);
|
2069
|
+
if (isArray(collection)) {
|
2070
|
+
while (++index < length) {
|
2071
|
+
result[index] = callback(collection[index], index, collection);
|
2072
|
+
}
|
2073
|
+
} else {
|
2074
|
+
forEach(collection, function(value, key, collection) {
|
2075
|
+
result[++index] = callback(value, key, collection);
|
2076
|
+
});
|
2077
|
+
}
|
2078
|
+
return result;
|
2079
|
+
}
|
2090
2080
|
|
2091
2081
|
/**
|
2092
2082
|
* Retrieves the maximum value of an `array`. If `callback` is passed,
|
@@ -2118,7 +2108,7 @@
|
|
2118
2108
|
length = collection ? collection.length : 0,
|
2119
2109
|
result = computed;
|
2120
2110
|
|
2121
|
-
if (callback || length
|
2111
|
+
if (callback || typeof length != 'number') {
|
2122
2112
|
callback = createCallback(callback, thisArg);
|
2123
2113
|
forEach(collection, function(value, index, collection) {
|
2124
2114
|
var current = callback(value, index, collection);
|
@@ -2161,7 +2151,7 @@
|
|
2161
2151
|
length = collection ? collection.length : 0,
|
2162
2152
|
result = computed;
|
2163
2153
|
|
2164
|
-
if (callback || length
|
2154
|
+
if (callback || typeof length != 'number') {
|
2165
2155
|
callback = createCallback(callback, thisArg);
|
2166
2156
|
forEach(collection, function(value, index, collection) {
|
2167
2157
|
var current = callback(value, index, collection);
|
@@ -2201,13 +2191,13 @@
|
|
2201
2191
|
* _.pluck(stooges, 'name');
|
2202
2192
|
* // => ['moe', 'larry', 'curly']
|
2203
2193
|
*/
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
}
|
2194
|
+
function pluck(collection, property) {
|
2195
|
+
var result = [];
|
2196
|
+
forEach(collection, function(value) {
|
2197
|
+
result.push(value[property]);
|
2198
|
+
});
|
2199
|
+
return result;
|
2200
|
+
}
|
2211
2201
|
|
2212
2202
|
/**
|
2213
2203
|
* Boils down a `collection` to a single value. The initial state of the
|
@@ -2229,24 +2219,16 @@
|
|
2229
2219
|
* var sum = _.reduce([1, 2, 3], function(memo, num) { return memo + num; });
|
2230
2220
|
* // => 6
|
2231
2221
|
*/
|
2232
|
-
|
2233
|
-
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2240
|
-
|
2241
|
-
|
2242
|
-
'array':
|
2243
|
-
'result = callback(result, value, index, collection)',
|
2244
|
-
'object':
|
2245
|
-
'result = noaccum\n' +
|
2246
|
-
' ? (noaccum = false, value)\n' +
|
2247
|
-
' : callback(result, value, index, collection)'
|
2248
|
-
}
|
2249
|
-
});
|
2222
|
+
function reduce(collection, callback, accumulator, thisArg) {
|
2223
|
+
var noaccum = arguments.length < 3;
|
2224
|
+
callback = createCallback(callback, thisArg);
|
2225
|
+
forEach(collection, function(value, index, collection) {
|
2226
|
+
accumulator = noaccum
|
2227
|
+
? (noaccum = false, value)
|
2228
|
+
: callback(accumulator, value, index, collection)
|
2229
|
+
});
|
2230
|
+
return accumulator;
|
2231
|
+
}
|
2250
2232
|
|
2251
2233
|
/**
|
2252
2234
|
* The right-associative version of `_.reduce`.
|
@@ -2271,17 +2253,17 @@
|
|
2271
2253
|
length = collection ? collection.length : 0,
|
2272
2254
|
noaccum = arguments.length < 3;
|
2273
2255
|
|
2274
|
-
if (length
|
2256
|
+
if (typeof length != 'number') {
|
2275
2257
|
var props = keys(collection);
|
2276
2258
|
length = props.length;
|
2277
2259
|
} else if (noCharByIndex && toString.call(collection) == stringClass) {
|
2278
2260
|
iteratee = collection.split('');
|
2279
2261
|
}
|
2280
|
-
forEach(collection, function(value, index,
|
2262
|
+
forEach(collection, function(value, index, collection) {
|
2281
2263
|
index = props ? props[--length] : --length;
|
2282
2264
|
accumulator = noaccum
|
2283
2265
|
? (noaccum = false, iteratee[index])
|
2284
|
-
: callback.call(thisArg, accumulator, iteratee[index], index,
|
2266
|
+
: callback.call(thisArg, accumulator, iteratee[index], index, collection);
|
2285
2267
|
});
|
2286
2268
|
return accumulator;
|
2287
2269
|
}
|
@@ -2303,9 +2285,12 @@
|
|
2303
2285
|
* var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
2304
2286
|
* // => [1, 3, 5]
|
2305
2287
|
*/
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2288
|
+
function reject(collection, callback, thisArg) {
|
2289
|
+
callback = createCallback(callback, thisArg);
|
2290
|
+
return filter(collection, function(value, index, collection) {
|
2291
|
+
return !callback(value, index, collection);
|
2292
|
+
});
|
2293
|
+
}
|
2309
2294
|
|
2310
2295
|
/**
|
2311
2296
|
* Creates an array of shuffled `array` values, using a version of the
|
@@ -2355,7 +2340,7 @@
|
|
2355
2340
|
*/
|
2356
2341
|
function size(collection) {
|
2357
2342
|
var length = collection ? collection.length : 0;
|
2358
|
-
return length
|
2343
|
+
return typeof length == 'number' ? length : keys(collection).length;
|
2359
2344
|
}
|
2360
2345
|
|
2361
2346
|
/**
|
@@ -2378,10 +2363,14 @@
|
|
2378
2363
|
* _.some([null, 0, 'yes', false]);
|
2379
2364
|
* // => true
|
2380
2365
|
*/
|
2381
|
-
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2366
|
+
function some(collection, callback, thisArg) {
|
2367
|
+
var result;
|
2368
|
+
callback = createCallback(callback, thisArg);
|
2369
|
+
forEach(collection, function(value, index, collection) {
|
2370
|
+
return !(result = callback(value, index, collection));
|
2371
|
+
});
|
2372
|
+
return !!result;
|
2373
|
+
}
|
2385
2374
|
|
2386
2375
|
/**
|
2387
2376
|
* Creates an array, stable sorted in ascending order by the results of
|
@@ -2408,28 +2397,24 @@
|
|
2408
2397
|
* _.sortBy(['larry', 'brendan', 'moe'], 'length');
|
2409
2398
|
* // => ['moe', 'larry', 'brendan']
|
2410
2399
|
*/
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
2414
|
-
|
2415
|
-
|
2416
|
-
'
|
2417
|
-
'
|
2418
|
-
'
|
2419
|
-
|
2420
|
-
|
2421
|
-
|
2422
|
-
|
2423
|
-
|
2424
|
-
|
2425
|
-
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
'while (length--) {\n' +
|
2430
|
-
' result[length] = result[length].value\n' +
|
2431
|
-
'}'
|
2432
|
-
});
|
2400
|
+
function sortBy(collection, callback, thisArg) {
|
2401
|
+
var result = [];
|
2402
|
+
callback = createCallback(callback, thisArg);
|
2403
|
+
forEach(collection, function(value, index, collection) {
|
2404
|
+
result.push({
|
2405
|
+
'criteria': callback(value, index, collection),
|
2406
|
+
'index': index,
|
2407
|
+
'value': value
|
2408
|
+
});
|
2409
|
+
});
|
2410
|
+
|
2411
|
+
var length = result.length;
|
2412
|
+
result.sort(compareAscending);
|
2413
|
+
while (length--) {
|
2414
|
+
result[length] = result[length].value;
|
2415
|
+
}
|
2416
|
+
return result;
|
2417
|
+
}
|
2433
2418
|
|
2434
2419
|
/**
|
2435
2420
|
* Converts the `collection`, to an array.
|
@@ -2445,11 +2430,7 @@
|
|
2445
2430
|
* // => [2, 3, 4]
|
2446
2431
|
*/
|
2447
2432
|
function toArray(collection) {
|
2448
|
-
if (
|
2449
|
-
return [];
|
2450
|
-
}
|
2451
|
-
var length = collection.length;
|
2452
|
-
if (length === +length) {
|
2433
|
+
if (collection && typeof collection.length == 'number') {
|
2453
2434
|
return (noArraySliceOnStrings ? toString.call(collection) == stringClass : typeof collection == 'string')
|
2454
2435
|
? collection.split('')
|
2455
2436
|
: slice.call(collection);
|
@@ -2465,7 +2446,7 @@
|
|
2465
2446
|
* @memberOf _
|
2466
2447
|
* @category Collections
|
2467
2448
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2468
|
-
* @param {Object} properties The object of
|
2449
|
+
* @param {Object} properties The object of property values to filter by.
|
2469
2450
|
* @returns {Array} Returns a new array of elements that contain the given `properties`.
|
2470
2451
|
* @example
|
2471
2452
|
*
|
@@ -2478,19 +2459,22 @@
|
|
2478
2459
|
* _.where(stooges, { 'age': 40 });
|
2479
2460
|
* // => [{ 'name': 'moe', 'age': 40 }]
|
2480
2461
|
*/
|
2481
|
-
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2486
|
-
|
2487
|
-
|
2488
|
-
|
2489
|
-
|
2490
|
-
|
2491
|
-
|
2492
|
-
|
2493
|
-
|
2462
|
+
function where(collection, properties) {
|
2463
|
+
var props = [];
|
2464
|
+
forIn(properties, function(value, prop) {
|
2465
|
+
props.push(prop);
|
2466
|
+
});
|
2467
|
+
return filter(collection, function(object) {
|
2468
|
+
var length = props.length;
|
2469
|
+
while (length--) {
|
2470
|
+
var result = object[props[length]] === properties[props[length]];
|
2471
|
+
if (!result) {
|
2472
|
+
break;
|
2473
|
+
}
|
2474
|
+
}
|
2475
|
+
return !!result;
|
2476
|
+
});
|
2477
|
+
}
|
2494
2478
|
|
2495
2479
|
/*--------------------------------------------------------------------------*/
|
2496
2480
|
|
@@ -2539,14 +2523,11 @@
|
|
2539
2523
|
* // => [1, 3, 4]
|
2540
2524
|
*/
|
2541
2525
|
function difference(array) {
|
2542
|
-
var result = [];
|
2543
|
-
if (!array) {
|
2544
|
-
return result;
|
2545
|
-
}
|
2546
2526
|
var index = -1,
|
2547
|
-
length = array.length,
|
2548
|
-
flattened = concat.apply(
|
2549
|
-
contains = cachedContains(flattened, length)
|
2527
|
+
length = array ? array.length : 0,
|
2528
|
+
flattened = concat.apply(arrayRef, arguments),
|
2529
|
+
contains = cachedContains(flattened, length),
|
2530
|
+
result = [];
|
2550
2531
|
|
2551
2532
|
while (++index < length) {
|
2552
2533
|
var value = array[index];
|
@@ -2699,23 +2680,22 @@
|
|
2699
2680
|
* // => [1, 2]
|
2700
2681
|
*/
|
2701
2682
|
function intersection(array) {
|
2702
|
-
var
|
2703
|
-
|
2704
|
-
|
2705
|
-
length = array ? array.length : 0,
|
2683
|
+
var args = arguments,
|
2684
|
+
argsLength = args.length,
|
2685
|
+
cache = {},
|
2706
2686
|
result = [];
|
2707
2687
|
|
2708
|
-
array
|
2709
|
-
var value = array[index];
|
2688
|
+
forEach(array, function(value) {
|
2710
2689
|
if (indexOf(result, value) < 0) {
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2690
|
+
var length = argsLength;
|
2691
|
+
while (--length) {
|
2692
|
+
if (!(cache[length] || (cache[length] = cachedContains(args[length])))(value)) {
|
2693
|
+
return;
|
2714
2694
|
}
|
2715
2695
|
}
|
2716
2696
|
result.push(value);
|
2717
2697
|
}
|
2718
|
-
}
|
2698
|
+
});
|
2719
2699
|
return result;
|
2720
2700
|
}
|
2721
2701
|
|
@@ -2927,18 +2907,14 @@
|
|
2927
2907
|
var low = 0,
|
2928
2908
|
high = array ? array.length : low;
|
2929
2909
|
|
2930
|
-
|
2931
|
-
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2935
|
-
|
2936
|
-
|
2937
|
-
|
2938
|
-
while (low < high) {
|
2939
|
-
var mid = (low + high) >>> 1;
|
2940
|
-
array[mid] < value ? low = mid + 1 : high = mid;
|
2941
|
-
}
|
2910
|
+
// explicitly reference `identity` for better engine inlining
|
2911
|
+
callback = callback ? createCallback(callback, thisArg) : identity;
|
2912
|
+
value = callback(value);
|
2913
|
+
while (low < high) {
|
2914
|
+
var mid = (low + high) >>> 1;
|
2915
|
+
callback(array[mid]) < value
|
2916
|
+
? low = mid + 1
|
2917
|
+
: high = mid;
|
2942
2918
|
}
|
2943
2919
|
return low;
|
2944
2920
|
}
|
@@ -2960,7 +2936,7 @@
|
|
2960
2936
|
*/
|
2961
2937
|
function union() {
|
2962
2938
|
var index = -1,
|
2963
|
-
flattened = concat.apply(
|
2939
|
+
flattened = concat.apply(arrayRef, arguments),
|
2964
2940
|
length = flattened.length,
|
2965
2941
|
result = [];
|
2966
2942
|
|
@@ -3170,23 +3146,17 @@
|
|
3170
3146
|
* jQuery('#lodash_button').on('click', buttonView.onClick);
|
3171
3147
|
* // => When the button is clicked, `this.label` will have the correct value
|
3172
3148
|
*/
|
3173
|
-
|
3174
|
-
|
3175
|
-
|
3176
|
-
|
3177
|
-
|
3178
|
-
|
3179
|
-
|
3180
|
-
|
3181
|
-
|
3182
|
-
|
3183
|
-
|
3184
|
-
' }\n' +
|
3185
|
-
' return result\n' +
|
3186
|
-
'}',
|
3187
|
-
'inLoop':
|
3188
|
-
'if (isFunction(value)) result[index] = bind(value, result)'
|
3189
|
-
});
|
3149
|
+
function bindAll(object) {
|
3150
|
+
var funcs = arguments,
|
3151
|
+
index = funcs.length > 1 ? 0 : (funcs = functions(object), -1),
|
3152
|
+
length = funcs.length;
|
3153
|
+
|
3154
|
+
while (++index < length) {
|
3155
|
+
var key = funcs[index];
|
3156
|
+
object[key] = bind(object[key], object);
|
3157
|
+
}
|
3158
|
+
return object;
|
3159
|
+
}
|
3190
3160
|
|
3191
3161
|
/**
|
3192
3162
|
* Creates a function that is the composition of the passed functions,
|
@@ -3251,7 +3221,6 @@
|
|
3251
3221
|
result = func.apply(thisArg, args);
|
3252
3222
|
}
|
3253
3223
|
}
|
3254
|
-
|
3255
3224
|
return function() {
|
3256
3225
|
var isImmediate = immediate && !timeoutId;
|
3257
3226
|
args = arguments;
|
@@ -3286,7 +3255,7 @@
|
|
3286
3255
|
*/
|
3287
3256
|
function delay(func, wait) {
|
3288
3257
|
var args = slice.call(arguments, 2);
|
3289
|
-
return setTimeout(function() {
|
3258
|
+
return setTimeout(function() { func.apply(undefined, args); }, wait);
|
3290
3259
|
}
|
3291
3260
|
|
3292
3261
|
/**
|
@@ -3306,7 +3275,7 @@
|
|
3306
3275
|
*/
|
3307
3276
|
function defer(func) {
|
3308
3277
|
var args = slice.call(arguments, 1);
|
3309
|
-
return setTimeout(function() {
|
3278
|
+
return setTimeout(function() { func.apply(undefined, args); }, 1);
|
3310
3279
|
}
|
3311
3280
|
|
3312
3281
|
/**
|
@@ -3367,10 +3336,10 @@
|
|
3367
3336
|
function memoize(func, resolver) {
|
3368
3337
|
var cache = {};
|
3369
3338
|
return function() {
|
3370
|
-
var
|
3371
|
-
return hasOwnProperty.call(cache,
|
3372
|
-
? cache[
|
3373
|
-
: (cache[
|
3339
|
+
var key = resolver ? resolver.apply(this, arguments) : arguments[0];
|
3340
|
+
return hasOwnProperty.call(cache, key)
|
3341
|
+
? cache[key]
|
3342
|
+
: (cache[key] = func.apply(this, arguments));
|
3374
3343
|
};
|
3375
3344
|
}
|
3376
3345
|
|
@@ -3459,21 +3428,20 @@
|
|
3459
3428
|
timeoutId = null;
|
3460
3429
|
result = func.apply(thisArg, args);
|
3461
3430
|
}
|
3462
|
-
|
3463
3431
|
return function() {
|
3464
3432
|
var now = new Date,
|
3465
|
-
|
3433
|
+
remaining = wait - (now - lastCalled);
|
3466
3434
|
|
3467
3435
|
args = arguments;
|
3468
3436
|
thisArg = this;
|
3469
3437
|
|
3470
|
-
if (
|
3438
|
+
if (remaining <= 0) {
|
3471
3439
|
clearTimeout(timeoutId);
|
3472
3440
|
lastCalled = now;
|
3473
3441
|
result = func.apply(thisArg, args);
|
3474
3442
|
}
|
3475
3443
|
else if (!timeoutId) {
|
3476
|
-
timeoutId = setTimeout(trailingCall,
|
3444
|
+
timeoutId = setTimeout(trailingCall, remaining);
|
3477
3445
|
}
|
3478
3446
|
return result;
|
3479
3447
|
};
|
@@ -3492,19 +3460,17 @@
|
|
3492
3460
|
* @returns {Function} Returns the new function.
|
3493
3461
|
* @example
|
3494
3462
|
*
|
3495
|
-
* var hello = function(name) { return 'hello
|
3463
|
+
* var hello = function(name) { return 'hello ' + name; };
|
3496
3464
|
* hello = _.wrap(hello, function(func) {
|
3497
3465
|
* return 'before, ' + func('moe') + ', after';
|
3498
3466
|
* });
|
3499
3467
|
* hello();
|
3500
|
-
* // => 'before, hello
|
3468
|
+
* // => 'before, hello moe, after'
|
3501
3469
|
*/
|
3502
3470
|
function wrap(value, wrapper) {
|
3503
3471
|
return function() {
|
3504
3472
|
var args = [value];
|
3505
|
-
|
3506
|
-
push.apply(args, arguments);
|
3507
|
-
}
|
3473
|
+
push.apply(args, arguments);
|
3508
3474
|
return wrapper.apply(this, args);
|
3509
3475
|
};
|
3510
3476
|
}
|
@@ -3577,9 +3543,8 @@
|
|
3577
3543
|
|
3578
3544
|
lodash.prototype[methodName] = function() {
|
3579
3545
|
var args = [this.__wrapped__];
|
3580
|
-
|
3581
|
-
|
3582
|
-
}
|
3546
|
+
push.apply(args, arguments);
|
3547
|
+
|
3583
3548
|
var result = func.apply(lodash, args);
|
3584
3549
|
if (this.__chain__) {
|
3585
3550
|
result = new lodash(result);
|
@@ -3688,14 +3653,20 @@
|
|
3688
3653
|
* @param {String} text The template text.
|
3689
3654
|
* @param {Obect} data The data object used to populate the text.
|
3690
3655
|
* @param {Object} options The options object.
|
3656
|
+
* escape - The "escape" delimiter regexp.
|
3657
|
+
* evaluate - The "evaluate" delimiter regexp.
|
3658
|
+
* interpolate - The "interpolate" delimiter regexp.
|
3659
|
+
* sourceURL - The sourceURL of the template's compiled source.
|
3660
|
+
* variable - The data object variable name.
|
3661
|
+
*
|
3691
3662
|
* @returns {Function|String} Returns a compiled function when no `data` object
|
3692
3663
|
* is given, else it returns the interpolated text.
|
3693
3664
|
* @example
|
3694
3665
|
*
|
3695
3666
|
* // using a compiled template
|
3696
|
-
* var compiled = _.template('hello
|
3667
|
+
* var compiled = _.template('hello <%= name %>');
|
3697
3668
|
* compiled({ 'name': 'moe' });
|
3698
|
-
* // => 'hello
|
3669
|
+
* // => 'hello moe'
|
3699
3670
|
*
|
3700
3671
|
* var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
|
3701
3672
|
* _.template(list, { 'people': ['moe', 'larry', 'curly'] });
|
@@ -3706,23 +3677,28 @@
|
|
3706
3677
|
* // => '<b><script></b>'
|
3707
3678
|
*
|
3708
3679
|
* // using the internal `print` function in "evaluate" delimiters
|
3709
|
-
* _.template('<% print("
|
3710
|
-
* // => '
|
3680
|
+
* _.template('<% print("hello " + epithet); %>!', { 'epithet': 'stooge' });
|
3681
|
+
* // => 'hello stooge!'
|
3711
3682
|
*
|
3712
|
-
* // using custom template
|
3683
|
+
* // using custom template delimiters
|
3713
3684
|
* _.templateSettings = {
|
3714
3685
|
* 'interpolate': /\{\{([\s\S]+?)\}\}/g
|
3715
3686
|
* };
|
3716
3687
|
*
|
3717
|
-
* _.template('
|
3718
|
-
* // => '
|
3688
|
+
* _.template('hello {{ name }}!', { 'name': 'mustache' });
|
3689
|
+
* // => 'hello mustache!'
|
3690
|
+
*
|
3691
|
+
* // using the `sourceURL` option to specify a custom sourceURL for the template
|
3692
|
+
* var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
|
3693
|
+
* compiled(data);
|
3694
|
+
* // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
|
3719
3695
|
*
|
3720
3696
|
* // using the `variable` option to ensure a with-statement isn't used in the compiled template
|
3721
|
-
* var compiled = _.template('hello
|
3697
|
+
* var compiled = _.template('hello <%= data.name %>!', null, { 'variable': 'data' });
|
3722
3698
|
* compiled.source;
|
3723
3699
|
* // => function(data) {
|
3724
3700
|
* var __t, __p = '', __e = _.escape;
|
3725
|
-
* __p += 'hello
|
3701
|
+
* __p += 'hello ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
|
3726
3702
|
* return __p;
|
3727
3703
|
* }
|
3728
3704
|
*
|
@@ -3810,7 +3786,7 @@
|
|
3810
3786
|
// use a sourceURL for easier debugging
|
3811
3787
|
// http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
|
3812
3788
|
var sourceURL = useSourceURL
|
3813
|
-
? '\n//@ sourceURL
|
3789
|
+
? '\n//@ sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']')
|
3814
3790
|
: '';
|
3815
3791
|
|
3816
3792
|
try {
|
@@ -3865,8 +3841,9 @@
|
|
3865
3841
|
}
|
3866
3842
|
|
3867
3843
|
/**
|
3868
|
-
*
|
3869
|
-
* in `string` to their
|
3844
|
+
* The opposite of `_.escape`, this method converts the HTML entities
|
3845
|
+
* `&`, `<`, `>`, `"`, and `'` in `string` to their
|
3846
|
+
* corresponding characters.
|
3870
3847
|
*
|
3871
3848
|
* @static
|
3872
3849
|
* @memberOf _
|
@@ -4001,7 +3978,7 @@
|
|
4001
3978
|
* @memberOf _
|
4002
3979
|
* @type String
|
4003
3980
|
*/
|
4004
|
-
lodash.VERSION = '0.
|
3981
|
+
lodash.VERSION = '0.9.0';
|
4005
3982
|
|
4006
3983
|
// assign static methods
|
4007
3984
|
lodash.after = after;
|
@@ -4117,9 +4094,8 @@
|
|
4117
4094
|
lodash.take = first;
|
4118
4095
|
lodash.unique = uniq;
|
4119
4096
|
|
4120
|
-
// add pseudo private
|
4097
|
+
// add pseudo private property to be used and removed during the build process
|
4121
4098
|
lodash._iteratorTemplate = iteratorTemplate;
|
4122
|
-
lodash._shimKeys = shimKeys;
|
4123
4099
|
|
4124
4100
|
/*--------------------------------------------------------------------------*/
|
4125
4101
|
|
@@ -4133,7 +4109,7 @@
|
|
4133
4109
|
|
4134
4110
|
// add all mutator Array functions to the wrapper.
|
4135
4111
|
forEach(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
|
4136
|
-
var func =
|
4112
|
+
var func = arrayRef[methodName];
|
4137
4113
|
|
4138
4114
|
lodash.prototype[methodName] = function() {
|
4139
4115
|
var value = this.__wrapped__;
|
@@ -4154,7 +4130,7 @@
|
|
4154
4130
|
|
4155
4131
|
// add all accessor Array functions to the wrapper.
|
4156
4132
|
forEach(['concat', 'join', 'slice'], function(methodName) {
|
4157
|
-
var func =
|
4133
|
+
var func = arrayRef[methodName];
|
4158
4134
|
|
4159
4135
|
lodash.prototype[methodName] = function() {
|
4160
4136
|
var value = this.__wrapped__,
|