lodash-rails 1.0.0.rc.3 → 1.0.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 +1321 -792
- data/vendor/assets/javascripts/lodash.min.js +40 -42
- metadata +6 -7
data/README.md
CHANGED
data/lib/lodash/rails/version.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
|
2
|
-
*
|
3
|
-
*
|
4
|
-
*
|
5
|
-
*
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Lo-Dash 1.0.1 (Custom Build) <http://lodash.com/>
|
4
|
+
* Build: `lodash modern -o ./dist/lodash.js`
|
5
|
+
* Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
|
6
|
+
* Based on Underscore.js 1.4.4 <http://underscorejs.org/>
|
7
|
+
* Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
|
6
8
|
* Available under MIT license <http://lodash.com/license>
|
7
9
|
*/
|
8
10
|
;(function(window, undefined) {
|
@@ -10,6 +12,9 @@
|
|
10
12
|
/** Detect free variable `exports` */
|
11
13
|
var freeExports = typeof exports == 'object' && exports;
|
12
14
|
|
15
|
+
/** Detect free variable `module` */
|
16
|
+
var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
|
17
|
+
|
13
18
|
/** Detect free variable `global` and use it as `window` */
|
14
19
|
var freeGlobal = typeof global == 'object' && global;
|
15
20
|
if (freeGlobal.global === freeGlobal) {
|
@@ -18,8 +23,7 @@
|
|
18
23
|
|
19
24
|
/** Used for array and object method references */
|
20
25
|
var arrayRef = [],
|
21
|
-
|
22
|
-
objectRef = new function(){};
|
26
|
+
objectRef = {};
|
23
27
|
|
24
28
|
/** Used to generate unique IDs */
|
25
29
|
var idCounter = 0;
|
@@ -33,11 +37,8 @@
|
|
33
37
|
/** Used to restore the original `_` reference in `noConflict` */
|
34
38
|
var oldDash = window._;
|
35
39
|
|
36
|
-
/** Used to detect template delimiter values that require a with-statement */
|
37
|
-
var reComplexDelimiter = /[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/;
|
38
|
-
|
39
40
|
/** Used to match HTML entities */
|
40
|
-
var reEscapedHtml = /&(?:amp|lt|gt|quot|#
|
41
|
+
var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
|
41
42
|
|
42
43
|
/** Used to match empty string literals in compiled template source */
|
43
44
|
var reEmptyStringLeading = /\b__p \+= '';/g,
|
@@ -47,13 +48,10 @@
|
|
47
48
|
/** Used to match regexp flags from their coerced string values */
|
48
49
|
var reFlags = /\w*$/;
|
49
50
|
|
50
|
-
/** Used to insert the data object variable into compiled template source */
|
51
|
-
var reInsertVariable = /(?:__e|__t = )\(\s*(?![\d\s"']|this\.)/g;
|
52
|
-
|
53
51
|
/** Used to detect if a method is native */
|
54
52
|
var reNative = RegExp('^' +
|
55
53
|
(objectRef.valueOf + '')
|
56
|
-
.replace(/[
|
54
|
+
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
57
55
|
.replace(/valueOf|for [^\]]+/g, '.+?') + '$'
|
58
56
|
);
|
59
57
|
|
@@ -61,7 +59,7 @@
|
|
61
59
|
* Used to match ES6 template delimiters
|
62
60
|
* http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
|
63
61
|
*/
|
64
|
-
var reEsTemplate = /\$\{((
|
62
|
+
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
|
65
63
|
|
66
64
|
/** Used to match "interpolate" template delimiters */
|
67
65
|
var reInterpolate = /<%=([\s\S]+?)%>/g;
|
@@ -75,12 +73,6 @@
|
|
75
73
|
/** Used to match unescaped characters in compiled string literals */
|
76
74
|
var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
|
77
75
|
|
78
|
-
/** Used to fix the JScript [[DontEnum]] bug */
|
79
|
-
var shadowed = [
|
80
|
-
'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
|
81
|
-
'toLocaleString', 'toString', 'valueOf'
|
82
|
-
];
|
83
|
-
|
84
76
|
/** Used to make template sourceURLs easier to identify */
|
85
77
|
var templateCounter = 0;
|
86
78
|
|
@@ -91,7 +83,6 @@
|
|
91
83
|
getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
|
92
84
|
hasOwnProperty = objectRef.hasOwnProperty,
|
93
85
|
push = arrayRef.push,
|
94
|
-
propertyIsEnumerable = objectRef.propertyIsEnumerable,
|
95
86
|
toString = objectRef.toString;
|
96
87
|
|
97
88
|
/* Native method shortcuts for methods with the same name as other `lodash` methods */
|
@@ -125,84 +116,6 @@
|
|
125
116
|
/* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */
|
126
117
|
var isKeysFast = nativeKeys && (isIeOpera || isV8);
|
127
118
|
|
128
|
-
/**
|
129
|
-
* Detect the JScript [[DontEnum]] bug:
|
130
|
-
*
|
131
|
-
* In IE < 9 an objects own properties, shadowing non-enumerable ones, are
|
132
|
-
* made non-enumerable as well.
|
133
|
-
*/
|
134
|
-
var hasDontEnumBug;
|
135
|
-
|
136
|
-
/** Detect if own properties are iterated after inherited properties (IE < 9) */
|
137
|
-
var iteratesOwnLast;
|
138
|
-
|
139
|
-
/**
|
140
|
-
* Detect if `Array#shift` and `Array#splice` augment array-like objects
|
141
|
-
* incorrectly:
|
142
|
-
*
|
143
|
-
* Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
|
144
|
-
* and `splice()` functions that fail to remove the last element, `value[0]`,
|
145
|
-
* of array-like objects even though the `length` property is set to `0`.
|
146
|
-
* The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
|
147
|
-
* is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
|
148
|
-
*/
|
149
|
-
var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 },
|
150
|
-
arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]);
|
151
|
-
|
152
|
-
/** Detect if an `arguments` object's indexes are non-enumerable (IE < 9) */
|
153
|
-
var nonEnumArgs = true;
|
154
|
-
|
155
|
-
(function() {
|
156
|
-
var props = [];
|
157
|
-
function ctor() { this.x = 1; }
|
158
|
-
ctor.prototype = { 'valueOf': 1, 'y': 1 };
|
159
|
-
for (var prop in new ctor) { props.push(prop); }
|
160
|
-
for (prop in arguments) { nonEnumArgs = !prop; }
|
161
|
-
|
162
|
-
hasDontEnumBug = !/valueOf/.test(props);
|
163
|
-
iteratesOwnLast = props[0] != 'x';
|
164
|
-
}(1));
|
165
|
-
|
166
|
-
/** Detect if `arguments` objects are `Object` objects (all but Opera < 10.5) */
|
167
|
-
var argsAreObjects = arguments.constructor == Object;
|
168
|
-
|
169
|
-
/** Detect if `arguments` objects [[Class]] is unresolvable (Firefox < 4, IE < 9) */
|
170
|
-
var noArgsClass = !isArguments(arguments);
|
171
|
-
|
172
|
-
/**
|
173
|
-
* Detect lack of support for accessing string characters by index:
|
174
|
-
*
|
175
|
-
* IE < 8 can't access characters by index and IE 8 can only access
|
176
|
-
* characters by index on string literals.
|
177
|
-
*/
|
178
|
-
var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx';
|
179
|
-
|
180
|
-
/**
|
181
|
-
* Detect if a node's [[Class]] is unresolvable (IE < 9)
|
182
|
-
* and that the JS engine won't error when attempting to coerce an object to
|
183
|
-
* a string without a `toString` property value of `typeof` "function".
|
184
|
-
*/
|
185
|
-
try {
|
186
|
-
var noNodeClass = ({ 'toString': 0 } + '', toString.call(document) == objectClass);
|
187
|
-
} catch(e) { }
|
188
|
-
|
189
|
-
/**
|
190
|
-
* Detect if sourceURL syntax is usable without erroring:
|
191
|
-
*
|
192
|
-
* The JS engine embedded in Adobe products will throw a syntax error when
|
193
|
-
* it encounters a single line comment beginning with the `@` symbol.
|
194
|
-
*
|
195
|
-
* The JS engine in Narwhal will generate the function `function anonymous(){//}`
|
196
|
-
* and throw a syntax error.
|
197
|
-
*
|
198
|
-
* Avoid comments beginning `@` symbols in IE because they are part of its
|
199
|
-
* non-standard conditional compilation support.
|
200
|
-
* http://msdn.microsoft.com/en-us/library/121hztk3(v=vs.94).aspx
|
201
|
-
*/
|
202
|
-
try {
|
203
|
-
var useSourceURL = (Function('//@')(), !isIeOpera);
|
204
|
-
} catch(e) { }
|
205
|
-
|
206
119
|
/** Used to identify object classifications that `_.clone` supports */
|
207
120
|
var cloneableClasses = {};
|
208
121
|
cloneableClasses[funcClass] = false;
|
@@ -245,18 +158,22 @@
|
|
245
158
|
/*--------------------------------------------------------------------------*/
|
246
159
|
|
247
160
|
/**
|
248
|
-
* Creates a `lodash` object, that wraps the given `value`, to enable
|
249
|
-
*
|
161
|
+
* Creates a `lodash` object, that wraps the given `value`, to enable method
|
162
|
+
* chaining.
|
163
|
+
*
|
164
|
+
* In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
|
165
|
+
* `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
|
166
|
+
* and `unshift`
|
250
167
|
*
|
251
168
|
* The chainable wrapper functions are:
|
252
169
|
* `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`,
|
253
170
|
* `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`,
|
254
171
|
* `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`,
|
255
172
|
* `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`,
|
256
|
-
* `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `
|
257
|
-
* `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
|
258
|
-
* `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
|
259
|
-
* `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
|
173
|
+
* `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
|
174
|
+
* `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
|
175
|
+
* `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
|
176
|
+
* `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
|
260
177
|
*
|
261
178
|
* The non-chainable wrapper functions are:
|
262
179
|
* `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`,
|
@@ -301,7 +218,6 @@
|
|
301
218
|
/**
|
302
219
|
* Used to detect `data` property values to be HTML-escaped.
|
303
220
|
*
|
304
|
-
* @static
|
305
221
|
* @memberOf _.templateSettings
|
306
222
|
* @type RegExp
|
307
223
|
*/
|
@@ -310,7 +226,6 @@
|
|
310
226
|
/**
|
311
227
|
* Used to detect code to be evaluated.
|
312
228
|
*
|
313
|
-
* @static
|
314
229
|
* @memberOf _.templateSettings
|
315
230
|
* @type RegExp
|
316
231
|
*/
|
@@ -319,7 +234,6 @@
|
|
319
234
|
/**
|
320
235
|
* Used to detect `data` property values to inject.
|
321
236
|
*
|
322
|
-
* @static
|
323
237
|
* @memberOf _.templateSettings
|
324
238
|
* @type RegExp
|
325
239
|
*/
|
@@ -328,11 +242,27 @@
|
|
328
242
|
/**
|
329
243
|
* Used to reference the data object in the template text.
|
330
244
|
*
|
331
|
-
* @static
|
332
245
|
* @memberOf _.templateSettings
|
333
246
|
* @type String
|
334
247
|
*/
|
335
|
-
'variable': ''
|
248
|
+
'variable': '',
|
249
|
+
|
250
|
+
/**
|
251
|
+
* Used to import variables into the compiled template.
|
252
|
+
*
|
253
|
+
* @memberOf _.templateSettings
|
254
|
+
* @type Object
|
255
|
+
*/
|
256
|
+
'imports': {
|
257
|
+
|
258
|
+
/**
|
259
|
+
* A reference to the `lodash` function.
|
260
|
+
*
|
261
|
+
* @memberOf _.templateSettings.imports
|
262
|
+
* @type Function
|
263
|
+
*/
|
264
|
+
'_': lodash
|
265
|
+
}
|
336
266
|
};
|
337
267
|
|
338
268
|
/*--------------------------------------------------------------------------*/
|
@@ -344,134 +274,80 @@
|
|
344
274
|
* @param {Obect} data The data object used to populate the text.
|
345
275
|
* @returns {String} Returns the interpolated text.
|
346
276
|
*/
|
347
|
-
var iteratorTemplate =
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
'
|
368
|
-
|
369
|
-
'
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
'
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
'
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
'
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
// value to `true`. Because of this Lo-Dash standardizes on skipping
|
395
|
-
// the the `prototype` property of functions regardless of its
|
396
|
-
// [[Enumerable]] value.
|
397
|
-
' <% if (!hasDontEnumBug) { %>\n' +
|
398
|
-
" var skipProto = typeof iteratee == 'function' && \n" +
|
399
|
-
" propertyIsEnumerable.call(iteratee, 'prototype');\n" +
|
400
|
-
' <% } %>' +
|
401
|
-
|
402
|
-
// iterate own properties using `Object.keys` if it's fast
|
403
|
-
' <% if (isKeysFast && useHas) { %>\n' +
|
404
|
-
' var ownIndex = -1,\n' +
|
405
|
-
' ownProps = objectTypes[typeof iteratee] ? nativeKeys(iteratee) : [],\n' +
|
406
|
-
' length = ownProps.length;\n\n' +
|
407
|
-
' while (++ownIndex < length) {\n' +
|
408
|
-
' index = ownProps[ownIndex];\n' +
|
409
|
-
" <% if (!hasDontEnumBug) { %>if (!(skipProto && index == 'prototype')) {\n <% } %>" +
|
410
|
-
' <%= objectLoop %>\n' +
|
411
|
-
' <% if (!hasDontEnumBug) { %>}\n<% } %>' +
|
412
|
-
' }' +
|
413
|
-
|
414
|
-
// else using a for-in loop
|
415
|
-
' <% } else { %>\n' +
|
416
|
-
' for (index in iteratee) {<%' +
|
417
|
-
' if (!hasDontEnumBug || useHas) { %>\n if (<%' +
|
418
|
-
" if (!hasDontEnumBug) { %>!(skipProto && index == 'prototype')<% }" +
|
419
|
-
' if (!hasDontEnumBug && useHas) { %> && <% }' +
|
420
|
-
' if (useHas) { %>hasOwnProperty.call(iteratee, index)<% }' +
|
421
|
-
' %>) {' +
|
422
|
-
' <% } %>\n' +
|
423
|
-
' <%= objectLoop %>;' +
|
424
|
-
' <% if (!hasDontEnumBug || useHas) { %>\n }<% } %>\n' +
|
425
|
-
' }' +
|
426
|
-
' <% } %>' +
|
427
|
-
|
428
|
-
// Because IE < 9 can't set the `[[Enumerable]]` attribute of an
|
429
|
-
// existing property and the `constructor` property of a prototype
|
430
|
-
// defaults to non-enumerable, Lo-Dash skips the `constructor`
|
431
|
-
// property when it infers it's iterating over a `prototype` object.
|
432
|
-
' <% if (hasDontEnumBug) { %>\n\n' +
|
433
|
-
' var ctor = iteratee.constructor;\n' +
|
434
|
-
' <% for (var k = 0; k < 7; k++) { %>\n' +
|
435
|
-
" index = '<%= shadowed[k] %>';\n" +
|
436
|
-
' if (<%' +
|
437
|
-
" if (shadowed[k] == 'constructor') {" +
|
438
|
-
' %>!(ctor && ctor.prototype === iteratee) && <%' +
|
439
|
-
' } %>hasOwnProperty.call(iteratee, index)) {\n' +
|
440
|
-
' <%= objectLoop %>\n' +
|
441
|
-
' }' +
|
442
|
-
' <% } %>' +
|
443
|
-
' <% } %>' +
|
444
|
-
' <% if (arrayLoop || nonEnumArgs) { %>\n}<% } %>\n' +
|
445
|
-
|
446
|
-
// add code to the bottom of the iteration function
|
447
|
-
'<%= bottom %>;\n' +
|
448
|
-
// finally, return the `result`
|
449
|
-
'return result'
|
450
|
-
);
|
277
|
+
var iteratorTemplate = function(obj) {
|
278
|
+
|
279
|
+
var __p = 'var index, iterable = ' +
|
280
|
+
(obj.firstArg ) +
|
281
|
+
', result = iterable;\nif (!iterable) return result;\n' +
|
282
|
+
(obj.top ) +
|
283
|
+
';\n';
|
284
|
+
if (obj.arrays) {
|
285
|
+
__p += 'var length = iterable.length; index = -1;\nif (' +
|
286
|
+
(obj.arrays ) +
|
287
|
+
') {\n while (++index < length) {\n ' +
|
288
|
+
(obj.loop ) +
|
289
|
+
'\n }\n}\nelse { ';
|
290
|
+
} ;
|
291
|
+
|
292
|
+
if (obj.isKeysFast && obj.useHas) {
|
293
|
+
__p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n ' +
|
294
|
+
(obj.loop ) +
|
295
|
+
'\n } ';
|
296
|
+
} else {
|
297
|
+
__p += '\n for (index in iterable) {';
|
298
|
+
if (obj.useHas) {
|
299
|
+
__p += '\n if (';
|
300
|
+
if (obj.useHas) {
|
301
|
+
__p += 'hasOwnProperty.call(iterable, index)';
|
302
|
+
} ;
|
303
|
+
__p += ') { ';
|
304
|
+
} ;
|
305
|
+
__p +=
|
306
|
+
(obj.loop ) +
|
307
|
+
'; ';
|
308
|
+
if (obj.useHas) {
|
309
|
+
__p += '\n }';
|
310
|
+
} ;
|
311
|
+
__p += '\n } ';
|
312
|
+
} ;
|
313
|
+
|
314
|
+
if (obj.arrays) {
|
315
|
+
__p += '\n}';
|
316
|
+
} ;
|
317
|
+
__p +=
|
318
|
+
(obj.bottom ) +
|
319
|
+
';\nreturn result';
|
320
|
+
|
321
|
+
|
322
|
+
return __p
|
323
|
+
};
|
451
324
|
|
452
325
|
/** Reusable iterator options for `assign` and `defaults` */
|
453
|
-
var
|
326
|
+
var defaultsIteratorOptions = {
|
454
327
|
'args': 'object, source, guard',
|
455
328
|
'top':
|
456
|
-
|
457
|
-
'
|
458
|
-
'
|
329
|
+
'var args = arguments,\n' +
|
330
|
+
' argsIndex = 0,\n' +
|
331
|
+
" argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
|
332
|
+
'while (++argsIndex < argsLength) {\n' +
|
333
|
+
' iterable = args[argsIndex];\n' +
|
334
|
+
' if (iterable && objectTypes[typeof iterable]) {',
|
335
|
+
'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
|
459
336
|
'bottom': ' }\n}'
|
460
337
|
};
|
461
338
|
|
462
|
-
/**
|
463
|
-
* Reusable iterator options shared by `each`, `forIn`, and `forOwn`.
|
464
|
-
*/
|
339
|
+
/** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
|
465
340
|
var eachIteratorOptions = {
|
466
341
|
'args': 'collection, callback, thisArg',
|
467
342
|
'top': "callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)",
|
468
|
-
'
|
469
|
-
'
|
343
|
+
'arrays': "typeof length == 'number'",
|
344
|
+
'loop': 'if (callback(iterable[index], index, collection) === false) return result'
|
470
345
|
};
|
471
346
|
|
472
347
|
/** Reusable iterator options for `forIn` and `forOwn` */
|
473
348
|
var forOwnIteratorOptions = {
|
474
|
-
'
|
349
|
+
'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
|
350
|
+
'arrays': false
|
475
351
|
};
|
476
352
|
|
477
353
|
/*--------------------------------------------------------------------------*/
|
@@ -485,7 +361,7 @@
|
|
485
361
|
* @param {Mixed} value The value to search for.
|
486
362
|
* @param {Number} [fromIndex=0] The index to search from.
|
487
363
|
* @param {Number} [largeSize=30] The length at which an array is considered large.
|
488
|
-
* @returns {Boolean} Returns `true
|
364
|
+
* @returns {Boolean} Returns `true`, if `value` is found, else `false`.
|
489
365
|
*/
|
490
366
|
function cachedContains(array, fromIndex, largeSize) {
|
491
367
|
fromIndex || (fromIndex = 0);
|
@@ -555,17 +431,18 @@
|
|
555
431
|
}
|
556
432
|
|
557
433
|
/**
|
558
|
-
* Creates a function that, when called, invokes `func` with the `this`
|
559
|
-
*
|
560
|
-
*
|
434
|
+
* Creates a function that, when called, invokes `func` with the `this` binding
|
435
|
+
* of `thisArg` and prepends any `partialArgs` to the arguments passed to the
|
436
|
+
* bound function.
|
561
437
|
*
|
562
438
|
* @private
|
563
439
|
* @param {Function|String} func The function to bind or the method name.
|
564
440
|
* @param {Mixed} [thisArg] The `this` binding of `func`.
|
565
441
|
* @param {Array} partialArgs An array of arguments to be partially applied.
|
442
|
+
* @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right.
|
566
443
|
* @returns {Function} Returns the new bound function.
|
567
444
|
*/
|
568
|
-
function createBound(func, thisArg, partialArgs) {
|
445
|
+
function createBound(func, thisArg, partialArgs, rightIndicator) {
|
569
446
|
var isFunc = isFunction(func),
|
570
447
|
isPartial = !partialArgs,
|
571
448
|
key = thisArg;
|
@@ -589,7 +466,7 @@
|
|
589
466
|
}
|
590
467
|
if (partialArgs.length) {
|
591
468
|
args = args.length
|
592
|
-
? partialArgs.concat(
|
469
|
+
? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
|
593
470
|
: partialArgs;
|
594
471
|
}
|
595
472
|
if (this instanceof bound) {
|
@@ -609,28 +486,52 @@
|
|
609
486
|
}
|
610
487
|
|
611
488
|
/**
|
612
|
-
* Produces
|
613
|
-
*
|
489
|
+
* Produces a callback bound to an optional `thisArg`. If `func` is a property
|
490
|
+
* name, the created callback will return the property value for a given element.
|
491
|
+
* If `func` is an object, the created callback will return `true` for elements
|
492
|
+
* that contain the equivalent object properties, otherwise it will return `false`.
|
614
493
|
*
|
615
494
|
* @private
|
616
|
-
* @param {
|
617
|
-
*
|
618
|
-
* @param {
|
619
|
-
* @param {Object} [accumulating] Used to indicate that the callback should
|
620
|
-
* accept an `accumulator` argument.
|
495
|
+
* @param {Mixed} [func=identity] The value to convert to a callback.
|
496
|
+
* @param {Mixed} [thisArg] The `this` binding of the created callback.
|
497
|
+
* @param {Number} [argCount=3] The number of arguments the callback accepts.
|
621
498
|
* @returns {Function} Returns a callback function.
|
622
499
|
*/
|
623
|
-
function createCallback(func, thisArg,
|
624
|
-
if (
|
500
|
+
function createCallback(func, thisArg, argCount) {
|
501
|
+
if (func == null) {
|
625
502
|
return identity;
|
626
503
|
}
|
627
|
-
|
504
|
+
var type = typeof func;
|
505
|
+
if (type != 'function') {
|
506
|
+
if (type != 'object') {
|
507
|
+
return function(object) {
|
508
|
+
return object[func];
|
509
|
+
};
|
510
|
+
}
|
511
|
+
var props = keys(func);
|
628
512
|
return function(object) {
|
629
|
-
|
513
|
+
var length = props.length,
|
514
|
+
result = false;
|
515
|
+
while (length--) {
|
516
|
+
if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) {
|
517
|
+
break;
|
518
|
+
}
|
519
|
+
}
|
520
|
+
return result;
|
630
521
|
};
|
631
522
|
}
|
632
523
|
if (typeof thisArg != 'undefined') {
|
633
|
-
if (
|
524
|
+
if (argCount === 1) {
|
525
|
+
return function(value) {
|
526
|
+
return func.call(thisArg, value);
|
527
|
+
};
|
528
|
+
}
|
529
|
+
if (argCount === 2) {
|
530
|
+
return function(a, b) {
|
531
|
+
return func.call(thisArg, a, b);
|
532
|
+
};
|
533
|
+
}
|
534
|
+
if (argCount === 4) {
|
634
535
|
return function(accumulator, value, index, object) {
|
635
536
|
return func.call(thisArg, accumulator, value, index, object);
|
636
537
|
};
|
@@ -647,25 +548,24 @@
|
|
647
548
|
*
|
648
549
|
* @private
|
649
550
|
* @param {Object} [options1, options2, ...] The compile options object(s).
|
551
|
+
* arrays - A string of code to determine if the iterable is an array or array-like.
|
650
552
|
* useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
|
651
553
|
* args - A string of comma separated arguments the iteration function will accept.
|
652
554
|
* top - A string of code to execute before the iteration branches.
|
653
|
-
*
|
654
|
-
* objectLoop - A string of code to execute in the object loop.
|
555
|
+
* loop - A string of code to execute in the object loop.
|
655
556
|
* bottom - A string of code to execute after the iteration branches.
|
656
557
|
*
|
657
558
|
* @returns {Function} Returns the compiled function.
|
658
559
|
*/
|
659
560
|
function createIterator() {
|
660
561
|
var data = {
|
661
|
-
|
662
|
-
'bottom': '',
|
663
|
-
'hasDontEnumBug': hasDontEnumBug,
|
562
|
+
// support properties
|
664
563
|
'isKeysFast': isKeysFast,
|
665
|
-
|
666
|
-
|
667
|
-
'
|
668
|
-
'
|
564
|
+
|
565
|
+
// iterator options
|
566
|
+
'arrays': 'isArray(iterable)',
|
567
|
+
'bottom': '',
|
568
|
+
'loop': '',
|
669
569
|
'top': '',
|
670
570
|
'useHas': true
|
671
571
|
};
|
@@ -681,14 +581,14 @@
|
|
681
581
|
|
682
582
|
// create the function factory
|
683
583
|
var factory = Function(
|
684
|
-
'createCallback, hasOwnProperty, isArguments,
|
685
|
-
'
|
584
|
+
'createCallback, hasOwnProperty, isArguments, isArray, isString, ' +
|
585
|
+
'objectTypes, nativeKeys',
|
686
586
|
'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
|
687
587
|
);
|
688
588
|
// return the compiled function
|
689
589
|
return factory(
|
690
|
-
createCallback, hasOwnProperty, isArguments,
|
691
|
-
|
590
|
+
createCallback, hasOwnProperty, isArguments, isArray, isString,
|
591
|
+
objectTypes, nativeKeys
|
692
592
|
);
|
693
593
|
}
|
694
594
|
|
@@ -700,6 +600,7 @@
|
|
700
600
|
* iteration early by explicitly returning `false`.
|
701
601
|
*
|
702
602
|
* @private
|
603
|
+
* @type Function
|
703
604
|
* @param {Array|Object|String} collection The collection to iterate over.
|
704
605
|
* @param {Function} [callback=identity] The function called per iteration.
|
705
606
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
@@ -793,25 +694,6 @@
|
|
793
694
|
|
794
695
|
/*--------------------------------------------------------------------------*/
|
795
696
|
|
796
|
-
/**
|
797
|
-
* Assigns own enumerable properties of source object(s) to the `destination`
|
798
|
-
* object. Subsequent sources will overwrite propery assignments of previous
|
799
|
-
* sources.
|
800
|
-
*
|
801
|
-
* @static
|
802
|
-
* @memberOf _
|
803
|
-
* @alias extend
|
804
|
-
* @category Objects
|
805
|
-
* @param {Object} object The destination object.
|
806
|
-
* @param {Object} [source1, source2, ...] The source objects.
|
807
|
-
* @returns {Object} Returns the destination object.
|
808
|
-
* @example
|
809
|
-
*
|
810
|
-
* _.assign({ 'name': 'moe' }, { 'age': 40 });
|
811
|
-
* // => { 'name': 'moe', 'age': 40 }
|
812
|
-
*/
|
813
|
-
var assign = createIterator(assignIteratorOptions);
|
814
|
-
|
815
697
|
/**
|
816
698
|
* Checks if `value` is an `arguments` object.
|
817
699
|
*
|
@@ -819,7 +701,7 @@
|
|
819
701
|
* @memberOf _
|
820
702
|
* @category Objects
|
821
703
|
* @param {Mixed} value The value to check.
|
822
|
-
* @returns {Boolean} Returns `true
|
704
|
+
* @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
|
823
705
|
* @example
|
824
706
|
*
|
825
707
|
* (function() { return _.isArguments(arguments); })(1, 2, 3);
|
@@ -831,12 +713,6 @@
|
|
831
713
|
function isArguments(value) {
|
832
714
|
return toString.call(value) == argsClass;
|
833
715
|
}
|
834
|
-
// fallback for browsers that can't detect `arguments` objects by [[Class]]
|
835
|
-
if (noArgsClass) {
|
836
|
-
isArguments = function(value) {
|
837
|
-
return value ? hasOwnProperty.call(value, 'callee') : false;
|
838
|
-
};
|
839
|
-
}
|
840
716
|
|
841
717
|
/**
|
842
718
|
* Iterates over `object`'s own and inherited enumerable properties, executing
|
@@ -846,6 +722,7 @@
|
|
846
722
|
*
|
847
723
|
* @static
|
848
724
|
* @memberOf _
|
725
|
+
* @type Function
|
849
726
|
* @category Objects
|
850
727
|
* @param {Object} object The object to iterate over.
|
851
728
|
* @param {Function} [callback=identity] The function called per iteration.
|
@@ -878,6 +755,7 @@
|
|
878
755
|
*
|
879
756
|
* @static
|
880
757
|
* @memberOf _
|
758
|
+
* @type Function
|
881
759
|
* @category Objects
|
882
760
|
* @param {Object} object The object to iterate over.
|
883
761
|
* @param {Function} [callback=identity] The function called per iteration.
|
@@ -892,6 +770,48 @@
|
|
892
770
|
*/
|
893
771
|
var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
|
894
772
|
|
773
|
+
/**
|
774
|
+
* Checks if `value` is an array.
|
775
|
+
*
|
776
|
+
* @static
|
777
|
+
* @memberOf _
|
778
|
+
* @category Objects
|
779
|
+
* @param {Mixed} value The value to check.
|
780
|
+
* @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
|
781
|
+
* @example
|
782
|
+
*
|
783
|
+
* (function() { return _.isArray(arguments); })();
|
784
|
+
* // => false
|
785
|
+
*
|
786
|
+
* _.isArray([1, 2, 3]);
|
787
|
+
* // => true
|
788
|
+
*/
|
789
|
+
var isArray = nativeIsArray || function(value) {
|
790
|
+
// `instanceof` may cause a memory leak in IE 7 if `value` is a host object
|
791
|
+
// http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
|
792
|
+
return value instanceof Array || toString.call(value) == arrayClass;
|
793
|
+
};
|
794
|
+
|
795
|
+
/**
|
796
|
+
* Creates an array composed of the own enumerable property names of `object`.
|
797
|
+
*
|
798
|
+
* @static
|
799
|
+
* @memberOf _
|
800
|
+
* @category Objects
|
801
|
+
* @param {Object} object The object to inspect.
|
802
|
+
* @returns {Array} Returns a new array of property names.
|
803
|
+
* @example
|
804
|
+
*
|
805
|
+
* _.keys({ 'one': 1, 'two': 2, 'three': 3 });
|
806
|
+
* // => ['one', 'two', 'three'] (order is not guaranteed)
|
807
|
+
*/
|
808
|
+
var keys = !nativeKeys ? shimKeys : function(object) {
|
809
|
+
if (!isObject(object)) {
|
810
|
+
return [];
|
811
|
+
}
|
812
|
+
return nativeKeys(object);
|
813
|
+
};
|
814
|
+
|
895
815
|
/**
|
896
816
|
* A fallback implementation of `isPlainObject` that checks if a given `value`
|
897
817
|
* is an object created by the `Object` constructor, assuming objects created
|
@@ -900,7 +820,7 @@
|
|
900
820
|
*
|
901
821
|
* @private
|
902
822
|
* @param {Mixed} value The value to check.
|
903
|
-
* @returns {Boolean} Returns `true
|
823
|
+
* @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
|
904
824
|
*/
|
905
825
|
function shimIsPlainObject(value) {
|
906
826
|
// avoid non-objects and false positives for `arguments` objects
|
@@ -910,17 +830,7 @@
|
|
910
830
|
}
|
911
831
|
// check that the constructor is `Object` (i.e. `Object instanceof Object`)
|
912
832
|
var ctor = value.constructor;
|
913
|
-
if ((!isFunction(ctor)
|
914
|
-
// IE < 9 iterates inherited properties before own properties. If the first
|
915
|
-
// iterated property is an object's own property then there are no inherited
|
916
|
-
// enumerable properties.
|
917
|
-
if (iteratesOwnLast) {
|
918
|
-
forIn(value, function(value, key, object) {
|
919
|
-
result = !hasOwnProperty.call(object, key);
|
920
|
-
return false;
|
921
|
-
});
|
922
|
-
return result === false;
|
923
|
-
}
|
833
|
+
if ((!isFunction(ctor)) || ctor instanceof ctor) {
|
924
834
|
// In most environments an object's own properties are iterated before
|
925
835
|
// its inherited properties. If the last iterated property is an object's
|
926
836
|
// own property then there are no inherited enumerable properties.
|
@@ -961,7 +871,7 @@
|
|
961
871
|
'<': '<',
|
962
872
|
'>': '>',
|
963
873
|
'"': '"',
|
964
|
-
"'": '&#
|
874
|
+
"'": '''
|
965
875
|
};
|
966
876
|
|
967
877
|
/** Used to convert HTML entities to characters */
|
@@ -969,27 +879,71 @@
|
|
969
879
|
|
970
880
|
/*--------------------------------------------------------------------------*/
|
971
881
|
|
882
|
+
/**
|
883
|
+
* Assigns own enumerable properties of source object(s) to the destination
|
884
|
+
* object. Subsequent sources will overwrite propery assignments of previous
|
885
|
+
* sources. If a `callback` function is passed, it will be executed to produce
|
886
|
+
* the assigned values. The `callback` is bound to `thisArg` and invoked with
|
887
|
+
* two arguments; (objectValue, sourceValue).
|
888
|
+
*
|
889
|
+
* @static
|
890
|
+
* @memberOf _
|
891
|
+
* @type Function
|
892
|
+
* @alias extend
|
893
|
+
* @category Objects
|
894
|
+
* @param {Object} object The destination object.
|
895
|
+
* @param {Object} [source1, source2, ...] The source objects.
|
896
|
+
* @param {Function} [callback] The function to customize assigning values.
|
897
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
898
|
+
* @returns {Object} Returns the destination object.
|
899
|
+
* @example
|
900
|
+
*
|
901
|
+
* _.assign({ 'name': 'moe' }, { 'age': 40 });
|
902
|
+
* // => { 'name': 'moe', 'age': 40 }
|
903
|
+
*
|
904
|
+
* var defaults = _.partialRight(_.assign, function(a, b) {
|
905
|
+
* return typeof a == 'undefined' ? b : a;
|
906
|
+
* });
|
907
|
+
*
|
908
|
+
* var food = { 'name': 'apple' };
|
909
|
+
* defaults(food, { 'name': 'banana', 'type': 'fruit' });
|
910
|
+
* // => { 'name': 'apple', 'type': 'fruit' }
|
911
|
+
*/
|
912
|
+
var assign = createIterator(defaultsIteratorOptions, {
|
913
|
+
'top':
|
914
|
+
defaultsIteratorOptions.top.replace(';',
|
915
|
+
';\n' +
|
916
|
+
"if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
|
917
|
+
' var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
|
918
|
+
"} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
|
919
|
+
' callback = args[--argsLength];\n' +
|
920
|
+
'}'
|
921
|
+
),
|
922
|
+
'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
|
923
|
+
});
|
924
|
+
|
972
925
|
/**
|
973
926
|
* Creates a clone of `value`. If `deep` is `true`, nested objects will also
|
974
|
-
* be cloned, otherwise they will be assigned by reference.
|
927
|
+
* be cloned, otherwise they will be assigned by reference. If a `callback`
|
928
|
+
* function is passed, it will be executed to produce the cloned values. If
|
929
|
+
* `callback` returns `undefined`, cloning will be handled by the method instead.
|
930
|
+
* The `callback` is bound to `thisArg` and invoked with one argument; (value).
|
975
931
|
*
|
976
932
|
* @static
|
977
933
|
* @memberOf _
|
978
934
|
* @category Objects
|
979
935
|
* @param {Mixed} value The value to clone.
|
980
|
-
* @param {Boolean} deep A flag to indicate a deep clone.
|
981
|
-
* @param
|
982
|
-
*
|
936
|
+
* @param {Boolean} [deep=false] A flag to indicate a deep clone.
|
937
|
+
* @param {Function} [callback] The function to customize cloning values.
|
938
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
983
939
|
* @param- {Array} [stackA=[]] Internally used to track traversed source objects.
|
984
|
-
* @param- {Array} [stackB=[]] Internally used to associate clones with
|
985
|
-
* source counterparts.
|
940
|
+
* @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts.
|
986
941
|
* @returns {Mixed} Returns the cloned `value`.
|
987
942
|
* @example
|
988
943
|
*
|
989
944
|
* var stooges = [
|
990
945
|
* { 'name': 'moe', 'age': 40 },
|
991
|
-
* { 'name': 'larry', 'age': 50 }
|
992
|
-
* { 'name': 'curly', 'age': 60 }
|
946
|
+
* { 'name': 'larry', 'age': 50 }
|
993
947
|
* ];
|
994
948
|
*
|
995
949
|
* var shallow = _.clone(stooges);
|
@@ -999,41 +953,63 @@
|
|
999
953
|
* var deep = _.clone(stooges, true);
|
1000
954
|
* deep[0] === stooges[0];
|
1001
955
|
* // => false
|
956
|
+
*
|
957
|
+
* _.mixin({
|
958
|
+
* 'clone': _.partialRight(_.clone, function(value) {
|
959
|
+
* return _.isElement(value) ? value.cloneNode(false) : undefined;
|
960
|
+
* })
|
961
|
+
* });
|
962
|
+
*
|
963
|
+
* var clone = _.clone(document.body);
|
964
|
+
* clone.childNodes.length;
|
965
|
+
* // => 0
|
1002
966
|
*/
|
1003
|
-
function clone(value, deep,
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
967
|
+
function clone(value, deep, callback, thisArg, stackA, stackB) {
|
968
|
+
var result = value;
|
969
|
+
|
970
|
+
// allows working with "Collections" methods without using their `callback`
|
971
|
+
// argument, `index|key`, for this method's `callback`
|
972
|
+
if (typeof deep == 'function') {
|
973
|
+
thisArg = callback;
|
974
|
+
callback = deep;
|
1008
975
|
deep = false;
|
1009
976
|
}
|
977
|
+
if (typeof callback == 'function') {
|
978
|
+
callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 1);
|
979
|
+
result = callback(result);
|
980
|
+
|
981
|
+
var done = typeof result != 'undefined';
|
982
|
+
if (!done) {
|
983
|
+
result = value;
|
984
|
+
}
|
985
|
+
}
|
1010
986
|
// inspect [[Class]]
|
1011
|
-
var isObj = isObject(
|
987
|
+
var isObj = isObject(result);
|
1012
988
|
if (isObj) {
|
1013
|
-
var className = toString.call(
|
1014
|
-
if (!cloneableClasses[className]
|
1015
|
-
return
|
989
|
+
var className = toString.call(result);
|
990
|
+
if (!cloneableClasses[className]) {
|
991
|
+
return result;
|
1016
992
|
}
|
1017
|
-
var isArr = isArray(
|
993
|
+
var isArr = isArray(result);
|
1018
994
|
}
|
1019
995
|
// shallow clone
|
1020
996
|
if (!isObj || !deep) {
|
1021
|
-
return isObj
|
1022
|
-
? (isArr ? slice(
|
1023
|
-
:
|
997
|
+
return isObj && !done
|
998
|
+
? (isArr ? slice(result) : assign({}, result))
|
999
|
+
: result;
|
1024
1000
|
}
|
1025
1001
|
var ctor = ctorByClass[className];
|
1026
1002
|
switch (className) {
|
1027
1003
|
case boolClass:
|
1028
1004
|
case dateClass:
|
1029
|
-
return new ctor(+
|
1005
|
+
return done ? result : new ctor(+result);
|
1030
1006
|
|
1031
1007
|
case numberClass:
|
1032
1008
|
case stringClass:
|
1033
|
-
return new ctor(
|
1009
|
+
return done ? result : new ctor(result);
|
1034
1010
|
|
1035
1011
|
case regexpClass:
|
1036
|
-
return ctor(
|
1012
|
+
return done ? result : ctor(result.source, reFlags.exec(result));
|
1037
1013
|
}
|
1038
1014
|
// check for circular references and return corresponding clone
|
1039
1015
|
stackA || (stackA = []);
|
@@ -1046,80 +1022,98 @@
|
|
1046
1022
|
}
|
1047
1023
|
}
|
1048
1024
|
// init cloned object
|
1049
|
-
|
1025
|
+
if (!done) {
|
1026
|
+
result = isArr ? ctor(result.length) : {};
|
1050
1027
|
|
1028
|
+
// add array properties assigned by `RegExp#exec`
|
1029
|
+
if (isArr) {
|
1030
|
+
if (hasOwnProperty.call(value, 'index')) {
|
1031
|
+
result.index = value.index;
|
1032
|
+
}
|
1033
|
+
if (hasOwnProperty.call(value, 'input')) {
|
1034
|
+
result.input = value.input;
|
1035
|
+
}
|
1036
|
+
}
|
1037
|
+
}
|
1051
1038
|
// add the source value to the stack of traversed objects
|
1052
1039
|
// and associate it with its clone
|
1053
1040
|
stackA.push(value);
|
1054
1041
|
stackB.push(result);
|
1055
1042
|
|
1056
1043
|
// recursively populate clone (susceptible to call stack limits)
|
1057
|
-
(isArr ? forEach : forOwn)(value, function(objValue, key) {
|
1058
|
-
result[key] = clone(objValue, deep,
|
1044
|
+
(isArr ? forEach : forOwn)(done ? result : value, function(objValue, key) {
|
1045
|
+
result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
|
1059
1046
|
});
|
1060
1047
|
|
1061
|
-
// add array properties assigned by `RegExp#exec`
|
1062
|
-
if (isArr) {
|
1063
|
-
if (hasOwnProperty.call(value, 'index')) {
|
1064
|
-
result.index = value.index;
|
1065
|
-
}
|
1066
|
-
if (hasOwnProperty.call(value, 'input')) {
|
1067
|
-
result.input = value.input;
|
1068
|
-
}
|
1069
|
-
}
|
1070
1048
|
return result;
|
1071
1049
|
}
|
1072
1050
|
|
1073
1051
|
/**
|
1074
|
-
* Creates a deep clone of `value`.
|
1075
|
-
*
|
1076
|
-
*
|
1052
|
+
* Creates a deep clone of `value`. If a `callback` function is passed, it will
|
1053
|
+
* be executed to produce the cloned values. If `callback` returns the value it
|
1054
|
+
* was passed, cloning will be handled by the method instead. The `callback` is
|
1055
|
+
* bound to `thisArg` and invoked with one argument; (value).
|
1077
1056
|
*
|
1078
|
-
* Note: This function is loosely based on the structured clone algorithm.
|
1079
|
-
*
|
1057
|
+
* Note: This function is loosely based on the structured clone algorithm. Functions
|
1058
|
+
* and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
|
1059
|
+
* objects created by constructors other than `Object` are cloned to plain `Object` objects.
|
1060
|
+
* See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
|
1080
1061
|
*
|
1081
1062
|
* @static
|
1082
1063
|
* @memberOf _
|
1083
1064
|
* @category Objects
|
1084
1065
|
* @param {Mixed} value The value to deep clone.
|
1066
|
+
* @param {Function} [callback] The function to customize cloning values.
|
1067
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1085
1068
|
* @returns {Mixed} Returns the deep cloned `value`.
|
1086
1069
|
* @example
|
1087
1070
|
*
|
1088
1071
|
* var stooges = [
|
1089
1072
|
* { 'name': 'moe', 'age': 40 },
|
1090
|
-
* { 'name': 'larry', 'age': 50 }
|
1091
|
-
* { 'name': 'curly', 'age': 60 }
|
1073
|
+
* { 'name': 'larry', 'age': 50 }
|
1092
1074
|
* ];
|
1093
1075
|
*
|
1094
1076
|
* var deep = _.cloneDeep(stooges);
|
1095
1077
|
* deep[0] === stooges[0];
|
1096
1078
|
* // => false
|
1079
|
+
*
|
1080
|
+
* var view = {
|
1081
|
+
* 'label': 'docs',
|
1082
|
+
* 'node': element
|
1083
|
+
* };
|
1084
|
+
*
|
1085
|
+
* var clone = _.cloneDeep(view, function(value) {
|
1086
|
+
* return _.isElement(value) ? value.cloneNode(true) : value;
|
1087
|
+
* });
|
1088
|
+
*
|
1089
|
+
* clone.node == view.node;
|
1090
|
+
* // => false
|
1097
1091
|
*/
|
1098
|
-
function cloneDeep(value) {
|
1099
|
-
return clone(value, true);
|
1092
|
+
function cloneDeep(value, callback, thisArg) {
|
1093
|
+
return clone(value, true, callback, thisArg);
|
1100
1094
|
}
|
1101
1095
|
|
1102
1096
|
/**
|
1103
|
-
* Assigns own enumerable properties of source object(s) to the
|
1104
|
-
* object for all
|
1105
|
-
*
|
1106
|
-
* ignored.
|
1097
|
+
* Assigns own enumerable properties of source object(s) to the destination
|
1098
|
+
* object for all destination properties that resolve to `undefined`. Once a
|
1099
|
+
* property is set, additional defaults of the same property will be ignored.
|
1107
1100
|
*
|
1108
1101
|
* @static
|
1109
1102
|
* @memberOf _
|
1103
|
+
* @type Function
|
1110
1104
|
* @category Objects
|
1111
1105
|
* @param {Object} object The destination object.
|
1112
|
-
* @param {Object} [
|
1106
|
+
* @param {Object} [source1, source2, ...] The source objects.
|
1107
|
+
* @param- {Object} [guard] Internally used to allow working with `_.reduce`
|
1108
|
+
* without using its callback's `key` and `object` arguments as sources.
|
1113
1109
|
* @returns {Object} Returns the destination object.
|
1114
1110
|
* @example
|
1115
1111
|
*
|
1116
|
-
* var
|
1117
|
-
* _.defaults(
|
1118
|
-
* // => { '
|
1112
|
+
* var food = { 'name': 'apple' };
|
1113
|
+
* _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
|
1114
|
+
* // => { 'name': 'apple', 'type': 'fruit' }
|
1119
1115
|
*/
|
1120
|
-
var defaults = createIterator(
|
1121
|
-
'objectLoop': 'if (result[index] == null) ' + assignIteratorOptions.objectLoop
|
1122
|
-
});
|
1116
|
+
var defaults = createIterator(defaultsIteratorOptions);
|
1123
1117
|
|
1124
1118
|
/**
|
1125
1119
|
* Creates a sorted array of all enumerable properties, own and inherited,
|
@@ -1175,47 +1169,30 @@
|
|
1175
1169
|
* @returns {Object} Returns the created inverted object.
|
1176
1170
|
* @example
|
1177
1171
|
*
|
1178
|
-
* _.invert({ 'first': '
|
1179
|
-
* // => { '
|
1172
|
+
* _.invert({ 'first': 'moe', 'second': 'larry' });
|
1173
|
+
* // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed)
|
1180
1174
|
*/
|
1181
1175
|
function invert(object) {
|
1182
|
-
var
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1176
|
+
var index = -1,
|
1177
|
+
props = keys(object),
|
1178
|
+
length = props.length,
|
1179
|
+
result = {};
|
1180
|
+
|
1181
|
+
while (++index < length) {
|
1182
|
+
var key = props[index];
|
1183
|
+
result[object[key]] = key;
|
1184
|
+
}
|
1186
1185
|
return result;
|
1187
1186
|
}
|
1188
1187
|
|
1189
1188
|
/**
|
1190
|
-
* Checks if `value` is
|
1191
|
-
*
|
1192
|
-
* @static
|
1193
|
-
* @memberOf _
|
1194
|
-
* @category Objects
|
1195
|
-
* @param {Mixed} value The value to check.
|
1196
|
-
* @returns {Boolean} Returns `true` if the `value` is an array, else `false`.
|
1197
|
-
* @example
|
1198
|
-
*
|
1199
|
-
* (function() { return _.isArray(arguments); })();
|
1200
|
-
* // => false
|
1201
|
-
*
|
1202
|
-
* _.isArray([1, 2, 3]);
|
1203
|
-
* // => true
|
1204
|
-
*/
|
1205
|
-
var isArray = nativeIsArray || function(value) {
|
1206
|
-
// `instanceof` may cause a memory leak in IE 7 if `value` is a host object
|
1207
|
-
// http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
|
1208
|
-
return (argsAreObjects && value instanceof Array) || toString.call(value) == arrayClass;
|
1209
|
-
};
|
1210
|
-
|
1211
|
-
/**
|
1212
|
-
* Checks if `value` is a boolean (`true` or `false`) value.
|
1189
|
+
* Checks if `value` is a boolean value.
|
1213
1190
|
*
|
1214
1191
|
* @static
|
1215
1192
|
* @memberOf _
|
1216
1193
|
* @category Objects
|
1217
1194
|
* @param {Mixed} value The value to check.
|
1218
|
-
* @returns {Boolean} Returns `true
|
1195
|
+
* @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
|
1219
1196
|
* @example
|
1220
1197
|
*
|
1221
1198
|
* _.isBoolean(null);
|
@@ -1232,7 +1209,7 @@
|
|
1232
1209
|
* @memberOf _
|
1233
1210
|
* @category Objects
|
1234
1211
|
* @param {Mixed} value The value to check.
|
1235
|
-
* @returns {Boolean} Returns `true
|
1212
|
+
* @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
|
1236
1213
|
* @example
|
1237
1214
|
*
|
1238
1215
|
* _.isDate(new Date);
|
@@ -1249,7 +1226,7 @@
|
|
1249
1226
|
* @memberOf _
|
1250
1227
|
* @category Objects
|
1251
1228
|
* @param {Mixed} value The value to check.
|
1252
|
-
* @returns {Boolean} Returns `true
|
1229
|
+
* @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
|
1253
1230
|
* @example
|
1254
1231
|
*
|
1255
1232
|
* _.isElement(document.body);
|
@@ -1268,7 +1245,7 @@
|
|
1268
1245
|
* @memberOf _
|
1269
1246
|
* @category Objects
|
1270
1247
|
* @param {Array|Object|String} value The value to inspect.
|
1271
|
-
* @returns {Boolean} Returns `true
|
1248
|
+
* @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
|
1272
1249
|
* @example
|
1273
1250
|
*
|
1274
1251
|
* _.isEmpty([1, 2, 3]);
|
@@ -1289,7 +1266,7 @@
|
|
1289
1266
|
length = value.length;
|
1290
1267
|
|
1291
1268
|
if ((className == arrayClass || className == stringClass ||
|
1292
|
-
className == argsClass
|
1269
|
+
className == argsClass) ||
|
1293
1270
|
(className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
|
1294
1271
|
return !length;
|
1295
1272
|
}
|
@@ -1301,48 +1278,84 @@
|
|
1301
1278
|
|
1302
1279
|
/**
|
1303
1280
|
* Performs a deep comparison between two values to determine if they are
|
1304
|
-
* equivalent to each other.
|
1281
|
+
* equivalent to each other. If `callback` is passed, it will be executed to
|
1282
|
+
* compare values. If `callback` returns `undefined`, comparisons will be handled
|
1283
|
+
* by the method instead. The `callback` is bound to `thisArg` and invoked with
|
1284
|
+
* two arguments; (a, b).
|
1305
1285
|
*
|
1306
1286
|
* @static
|
1307
1287
|
* @memberOf _
|
1308
1288
|
* @category Objects
|
1309
1289
|
* @param {Mixed} a The value to compare.
|
1310
1290
|
* @param {Mixed} b The other value to compare.
|
1291
|
+
* @param {Function} [callback] The function to customize comparing values.
|
1292
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1311
1293
|
* @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
|
1312
1294
|
* @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
|
1313
|
-
* @returns {Boolean} Returns `true
|
1295
|
+
* @returns {Boolean} Returns `true`, if the values are equvalent, else `false`.
|
1314
1296
|
* @example
|
1315
1297
|
*
|
1316
|
-
* var moe = { 'name': 'moe', '
|
1317
|
-
* var
|
1298
|
+
* var moe = { 'name': 'moe', 'age': 40 };
|
1299
|
+
* var copy = { 'name': 'moe', 'age': 40 };
|
1318
1300
|
*
|
1319
|
-
* moe ==
|
1301
|
+
* moe == copy;
|
1320
1302
|
* // => false
|
1321
1303
|
*
|
1322
|
-
* _.isEqual(moe,
|
1304
|
+
* _.isEqual(moe, copy);
|
1305
|
+
* // => true
|
1306
|
+
*
|
1307
|
+
* var words = ['hello', 'goodbye'];
|
1308
|
+
* var otherWords = ['hi', 'goodbye'];
|
1309
|
+
*
|
1310
|
+
* _.isEqual(words, otherWords, function(a, b) {
|
1311
|
+
* var reGreet = /^(?:hello|hi)$/i,
|
1312
|
+
* aGreet = _.isString(a) && reGreet.test(a),
|
1313
|
+
* bGreet = _.isString(b) && reGreet.test(b);
|
1314
|
+
*
|
1315
|
+
* return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
|
1316
|
+
* });
|
1323
1317
|
* // => true
|
1324
1318
|
*/
|
1325
|
-
function isEqual(a, b, stackA, stackB) {
|
1319
|
+
function isEqual(a, b, callback, thisArg, stackA, stackB) {
|
1320
|
+
// used to indicate that when comparing objects, `a` has at least the properties of `b`
|
1321
|
+
var whereIndicator = callback === indicatorObject;
|
1322
|
+
if (callback && !whereIndicator) {
|
1323
|
+
callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 2);
|
1324
|
+
var result = callback(a, b);
|
1325
|
+
if (typeof result != 'undefined') {
|
1326
|
+
return !!result;
|
1327
|
+
}
|
1328
|
+
}
|
1326
1329
|
// exit early for identical values
|
1327
1330
|
if (a === b) {
|
1328
1331
|
// treat `+0` vs. `-0` as not equal
|
1329
1332
|
return a !== 0 || (1 / a == 1 / b);
|
1330
1333
|
}
|
1331
|
-
|
1334
|
+
var type = typeof a,
|
1335
|
+
otherType = typeof b;
|
1336
|
+
|
1337
|
+
// exit early for unlike primitive values
|
1338
|
+
if (a === a &&
|
1339
|
+
(!a || (type != 'function' && type != 'object')) &&
|
1340
|
+
(!b || (otherType != 'function' && otherType != 'object'))) {
|
1341
|
+
return false;
|
1342
|
+
}
|
1343
|
+
// exit early for `null` and `undefined`, avoiding ES3's Function#call behavior
|
1344
|
+
// http://es5.github.com/#x15.3.4.4
|
1332
1345
|
if (a == null || b == null) {
|
1333
1346
|
return a === b;
|
1334
1347
|
}
|
1335
1348
|
// compare [[Class]] names
|
1336
1349
|
var className = toString.call(a),
|
1337
|
-
|
1350
|
+
otherClass = toString.call(b);
|
1338
1351
|
|
1339
1352
|
if (className == argsClass) {
|
1340
1353
|
className = objectClass;
|
1341
1354
|
}
|
1342
|
-
if (
|
1343
|
-
|
1355
|
+
if (otherClass == argsClass) {
|
1356
|
+
otherClass = objectClass;
|
1344
1357
|
}
|
1345
|
-
if (className !=
|
1358
|
+
if (className != otherClass) {
|
1346
1359
|
return false;
|
1347
1360
|
}
|
1348
1361
|
switch (className) {
|
@@ -1369,15 +1382,15 @@
|
|
1369
1382
|
if (!isArr) {
|
1370
1383
|
// unwrap any `lodash` wrapped values
|
1371
1384
|
if (a.__wrapped__ || b.__wrapped__) {
|
1372
|
-
return isEqual(a.__wrapped__ || a, b.__wrapped__ || b);
|
1385
|
+
return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, thisArg, stackA, stackB);
|
1373
1386
|
}
|
1374
1387
|
// exit for functions and DOM nodes
|
1375
|
-
if (className != objectClass
|
1388
|
+
if (className != objectClass) {
|
1376
1389
|
return false;
|
1377
1390
|
}
|
1378
1391
|
// in older versions of Opera, `arguments` objects have `Array` constructors
|
1379
|
-
var ctorA =
|
1380
|
-
ctorB =
|
1392
|
+
var ctorA = a.constructor,
|
1393
|
+
ctorB = b.constructor;
|
1381
1394
|
|
1382
1395
|
// non `Object` object instances with different constructors are not equal
|
1383
1396
|
if (ctorA != ctorB && !(
|
@@ -1399,9 +1412,8 @@
|
|
1399
1412
|
return stackB[length] == b;
|
1400
1413
|
}
|
1401
1414
|
}
|
1402
|
-
var
|
1403
|
-
|
1404
|
-
size = 0;
|
1415
|
+
var size = 0;
|
1416
|
+
result = true;
|
1405
1417
|
|
1406
1418
|
// add `a` and `b` to the stack of traversed objects
|
1407
1419
|
stackA.push(a);
|
@@ -1409,36 +1421,47 @@
|
|
1409
1421
|
|
1410
1422
|
// recursively compare objects and arrays (susceptible to call stack limits)
|
1411
1423
|
if (isArr) {
|
1412
|
-
|
1413
|
-
size =
|
1414
|
-
result = size == b.length;
|
1424
|
+
length = a.length;
|
1425
|
+
size = b.length;
|
1415
1426
|
|
1416
|
-
if
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1427
|
+
// compare lengths to determine if a deep comparison is necessary
|
1428
|
+
result = size == a.length;
|
1429
|
+
if (!result && !whereIndicator) {
|
1430
|
+
return result;
|
1431
|
+
}
|
1432
|
+
// deep compare the contents, ignoring non-numeric properties
|
1433
|
+
while (size--) {
|
1434
|
+
var index = length,
|
1435
|
+
value = b[size];
|
1436
|
+
|
1437
|
+
if (whereIndicator) {
|
1438
|
+
while (index--) {
|
1439
|
+
if ((result = isEqual(a[index], value, callback, thisArg, stackA, stackB))) {
|
1440
|
+
break;
|
1441
|
+
}
|
1421
1442
|
}
|
1443
|
+
} else if (!(result = isEqual(a[size], value, callback, thisArg, stackA, stackB))) {
|
1444
|
+
break;
|
1422
1445
|
}
|
1423
1446
|
}
|
1424
1447
|
return result;
|
1425
1448
|
}
|
1426
1449
|
// deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
|
1427
1450
|
// which, in this case, is more costly
|
1428
|
-
forIn(
|
1429
|
-
if (hasOwnProperty.call(
|
1451
|
+
forIn(b, function(value, key, b) {
|
1452
|
+
if (hasOwnProperty.call(b, key)) {
|
1430
1453
|
// count the number of properties.
|
1431
1454
|
size++;
|
1432
1455
|
// deep compare each property value.
|
1433
|
-
return (result = hasOwnProperty.call(
|
1456
|
+
return (result = hasOwnProperty.call(a, key) && isEqual(a[key], value, callback, thisArg, stackA, stackB));
|
1434
1457
|
}
|
1435
1458
|
});
|
1436
1459
|
|
1437
|
-
if (result) {
|
1460
|
+
if (result && !whereIndicator) {
|
1438
1461
|
// ensure both objects have the same number of properties
|
1439
|
-
forIn(
|
1440
|
-
if (hasOwnProperty.call(
|
1441
|
-
// `size` will be `-1` if `
|
1462
|
+
forIn(a, function(value, key, a) {
|
1463
|
+
if (hasOwnProperty.call(a, key)) {
|
1464
|
+
// `size` will be `-1` if `a` has more properties than `b`
|
1442
1465
|
return (result = --size > -1);
|
1443
1466
|
}
|
1444
1467
|
});
|
@@ -1456,7 +1479,7 @@
|
|
1456
1479
|
* @memberOf _
|
1457
1480
|
* @category Objects
|
1458
1481
|
* @param {Mixed} value The value to check.
|
1459
|
-
* @returns {Boolean} Returns `true
|
1482
|
+
* @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
|
1460
1483
|
* @example
|
1461
1484
|
*
|
1462
1485
|
* _.isFinite(-101);
|
@@ -1485,7 +1508,7 @@
|
|
1485
1508
|
* @memberOf _
|
1486
1509
|
* @category Objects
|
1487
1510
|
* @param {Mixed} value The value to check.
|
1488
|
-
* @returns {Boolean} Returns `true
|
1511
|
+
* @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
|
1489
1512
|
* @example
|
1490
1513
|
*
|
1491
1514
|
* _.isFunction(_);
|
@@ -1509,7 +1532,7 @@
|
|
1509
1532
|
* @memberOf _
|
1510
1533
|
* @category Objects
|
1511
1534
|
* @param {Mixed} value The value to check.
|
1512
|
-
* @returns {Boolean} Returns `true
|
1535
|
+
* @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
|
1513
1536
|
* @example
|
1514
1537
|
*
|
1515
1538
|
* _.isObject({});
|
@@ -1539,7 +1562,7 @@
|
|
1539
1562
|
* @memberOf _
|
1540
1563
|
* @category Objects
|
1541
1564
|
* @param {Mixed} value The value to check.
|
1542
|
-
* @returns {Boolean} Returns `true
|
1565
|
+
* @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
|
1543
1566
|
* @example
|
1544
1567
|
*
|
1545
1568
|
* _.isNaN(NaN);
|
@@ -1567,7 +1590,7 @@
|
|
1567
1590
|
* @memberOf _
|
1568
1591
|
* @category Objects
|
1569
1592
|
* @param {Mixed} value The value to check.
|
1570
|
-
* @returns {Boolean} Returns `true
|
1593
|
+
* @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
|
1571
1594
|
* @example
|
1572
1595
|
*
|
1573
1596
|
* _.isNull(null);
|
@@ -1587,7 +1610,7 @@
|
|
1587
1610
|
* @memberOf _
|
1588
1611
|
* @category Objects
|
1589
1612
|
* @param {Mixed} value The value to check.
|
1590
|
-
* @returns {Boolean} Returns `true
|
1613
|
+
* @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
|
1591
1614
|
* @example
|
1592
1615
|
*
|
1593
1616
|
* _.isNumber(8.4 * 5);
|
@@ -1604,7 +1627,7 @@
|
|
1604
1627
|
* @memberOf _
|
1605
1628
|
* @category Objects
|
1606
1629
|
* @param {Mixed} value The value to check.
|
1607
|
-
* @returns {Boolean} Returns `true
|
1630
|
+
* @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
|
1608
1631
|
* @example
|
1609
1632
|
*
|
1610
1633
|
* function Stooge(name, age) {
|
@@ -1621,7 +1644,7 @@
|
|
1621
1644
|
* _.isPlainObject({ 'name': 'moe', 'age': 40 });
|
1622
1645
|
* // => true
|
1623
1646
|
*/
|
1624
|
-
var isPlainObject =
|
1647
|
+
var isPlainObject = function(value) {
|
1625
1648
|
if (!(value && typeof value == 'object')) {
|
1626
1649
|
return false;
|
1627
1650
|
}
|
@@ -1640,7 +1663,7 @@
|
|
1640
1663
|
* @memberOf _
|
1641
1664
|
* @category Objects
|
1642
1665
|
* @param {Mixed} value The value to check.
|
1643
|
-
* @returns {Boolean} Returns `true
|
1666
|
+
* @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
|
1644
1667
|
* @example
|
1645
1668
|
*
|
1646
1669
|
* _.isRegExp(/moe/);
|
@@ -1657,7 +1680,7 @@
|
|
1657
1680
|
* @memberOf _
|
1658
1681
|
* @category Objects
|
1659
1682
|
* @param {Mixed} value The value to check.
|
1660
|
-
* @returns {Boolean} Returns `true
|
1683
|
+
* @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
|
1661
1684
|
* @example
|
1662
1685
|
*
|
1663
1686
|
* _.isString('moe');
|
@@ -1674,7 +1697,7 @@
|
|
1674
1697
|
* @memberOf _
|
1675
1698
|
* @category Objects
|
1676
1699
|
* @param {Mixed} value The value to check.
|
1677
|
-
* @returns {Boolean} Returns `true
|
1700
|
+
* @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
|
1678
1701
|
* @example
|
1679
1702
|
*
|
1680
1703
|
* _.isUndefined(void 0);
|
@@ -1685,100 +1708,137 @@
|
|
1685
1708
|
}
|
1686
1709
|
|
1687
1710
|
/**
|
1688
|
-
*
|
1689
|
-
*
|
1690
|
-
*
|
1691
|
-
*
|
1692
|
-
*
|
1693
|
-
*
|
1694
|
-
*
|
1695
|
-
* @example
|
1696
|
-
*
|
1697
|
-
* _.keys({ 'one': 1, 'two': 2, 'three': 3 });
|
1698
|
-
* // => ['one', 'two', 'three'] (order is not guaranteed)
|
1699
|
-
*/
|
1700
|
-
var keys = !nativeKeys ? shimKeys : function(object) {
|
1701
|
-
// avoid iterating over the `prototype` property
|
1702
|
-
return typeof object == 'function' && propertyIsEnumerable.call(object, 'prototype')
|
1703
|
-
? shimKeys(object)
|
1704
|
-
: (isObject(object) ? nativeKeys(object) : []);
|
1705
|
-
};
|
1706
|
-
|
1707
|
-
/**
|
1708
|
-
* Merges enumerable properties of the source object(s) into the `destination`
|
1709
|
-
* object. Subsequent sources will overwrite propery assignments of previous
|
1710
|
-
* sources.
|
1711
|
+
* Recursively merges own enumerable properties of the source object(s), that
|
1712
|
+
* don't resolve to `undefined`, into the destination object. Subsequent sources
|
1713
|
+
* will overwrite propery assignments of previous sources. If a `callback` function
|
1714
|
+
* is passed, it will be executed to produce the merged values of the destination
|
1715
|
+
* and source properties. If `callback` returns `undefined`, merging will be
|
1716
|
+
* handled by the method instead. The `callback` is bound to `thisArg` and
|
1717
|
+
* invoked with two arguments; (objectValue, sourceValue).
|
1711
1718
|
*
|
1712
1719
|
* @static
|
1713
1720
|
* @memberOf _
|
1714
1721
|
* @category Objects
|
1715
1722
|
* @param {Object} object The destination object.
|
1716
1723
|
* @param {Object} [source1, source2, ...] The source objects.
|
1717
|
-
* @param
|
1718
|
-
*
|
1724
|
+
* @param {Function} [callback] The function to customize merging properties.
|
1725
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1726
|
+
* @param- {Object} [deepIndicator] Internally used to indicate that `stackA`
|
1727
|
+
* and `stackB` are arrays of traversed objects instead of source objects.
|
1719
1728
|
* @param- {Array} [stackA=[]] Internally used to track traversed source objects.
|
1720
1729
|
* @param- {Array} [stackB=[]] Internally used to associate values with their
|
1721
1730
|
* source counterparts.
|
1722
1731
|
* @returns {Object} Returns the destination object.
|
1723
1732
|
* @example
|
1724
1733
|
*
|
1725
|
-
* var
|
1726
|
-
*
|
1727
|
-
*
|
1728
|
-
*
|
1734
|
+
* var names = {
|
1735
|
+
* 'stooges': [
|
1736
|
+
* { 'name': 'moe' },
|
1737
|
+
* { 'name': 'larry' }
|
1738
|
+
* ]
|
1739
|
+
* };
|
1729
1740
|
*
|
1730
|
-
* var ages =
|
1731
|
-
*
|
1732
|
-
*
|
1733
|
-
*
|
1741
|
+
* var ages = {
|
1742
|
+
* 'stooges': [
|
1743
|
+
* { 'age': 40 },
|
1744
|
+
* { 'age': 50 }
|
1745
|
+
* ]
|
1746
|
+
* };
|
1747
|
+
*
|
1748
|
+
* _.merge(names, ages);
|
1749
|
+
* // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
|
1750
|
+
*
|
1751
|
+
* var food = {
|
1752
|
+
* 'fruits': ['apple'],
|
1753
|
+
* 'vegetables': ['beet']
|
1754
|
+
* };
|
1734
1755
|
*
|
1735
|
-
*
|
1736
|
-
*
|
1756
|
+
* var otherFood = {
|
1757
|
+
* 'fruits': ['banana'],
|
1758
|
+
* 'vegetables': ['carrot']
|
1759
|
+
* };
|
1760
|
+
*
|
1761
|
+
* _.merge(food, otherFood, function(a, b) {
|
1762
|
+
* return _.isArray(a) ? a.concat(b) : undefined;
|
1763
|
+
* });
|
1764
|
+
* // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
|
1737
1765
|
*/
|
1738
|
-
function merge(object, source,
|
1766
|
+
function merge(object, source, deepIndicator) {
|
1739
1767
|
var args = arguments,
|
1740
1768
|
index = 0,
|
1741
|
-
length = 2
|
1742
|
-
stackA = args[3],
|
1743
|
-
stackB = args[4];
|
1769
|
+
length = 2;
|
1744
1770
|
|
1745
|
-
if (
|
1771
|
+
if (!isObject(object)) {
|
1772
|
+
return object;
|
1773
|
+
}
|
1774
|
+
if (deepIndicator === indicatorObject) {
|
1775
|
+
var callback = args[3],
|
1776
|
+
stackA = args[4],
|
1777
|
+
stackB = args[5];
|
1778
|
+
} else {
|
1746
1779
|
stackA = [];
|
1747
1780
|
stackB = [];
|
1748
1781
|
|
1749
|
-
//
|
1750
|
-
|
1782
|
+
// allows working with `_.reduce` and `_.reduceRight` without
|
1783
|
+
// using their `callback` arguments, `index|key` and `collection`
|
1784
|
+
if (typeof deepIndicator != 'number') {
|
1751
1785
|
length = args.length;
|
1752
1786
|
}
|
1787
|
+
if (length > 3 && typeof args[length - 2] == 'function') {
|
1788
|
+
callback = createCallback(args[--length - 1], args[length--], 2);
|
1789
|
+
} else if (length > 2 && typeof args[length - 1] == 'function') {
|
1790
|
+
callback = args[--length];
|
1791
|
+
}
|
1753
1792
|
}
|
1754
1793
|
while (++index < length) {
|
1755
|
-
forOwn(args[index], function(source, key) {
|
1756
|
-
var found,
|
1794
|
+
(isArray(args[index]) ? forEach : forOwn)(args[index], function(source, key) {
|
1795
|
+
var found,
|
1796
|
+
isArr,
|
1797
|
+
result = source,
|
1798
|
+
value = object[key];
|
1799
|
+
|
1757
1800
|
if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
|
1758
1801
|
// avoid merging previously merged cyclic sources
|
1759
1802
|
var stackLength = stackA.length;
|
1760
1803
|
while (stackLength--) {
|
1761
|
-
found = stackA[stackLength] == source
|
1762
|
-
|
1804
|
+
if ((found = stackA[stackLength] == source)) {
|
1805
|
+
value = stackB[stackLength];
|
1763
1806
|
break;
|
1764
1807
|
}
|
1765
1808
|
}
|
1766
|
-
if (found) {
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1809
|
+
if (!found) {
|
1810
|
+
value = isArr
|
1811
|
+
? (isArray(value) ? value : [])
|
1812
|
+
: (isPlainObject(value) ? value : {});
|
1813
|
+
|
1814
|
+
if (callback) {
|
1815
|
+
result = callback(value, source);
|
1816
|
+
if (typeof result != 'undefined') {
|
1817
|
+
value = result;
|
1818
|
+
}
|
1819
|
+
}
|
1770
1820
|
// add `source` and associated `value` to the stack of traversed objects
|
1771
1821
|
stackA.push(source);
|
1772
|
-
stackB.push(value
|
1773
|
-
|
1774
|
-
: (isPlainObject(value) ? value : {})
|
1775
|
-
);
|
1822
|
+
stackB.push(value);
|
1823
|
+
|
1776
1824
|
// recursively merge objects and arrays (susceptible to call stack limits)
|
1777
|
-
|
1825
|
+
if (!callback) {
|
1826
|
+
value = merge(value, source, indicatorObject, callback, stackA, stackB);
|
1827
|
+
}
|
1828
|
+
}
|
1829
|
+
}
|
1830
|
+
else {
|
1831
|
+
if (callback) {
|
1832
|
+
result = callback(value, source);
|
1833
|
+
if (typeof result == 'undefined') {
|
1834
|
+
result = source;
|
1835
|
+
}
|
1836
|
+
}
|
1837
|
+
if (typeof result != 'undefined') {
|
1838
|
+
value = result;
|
1778
1839
|
}
|
1779
|
-
} else if (source != null) {
|
1780
|
-
object[key] = source;
|
1781
1840
|
}
|
1841
|
+
object[key] = value;
|
1782
1842
|
});
|
1783
1843
|
}
|
1784
1844
|
return object;
|
@@ -1787,9 +1847,10 @@
|
|
1787
1847
|
/**
|
1788
1848
|
* Creates a shallow clone of `object` excluding the specified properties.
|
1789
1849
|
* Property names may be specified as individual arguments or as arrays of
|
1790
|
-
* property names. If `callback` is passed, it will be executed
|
1791
|
-
* in the `object`, omitting the properties `callback`
|
1792
|
-
* `callback` is bound to `thisArg` and invoked
|
1850
|
+
* property names. If a `callback` function is passed, it will be executed
|
1851
|
+
* for each property in the `object`, omitting the properties `callback`
|
1852
|
+
* returns truthy for. The `callback` is bound to `thisArg` and invoked
|
1853
|
+
* with three arguments; (value, key, object).
|
1793
1854
|
*
|
1794
1855
|
* @static
|
1795
1856
|
* @memberOf _
|
@@ -1801,11 +1862,11 @@
|
|
1801
1862
|
* @returns {Object} Returns an object without the omitted properties.
|
1802
1863
|
* @example
|
1803
1864
|
*
|
1804
|
-
* _.omit({ 'name': 'moe', 'age': 40
|
1805
|
-
* // => { 'name': 'moe'
|
1865
|
+
* _.omit({ 'name': 'moe', 'age': 40 }, 'age');
|
1866
|
+
* // => { 'name': 'moe' }
|
1806
1867
|
*
|
1807
|
-
* _.omit({ 'name': 'moe', '
|
1808
|
-
* return
|
1868
|
+
* _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
|
1869
|
+
* return typeof value == 'number';
|
1809
1870
|
* });
|
1810
1871
|
* // => { 'name': 'moe' }
|
1811
1872
|
*/
|
@@ -1840,38 +1901,43 @@
|
|
1840
1901
|
* @returns {Array} Returns new array of key-value pairs.
|
1841
1902
|
* @example
|
1842
1903
|
*
|
1843
|
-
* _.pairs({ 'moe': 30, 'larry': 40
|
1844
|
-
* // => [['moe', 30], ['larry', 40]
|
1904
|
+
* _.pairs({ 'moe': 30, 'larry': 40 });
|
1905
|
+
* // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
|
1845
1906
|
*/
|
1846
1907
|
function pairs(object) {
|
1847
|
-
var
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1908
|
+
var index = -1,
|
1909
|
+
props = keys(object),
|
1910
|
+
length = props.length,
|
1911
|
+
result = Array(length);
|
1912
|
+
|
1913
|
+
while (++index < length) {
|
1914
|
+
var key = props[index];
|
1915
|
+
result[index] = [key, object[key]];
|
1916
|
+
}
|
1851
1917
|
return result;
|
1852
1918
|
}
|
1853
1919
|
|
1854
1920
|
/**
|
1855
1921
|
* Creates a shallow clone of `object` composed of the specified properties.
|
1856
|
-
* Property names may be specified as individual arguments or as arrays of
|
1857
|
-
*
|
1858
|
-
*
|
1859
|
-
*
|
1922
|
+
* Property names may be specified as individual arguments or as arrays of property
|
1923
|
+
* names. If `callback` is passed, it will be executed for each property in the
|
1924
|
+
* `object`, picking the properties `callback` returns truthy for. The `callback`
|
1925
|
+
* is bound to `thisArg` and invoked with three arguments; (value, key, object).
|
1860
1926
|
*
|
1861
1927
|
* @static
|
1862
1928
|
* @memberOf _
|
1863
1929
|
* @category Objects
|
1864
1930
|
* @param {Object} object The source object.
|
1865
|
-
* @param {Function|String} callback|[prop1, prop2, ...] The
|
1866
|
-
* or
|
1931
|
+
* @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
|
1932
|
+
* per iteration or properties to pick, either as individual arguments or arrays.
|
1867
1933
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1868
1934
|
* @returns {Object} Returns an object composed of the picked properties.
|
1869
1935
|
* @example
|
1870
1936
|
*
|
1871
|
-
* _.pick({ 'name': 'moe', '
|
1872
|
-
* // => { 'name': 'moe'
|
1937
|
+
* _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
|
1938
|
+
* // => { 'name': 'moe' }
|
1873
1939
|
*
|
1874
|
-
* _.pick({ 'name': 'moe', '
|
1940
|
+
* _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
|
1875
1941
|
* return key.charAt(0) != '_';
|
1876
1942
|
* });
|
1877
1943
|
* // => { 'name': 'moe' }
|
@@ -1881,7 +1947,7 @@
|
|
1881
1947
|
if (typeof callback != 'function') {
|
1882
1948
|
var index = 0,
|
1883
1949
|
props = concat.apply(arrayRef, arguments),
|
1884
|
-
length = props.length;
|
1950
|
+
length = isObject(object) ? props.length : 0;
|
1885
1951
|
|
1886
1952
|
while (++index < length) {
|
1887
1953
|
var key = props[index];
|
@@ -1914,15 +1980,52 @@
|
|
1914
1980
|
* // => [1, 2, 3]
|
1915
1981
|
*/
|
1916
1982
|
function values(object) {
|
1917
|
-
var
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1983
|
+
var index = -1,
|
1984
|
+
props = keys(object),
|
1985
|
+
length = props.length,
|
1986
|
+
result = Array(length);
|
1987
|
+
|
1988
|
+
while (++index < length) {
|
1989
|
+
result[index] = object[props[index]];
|
1990
|
+
}
|
1991
|
+
return result;
|
1992
|
+
}
|
1993
|
+
|
1994
|
+
/*--------------------------------------------------------------------------*/
|
1995
|
+
|
1996
|
+
/**
|
1997
|
+
* Creates an array of elements from the specified indexes, or keys, of the
|
1998
|
+
* `collection`. Indexes may be specified as individual arguments or as arrays
|
1999
|
+
* of indexes.
|
2000
|
+
*
|
2001
|
+
* @static
|
2002
|
+
* @memberOf _
|
2003
|
+
* @category Collections
|
2004
|
+
* @param {Array|Object|String} collection The collection to iterate over.
|
2005
|
+
* @param {Array|Number|String} [index1, index2, ...] The indexes of
|
2006
|
+
* `collection` to retrieve, either as individual arguments or arrays.
|
2007
|
+
* @returns {Array} Returns a new array of elements corresponding to the
|
2008
|
+
* provided indexes.
|
2009
|
+
* @example
|
2010
|
+
*
|
2011
|
+
* _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
|
2012
|
+
* // => ['a', 'c', 'e']
|
2013
|
+
*
|
2014
|
+
* _.at(['moe', 'larry', 'curly'], 0, 2);
|
2015
|
+
* // => ['moe', 'curly']
|
2016
|
+
*/
|
2017
|
+
function at(collection) {
|
2018
|
+
var index = -1,
|
2019
|
+
props = concat.apply(arrayRef, slice(arguments, 1)),
|
2020
|
+
length = props.length,
|
2021
|
+
result = Array(length);
|
2022
|
+
|
2023
|
+
while(++index < length) {
|
2024
|
+
result[index] = collection[props[index]];
|
2025
|
+
}
|
1921
2026
|
return result;
|
1922
2027
|
}
|
1923
2028
|
|
1924
|
-
/*--------------------------------------------------------------------------*/
|
1925
|
-
|
1926
2029
|
/**
|
1927
2030
|
* Checks if a given `target` element is present in a `collection` using strict
|
1928
2031
|
* equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
|
@@ -1972,18 +2075,25 @@
|
|
1972
2075
|
}
|
1973
2076
|
|
1974
2077
|
/**
|
1975
|
-
* Creates an object composed of keys returned from running each element of
|
1976
|
-
* `collection` through
|
1977
|
-
* the number of times the key was returned by `callback`. The `callback`
|
1978
|
-
* bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
|
1979
|
-
*
|
2078
|
+
* Creates an object composed of keys returned from running each element of the
|
2079
|
+
* `collection` through the given `callback`. The corresponding value of each key
|
2080
|
+
* is the number of times the key was returned by the `callback`. The `callback`
|
2081
|
+
* is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2082
|
+
*
|
2083
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2084
|
+
* callback will return the property value of the given element.
|
2085
|
+
*
|
2086
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2087
|
+
* will return `true` for elements that have the propeties of the given object,
|
2088
|
+
* else `false`.
|
1980
2089
|
*
|
1981
2090
|
* @static
|
1982
2091
|
* @memberOf _
|
1983
2092
|
* @category Collections
|
1984
2093
|
* @param {Array|Object|String} collection The collection to iterate over.
|
1985
|
-
* @param {Function|String} callback
|
1986
|
-
*
|
2094
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2095
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2096
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
1987
2097
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
1988
2098
|
* @returns {Object} Returns the composed aggregate object.
|
1989
2099
|
* @example
|
@@ -2002,7 +2112,7 @@
|
|
2002
2112
|
callback = createCallback(callback, thisArg);
|
2003
2113
|
|
2004
2114
|
forEach(collection, function(value, key, collection) {
|
2005
|
-
key = callback(value, key, collection);
|
2115
|
+
key = callback(value, key, collection) + '';
|
2006
2116
|
(hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
|
2007
2117
|
});
|
2008
2118
|
return result;
|
@@ -2013,12 +2123,21 @@
|
|
2013
2123
|
* `collection`. The `callback` is bound to `thisArg` and invoked with three
|
2014
2124
|
* arguments; (value, index|key, collection).
|
2015
2125
|
*
|
2126
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2127
|
+
* callback will return the property value of the given element.
|
2128
|
+
*
|
2129
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2130
|
+
* will return `true` for elements that have the propeties of the given object,
|
2131
|
+
* else `false`.
|
2132
|
+
*
|
2016
2133
|
* @static
|
2017
2134
|
* @memberOf _
|
2018
2135
|
* @alias all
|
2019
2136
|
* @category Collections
|
2020
2137
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2021
|
-
* @param {Function} [callback=identity] The function called per
|
2138
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2139
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2140
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2022
2141
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2023
2142
|
* @returns {Boolean} Returns `true` if all elements pass the callback check,
|
2024
2143
|
* else `false`.
|
@@ -2026,6 +2145,19 @@
|
|
2026
2145
|
*
|
2027
2146
|
* _.every([true, 1, null, 'yes'], Boolean);
|
2028
2147
|
* // => false
|
2148
|
+
*
|
2149
|
+
* var stooges = [
|
2150
|
+
* { 'name': 'moe', 'age': 40 },
|
2151
|
+
* { 'name': 'larry', 'age': 50 }
|
2152
|
+
* ];
|
2153
|
+
*
|
2154
|
+
* // using "_.pluck" callback shorthand
|
2155
|
+
* _.every(stooges, 'age');
|
2156
|
+
* // => true
|
2157
|
+
*
|
2158
|
+
* // using "_.where" callback shorthand
|
2159
|
+
* _.every(stooges, { 'age': 50 });
|
2160
|
+
* // => false
|
2029
2161
|
*/
|
2030
2162
|
function every(collection, callback, thisArg) {
|
2031
2163
|
var result = true;
|
@@ -2053,18 +2185,40 @@
|
|
2053
2185
|
* the `callback` returns truthy for. The `callback` is bound to `thisArg` and
|
2054
2186
|
* invoked with three arguments; (value, index|key, collection).
|
2055
2187
|
*
|
2188
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2189
|
+
* callback will return the property value of the given element.
|
2190
|
+
*
|
2191
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2192
|
+
* will return `true` for elements that have the propeties of the given object,
|
2193
|
+
* else `false`.
|
2194
|
+
*
|
2056
2195
|
* @static
|
2057
2196
|
* @memberOf _
|
2058
2197
|
* @alias select
|
2059
2198
|
* @category Collections
|
2060
2199
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2061
|
-
* @param {Function} [callback=identity] The function called per
|
2200
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2201
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2202
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2062
2203
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2063
2204
|
* @returns {Array} Returns a new array of elements that passed the callback check.
|
2064
2205
|
* @example
|
2065
2206
|
*
|
2066
2207
|
* var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
2067
2208
|
* // => [2, 4, 6]
|
2209
|
+
*
|
2210
|
+
* var food = [
|
2211
|
+
* { 'name': 'apple', 'organic': false, 'type': 'fruit' },
|
2212
|
+
* { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
|
2213
|
+
* ];
|
2214
|
+
*
|
2215
|
+
* // using "_.pluck" callback shorthand
|
2216
|
+
* _.filter(food, 'organic');
|
2217
|
+
* // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
|
2218
|
+
*
|
2219
|
+
* // using "_.where" callback shorthand
|
2220
|
+
* _.filter(food, { 'type': 'fruit' });
|
2221
|
+
* // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
|
2068
2222
|
*/
|
2069
2223
|
function filter(collection, callback, thisArg) {
|
2070
2224
|
var result = [];
|
@@ -2091,17 +2245,25 @@
|
|
2091
2245
|
}
|
2092
2246
|
|
2093
2247
|
/**
|
2094
|
-
* Examines each element in a `collection`, returning the first
|
2095
|
-
* returns truthy for. The
|
2096
|
-
*
|
2097
|
-
*
|
2248
|
+
* Examines each element in a `collection`, returning the first that the `callback`
|
2249
|
+
* returns truthy for. The `callback` is bound to `thisArg` and invoked with three
|
2250
|
+
* arguments; (value, index|key, collection).
|
2251
|
+
*
|
2252
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2253
|
+
* callback will return the property value of the given element.
|
2254
|
+
*
|
2255
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2256
|
+
* will return `true` for elements that have the propeties of the given object,
|
2257
|
+
* else `false`.
|
2098
2258
|
*
|
2099
2259
|
* @static
|
2100
2260
|
* @memberOf _
|
2101
2261
|
* @alias detect
|
2102
2262
|
* @category Collections
|
2103
2263
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2104
|
-
* @param {Function} [callback=identity] The function called per
|
2264
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2265
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2266
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2105
2267
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2106
2268
|
* @returns {Mixed} Returns the element that passed the callback check,
|
2107
2269
|
* else `undefined`.
|
@@ -2109,6 +2271,21 @@
|
|
2109
2271
|
*
|
2110
2272
|
* var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
2111
2273
|
* // => 2
|
2274
|
+
*
|
2275
|
+
* var food = [
|
2276
|
+
* { 'name': 'apple', 'organic': false, 'type': 'fruit' },
|
2277
|
+
* { 'name': 'banana', 'organic': true, 'type': 'fruit' },
|
2278
|
+
* { 'name': 'beet', 'organic': false, 'type': 'vegetable' },
|
2279
|
+
* { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
|
2280
|
+
* ];
|
2281
|
+
*
|
2282
|
+
* // using "_.where" callback shorthand
|
2283
|
+
* var veggie = _.find(food, { 'type': 'vegetable' });
|
2284
|
+
* // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
|
2285
|
+
*
|
2286
|
+
* // using "_.pluck" callback shorthand
|
2287
|
+
* var healthy = _.find(food, 'organic');
|
2288
|
+
* // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
|
2112
2289
|
*/
|
2113
2290
|
function find(collection, callback, thisArg) {
|
2114
2291
|
var result;
|
@@ -2162,18 +2339,25 @@
|
|
2162
2339
|
}
|
2163
2340
|
|
2164
2341
|
/**
|
2165
|
-
* Creates an object composed of keys returned from running each element of
|
2166
|
-
* `collection` through
|
2167
|
-
* array of elements passed to `callback` that returned the key. The `callback`
|
2342
|
+
* Creates an object composed of keys returned from running each element of the
|
2343
|
+
* `collection` through the `callback`. The corresponding value of each key is
|
2344
|
+
* an array of elements passed to `callback` that returned the key. The `callback`
|
2168
2345
|
* is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2169
|
-
*
|
2346
|
+
*
|
2347
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2348
|
+
* callback will return the property value of the given element.
|
2349
|
+
*
|
2350
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2351
|
+
* will return `true` for elements that have the propeties of the given object,
|
2352
|
+
* else `false`
|
2170
2353
|
*
|
2171
2354
|
* @static
|
2172
2355
|
* @memberOf _
|
2173
2356
|
* @category Collections
|
2174
2357
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2175
|
-
* @param {Function|String} callback
|
2176
|
-
*
|
2358
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2359
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2360
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2177
2361
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2178
2362
|
* @returns {Object} Returns the composed aggregate object.
|
2179
2363
|
* @example
|
@@ -2184,6 +2368,7 @@
|
|
2184
2368
|
* _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
|
2185
2369
|
* // => { '4': [4.2], '6': [6.1, 6.4] }
|
2186
2370
|
*
|
2371
|
+
* // using "_.pluck" callback shorthand
|
2187
2372
|
* _.groupBy(['one', 'two', 'three'], 'length');
|
2188
2373
|
* // => { '3': ['one', 'two'], '5': ['three'] }
|
2189
2374
|
*/
|
@@ -2192,7 +2377,7 @@
|
|
2192
2377
|
callback = createCallback(callback, thisArg);
|
2193
2378
|
|
2194
2379
|
forEach(collection, function(value, key, collection) {
|
2195
|
-
key = callback(value, key, collection);
|
2380
|
+
key = callback(value, key, collection) + '';
|
2196
2381
|
(hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
|
2197
2382
|
});
|
2198
2383
|
return result;
|
@@ -2201,7 +2386,7 @@
|
|
2201
2386
|
/**
|
2202
2387
|
* Invokes the method named by `methodName` on each element in the `collection`,
|
2203
2388
|
* returning an array of the results of each invoked method. Additional arguments
|
2204
|
-
* will be passed to each invoked method. If `methodName` is a function it will
|
2389
|
+
* will be passed to each invoked method. If `methodName` is a function, it will
|
2205
2390
|
* be invoked for, and `this` bound to, each element in the `collection`.
|
2206
2391
|
*
|
2207
2392
|
* @static
|
@@ -2222,26 +2407,37 @@
|
|
2222
2407
|
*/
|
2223
2408
|
function invoke(collection, methodName) {
|
2224
2409
|
var args = slice(arguments, 2),
|
2410
|
+
index = -1,
|
2225
2411
|
isFunc = typeof methodName == 'function',
|
2226
|
-
|
2412
|
+
length = collection ? collection.length : 0,
|
2413
|
+
result = Array(typeof length == 'number' ? length : 0);
|
2227
2414
|
|
2228
2415
|
forEach(collection, function(value) {
|
2229
|
-
result
|
2416
|
+
result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
|
2230
2417
|
});
|
2231
2418
|
return result;
|
2232
2419
|
}
|
2233
2420
|
|
2234
2421
|
/**
|
2235
2422
|
* Creates an array of values by running each element in the `collection`
|
2236
|
-
* through
|
2423
|
+
* through the `callback`. The `callback` is bound to `thisArg` and invoked with
|
2237
2424
|
* three arguments; (value, index|key, collection).
|
2238
2425
|
*
|
2426
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2427
|
+
* callback will return the property value of the given element.
|
2428
|
+
*
|
2429
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2430
|
+
* will return `true` for elements that have the propeties of the given object,
|
2431
|
+
* else `false`.
|
2432
|
+
*
|
2239
2433
|
* @static
|
2240
2434
|
* @memberOf _
|
2241
2435
|
* @alias collect
|
2242
2436
|
* @category Collections
|
2243
2437
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2244
|
-
* @param {Function} [callback=identity] The function called per
|
2438
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2439
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2440
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2245
2441
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2246
2442
|
* @returns {Array} Returns a new array of the results of each `callback` execution.
|
2247
2443
|
* @example
|
@@ -2251,6 +2447,15 @@
|
|
2251
2447
|
*
|
2252
2448
|
* _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
|
2253
2449
|
* // => [3, 6, 9] (order is not guaranteed)
|
2450
|
+
*
|
2451
|
+
* var stooges = [
|
2452
|
+
* { 'name': 'moe', 'age': 40 },
|
2453
|
+
* { 'name': 'larry', 'age': 50 }
|
2454
|
+
* ];
|
2455
|
+
*
|
2456
|
+
* // using "_.pluck" callback shorthand
|
2457
|
+
* _.map(stooges, 'name');
|
2458
|
+
* // => ['moe', 'larry']
|
2254
2459
|
*/
|
2255
2460
|
function map(collection, callback, thisArg) {
|
2256
2461
|
var index = -1,
|
@@ -2276,31 +2481,54 @@
|
|
2276
2481
|
* criterion by which the value is ranked. The `callback` is bound to
|
2277
2482
|
* `thisArg` and invoked with three arguments; (value, index, collection).
|
2278
2483
|
*
|
2484
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2485
|
+
* callback will return the property value of the given element.
|
2486
|
+
*
|
2487
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2488
|
+
* will return `true` for elements that have the propeties of the given object,
|
2489
|
+
* else `false`.
|
2490
|
+
*
|
2279
2491
|
* @static
|
2280
2492
|
* @memberOf _
|
2281
2493
|
* @category Collections
|
2282
2494
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2283
|
-
* @param {Function} [callback] The function called per
|
2495
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2496
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2497
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2284
2498
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2285
2499
|
* @returns {Mixed} Returns the maximum value.
|
2286
2500
|
* @example
|
2287
2501
|
*
|
2502
|
+
* _.max([4, 2, 8, 6]);
|
2503
|
+
* // => 8
|
2504
|
+
*
|
2288
2505
|
* var stooges = [
|
2289
2506
|
* { 'name': 'moe', 'age': 40 },
|
2290
|
-
* { 'name': 'larry', 'age': 50 }
|
2291
|
-
* { 'name': 'curly', 'age': 60 }
|
2507
|
+
* { 'name': 'larry', 'age': 50 }
|
2292
2508
|
* ];
|
2293
2509
|
*
|
2294
2510
|
* _.max(stooges, function(stooge) { return stooge.age; });
|
2295
|
-
* // => { 'name': '
|
2511
|
+
* // => { 'name': 'larry', 'age': 50 };
|
2512
|
+
*
|
2513
|
+
* // using "_.pluck" callback shorthand
|
2514
|
+
* _.max(stooges, 'age');
|
2515
|
+
* // => { 'name': 'larry', 'age': 50 };
|
2296
2516
|
*/
|
2297
2517
|
function max(collection, callback, thisArg) {
|
2298
2518
|
var computed = -Infinity,
|
2299
|
-
index = -1,
|
2300
|
-
length = collection ? collection.length : 0,
|
2301
2519
|
result = computed;
|
2302
2520
|
|
2303
|
-
if (callback
|
2521
|
+
if (!callback && isArray(collection)) {
|
2522
|
+
var index = -1,
|
2523
|
+
length = collection.length;
|
2524
|
+
|
2525
|
+
while (++index < length) {
|
2526
|
+
var value = collection[index];
|
2527
|
+
if (value > result) {
|
2528
|
+
result = value;
|
2529
|
+
}
|
2530
|
+
}
|
2531
|
+
} else {
|
2304
2532
|
callback = !callback && isString(collection)
|
2305
2533
|
? charAtCallback
|
2306
2534
|
: createCallback(callback, thisArg);
|
@@ -2312,12 +2540,6 @@
|
|
2312
2540
|
result = value;
|
2313
2541
|
}
|
2314
2542
|
});
|
2315
|
-
} else {
|
2316
|
-
while (++index < length) {
|
2317
|
-
if (collection[index] > result) {
|
2318
|
-
result = collection[index];
|
2319
|
-
}
|
2320
|
-
}
|
2321
2543
|
}
|
2322
2544
|
return result;
|
2323
2545
|
}
|
@@ -2328,25 +2550,54 @@
|
|
2328
2550
|
* criterion by which the value is ranked. The `callback` is bound to `thisArg`
|
2329
2551
|
* and invoked with three arguments; (value, index, collection).
|
2330
2552
|
*
|
2553
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2554
|
+
* callback will return the property value of the given element.
|
2555
|
+
*
|
2556
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2557
|
+
* will return `true` for elements that have the propeties of the given object,
|
2558
|
+
* else `false`.
|
2559
|
+
*
|
2331
2560
|
* @static
|
2332
2561
|
* @memberOf _
|
2333
2562
|
* @category Collections
|
2334
2563
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2335
|
-
* @param {Function} [callback] The function called per
|
2564
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2565
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2566
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2336
2567
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2337
2568
|
* @returns {Mixed} Returns the minimum value.
|
2338
2569
|
* @example
|
2339
2570
|
*
|
2340
|
-
* _.min([
|
2571
|
+
* _.min([4, 2, 8, 6]);
|
2341
2572
|
* // => 2
|
2573
|
+
*
|
2574
|
+
* var stooges = [
|
2575
|
+
* { 'name': 'moe', 'age': 40 },
|
2576
|
+
* { 'name': 'larry', 'age': 50 }
|
2577
|
+
* ];
|
2578
|
+
*
|
2579
|
+
* _.min(stooges, function(stooge) { return stooge.age; });
|
2580
|
+
* // => { 'name': 'moe', 'age': 40 };
|
2581
|
+
*
|
2582
|
+
* // using "_.pluck" callback shorthand
|
2583
|
+
* _.min(stooges, 'age');
|
2584
|
+
* // => { 'name': 'moe', 'age': 40 };
|
2342
2585
|
*/
|
2343
2586
|
function min(collection, callback, thisArg) {
|
2344
2587
|
var computed = Infinity,
|
2345
|
-
index = -1,
|
2346
|
-
length = collection ? collection.length : 0,
|
2347
2588
|
result = computed;
|
2348
2589
|
|
2349
|
-
if (callback
|
2590
|
+
if (!callback && isArray(collection)) {
|
2591
|
+
var index = -1,
|
2592
|
+
length = collection.length;
|
2593
|
+
|
2594
|
+
while (++index < length) {
|
2595
|
+
var value = collection[index];
|
2596
|
+
if (value < result) {
|
2597
|
+
result = value;
|
2598
|
+
}
|
2599
|
+
}
|
2600
|
+
} else {
|
2350
2601
|
callback = !callback && isString(collection)
|
2351
2602
|
? charAtCallback
|
2352
2603
|
: createCallback(callback, thisArg);
|
@@ -2358,22 +2609,16 @@
|
|
2358
2609
|
result = value;
|
2359
2610
|
}
|
2360
2611
|
});
|
2361
|
-
} else {
|
2362
|
-
while (++index < length) {
|
2363
|
-
if (collection[index] < result) {
|
2364
|
-
result = collection[index];
|
2365
|
-
}
|
2366
|
-
}
|
2367
2612
|
}
|
2368
2613
|
return result;
|
2369
2614
|
}
|
2370
2615
|
|
2371
2616
|
/**
|
2372
|
-
* Retrieves the value of a specified property from all elements in
|
2373
|
-
* the `collection`.
|
2617
|
+
* Retrieves the value of a specified property from all elements in the `collection`.
|
2374
2618
|
*
|
2375
2619
|
* @static
|
2376
2620
|
* @memberOf _
|
2621
|
+
* @type Function
|
2377
2622
|
* @category Collections
|
2378
2623
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2379
2624
|
* @param {String} property The property to pluck.
|
@@ -2382,22 +2627,21 @@
|
|
2382
2627
|
*
|
2383
2628
|
* var stooges = [
|
2384
2629
|
* { 'name': 'moe', 'age': 40 },
|
2385
|
-
* { 'name': 'larry', 'age': 50 }
|
2386
|
-
* { 'name': 'curly', 'age': 60 }
|
2630
|
+
* { 'name': 'larry', 'age': 50 }
|
2387
2631
|
* ];
|
2388
2632
|
*
|
2389
2633
|
* _.pluck(stooges, 'name');
|
2390
|
-
* // => ['moe', 'larry'
|
2634
|
+
* // => ['moe', 'larry']
|
2391
2635
|
*/
|
2392
|
-
|
2393
|
-
return map(collection, property + '');
|
2394
|
-
}
|
2636
|
+
var pluck = map;
|
2395
2637
|
|
2396
2638
|
/**
|
2397
|
-
*
|
2398
|
-
*
|
2399
|
-
*
|
2400
|
-
*
|
2639
|
+
* Reduces a `collection` to a value that is the accumulated result of running
|
2640
|
+
* each element in the `collection` through the `callback`, where each successive
|
2641
|
+
* `callback` execution consumes the return value of the previous execution.
|
2642
|
+
* If `accumulator` is not passed, the first element of the `collection` will be
|
2643
|
+
* used as the initial `accumulator` value. The `callback` is bound to `thisArg`
|
2644
|
+
* and invoked with four arguments; (accumulator, value, index|key, collection).
|
2401
2645
|
*
|
2402
2646
|
* @static
|
2403
2647
|
* @memberOf _
|
@@ -2410,12 +2654,20 @@
|
|
2410
2654
|
* @returns {Mixed} Returns the accumulated value.
|
2411
2655
|
* @example
|
2412
2656
|
*
|
2413
|
-
* var sum = _.reduce([1, 2, 3], function(
|
2657
|
+
* var sum = _.reduce([1, 2, 3], function(sum, num) {
|
2658
|
+
* return sum + num;
|
2659
|
+
* });
|
2414
2660
|
* // => 6
|
2661
|
+
*
|
2662
|
+
* var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
|
2663
|
+
* result[key] = num * 3;
|
2664
|
+
* return result;
|
2665
|
+
* }, {});
|
2666
|
+
* // => { 'a': 3, 'b': 6, 'c': 9 }
|
2415
2667
|
*/
|
2416
2668
|
function reduce(collection, callback, accumulator, thisArg) {
|
2417
2669
|
var noaccum = arguments.length < 3;
|
2418
|
-
callback = createCallback(callback, thisArg,
|
2670
|
+
callback = createCallback(callback, thisArg, 4);
|
2419
2671
|
|
2420
2672
|
if (isArray(collection)) {
|
2421
2673
|
var index = -1,
|
@@ -2438,7 +2690,8 @@
|
|
2438
2690
|
}
|
2439
2691
|
|
2440
2692
|
/**
|
2441
|
-
*
|
2693
|
+
* This method is similar to `_.reduce`, except that it iterates over a
|
2694
|
+
* `collection` from right to left.
|
2442
2695
|
*
|
2443
2696
|
* @static
|
2444
2697
|
* @memberOf _
|
@@ -2456,35 +2709,42 @@
|
|
2456
2709
|
* // => [4, 5, 2, 3, 0, 1]
|
2457
2710
|
*/
|
2458
2711
|
function reduceRight(collection, callback, accumulator, thisArg) {
|
2459
|
-
var
|
2712
|
+
var iterable = collection,
|
2460
2713
|
length = collection ? collection.length : 0,
|
2461
2714
|
noaccum = arguments.length < 3;
|
2462
2715
|
|
2463
2716
|
if (typeof length != 'number') {
|
2464
2717
|
var props = keys(collection);
|
2465
2718
|
length = props.length;
|
2466
|
-
} else if (noCharByIndex && isString(collection)) {
|
2467
|
-
iteratee = collection.split('');
|
2468
2719
|
}
|
2469
|
-
callback = createCallback(callback, thisArg,
|
2720
|
+
callback = createCallback(callback, thisArg, 4);
|
2470
2721
|
forEach(collection, function(value, index, collection) {
|
2471
2722
|
index = props ? props[--length] : --length;
|
2472
2723
|
accumulator = noaccum
|
2473
|
-
? (noaccum = false,
|
2474
|
-
: callback(accumulator,
|
2724
|
+
? (noaccum = false, iterable[index])
|
2725
|
+
: callback(accumulator, iterable[index], index, collection);
|
2475
2726
|
});
|
2476
2727
|
return accumulator;
|
2477
2728
|
}
|
2478
2729
|
|
2479
2730
|
/**
|
2480
|
-
* The opposite of `_.filter`, this method returns the
|
2731
|
+
* The opposite of `_.filter`, this method returns the elements of a
|
2481
2732
|
* `collection` that `callback` does **not** return truthy for.
|
2482
2733
|
*
|
2734
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2735
|
+
* callback will return the property value of the given element.
|
2736
|
+
*
|
2737
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2738
|
+
* will return `true` for elements that have the propeties of the given object,
|
2739
|
+
* else `false`.
|
2740
|
+
*
|
2483
2741
|
* @static
|
2484
2742
|
* @memberOf _
|
2485
2743
|
* @category Collections
|
2486
2744
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2487
|
-
* @param {Function} [callback=identity] The function called per
|
2745
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2746
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2747
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2488
2748
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2489
2749
|
* @returns {Array} Returns a new array of elements that did **not** pass the
|
2490
2750
|
* callback check.
|
@@ -2492,6 +2752,19 @@
|
|
2492
2752
|
*
|
2493
2753
|
* var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
|
2494
2754
|
* // => [1, 3, 5]
|
2755
|
+
*
|
2756
|
+
* var food = [
|
2757
|
+
* { 'name': 'apple', 'organic': false, 'type': 'fruit' },
|
2758
|
+
* { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
|
2759
|
+
* ];
|
2760
|
+
*
|
2761
|
+
* // using "_.pluck" callback shorthand
|
2762
|
+
* _.reject(food, 'organic');
|
2763
|
+
* // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
|
2764
|
+
*
|
2765
|
+
* // using "_.where" callback shorthand
|
2766
|
+
* _.reject(food, { 'type': 'fruit' });
|
2767
|
+
* // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
|
2495
2768
|
*/
|
2496
2769
|
function reject(collection, callback, thisArg) {
|
2497
2770
|
callback = createCallback(callback, thisArg);
|
@@ -2516,7 +2789,8 @@
|
|
2516
2789
|
*/
|
2517
2790
|
function shuffle(collection) {
|
2518
2791
|
var index = -1,
|
2519
|
-
|
2792
|
+
length = collection ? collection.length : 0,
|
2793
|
+
result = Array(typeof length == 'number' ? length : 0);
|
2520
2794
|
|
2521
2795
|
forEach(collection, function(value) {
|
2522
2796
|
var rand = floor(nativeRandom() * (++index + 1));
|
@@ -2557,12 +2831,21 @@
|
|
2557
2831
|
* does not iterate over the entire `collection`. The `callback` is bound to
|
2558
2832
|
* `thisArg` and invoked with three arguments; (value, index|key, collection).
|
2559
2833
|
*
|
2834
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2835
|
+
* callback will return the property value of the given element.
|
2836
|
+
*
|
2837
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2838
|
+
* will return `true` for elements that have the propeties of the given object,
|
2839
|
+
* else `false`.
|
2840
|
+
*
|
2560
2841
|
* @static
|
2561
2842
|
* @memberOf _
|
2562
2843
|
* @alias any
|
2563
2844
|
* @category Collections
|
2564
2845
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2565
|
-
* @param {Function} [callback=identity] The function called per
|
2846
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2847
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2848
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2566
2849
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2567
2850
|
* @returns {Boolean} Returns `true` if any element passes the callback check,
|
2568
2851
|
* else `false`.
|
@@ -2570,6 +2853,19 @@
|
|
2570
2853
|
*
|
2571
2854
|
* _.some([null, 0, 'yes', false], Boolean);
|
2572
2855
|
* // => true
|
2856
|
+
*
|
2857
|
+
* var food = [
|
2858
|
+
* { 'name': 'apple', 'organic': false, 'type': 'fruit' },
|
2859
|
+
* { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
|
2860
|
+
* ];
|
2861
|
+
*
|
2862
|
+
* // using "_.pluck" callback shorthand
|
2863
|
+
* _.some(food, 'organic');
|
2864
|
+
* // => true
|
2865
|
+
*
|
2866
|
+
* // using "_.where" callback shorthand
|
2867
|
+
* _.some(food, { 'type': 'meat' });
|
2868
|
+
* // => false
|
2573
2869
|
*/
|
2574
2870
|
function some(collection, callback, thisArg) {
|
2575
2871
|
var result;
|
@@ -2593,17 +2889,26 @@
|
|
2593
2889
|
}
|
2594
2890
|
|
2595
2891
|
/**
|
2596
|
-
* Creates an array,
|
2597
|
-
* running each element
|
2598
|
-
*
|
2599
|
-
* The `callback`
|
2892
|
+
* Creates an array of elements, sorted in ascending order by the results of
|
2893
|
+
* running each element in the `collection` through the `callback`. This method
|
2894
|
+
* performs a stable sort, that is, it will preserve the original sort order of
|
2895
|
+
* equal elements. The `callback` is bound to `thisArg` and invoked with three
|
2896
|
+
* arguments; (value, index|key, collection).
|
2897
|
+
*
|
2898
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
2899
|
+
* callback will return the property value of the given element.
|
2900
|
+
*
|
2901
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
2902
|
+
* will return `true` for elements that have the propeties of the given object,
|
2903
|
+
* else `false`.
|
2600
2904
|
*
|
2601
2905
|
* @static
|
2602
2906
|
* @memberOf _
|
2603
2907
|
* @category Collections
|
2604
2908
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2605
|
-
* @param {Function|String} callback
|
2606
|
-
*
|
2909
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
2910
|
+
* iteration. If a property name or object is passed, it will be used to create
|
2911
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
2607
2912
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
2608
2913
|
* @returns {Array} Returns a new array of sorted elements.
|
2609
2914
|
* @example
|
@@ -2614,22 +2919,25 @@
|
|
2614
2919
|
* _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
|
2615
2920
|
* // => [3, 1, 2]
|
2616
2921
|
*
|
2617
|
-
* _.
|
2618
|
-
*
|
2922
|
+
* // using "_.pluck" callback shorthand
|
2923
|
+
* _.sortBy(['banana', 'strawberry', 'apple'], 'length');
|
2924
|
+
* // => ['apple', 'banana', 'strawberry']
|
2619
2925
|
*/
|
2620
2926
|
function sortBy(collection, callback, thisArg) {
|
2621
|
-
var
|
2622
|
-
|
2927
|
+
var index = -1,
|
2928
|
+
length = collection ? collection.length : 0,
|
2929
|
+
result = Array(typeof length == 'number' ? length : 0);
|
2623
2930
|
|
2624
|
-
|
2625
|
-
|
2626
|
-
|
2931
|
+
callback = createCallback(callback, thisArg);
|
2932
|
+
forEach(collection, function(value, key, collection) {
|
2933
|
+
result[++index] = {
|
2934
|
+
'criteria': callback(value, key, collection),
|
2627
2935
|
'index': index,
|
2628
2936
|
'value': value
|
2629
|
-
}
|
2937
|
+
};
|
2630
2938
|
});
|
2631
2939
|
|
2632
|
-
|
2940
|
+
length = result.length;
|
2633
2941
|
result.sort(compareAscending);
|
2634
2942
|
while (length--) {
|
2635
2943
|
result[length] = result[length].value;
|
@@ -2651,49 +2959,36 @@
|
|
2651
2959
|
* // => [2, 3, 4]
|
2652
2960
|
*/
|
2653
2961
|
function toArray(collection) {
|
2654
|
-
|
2655
|
-
|
2656
|
-
return noCharByIndex && isString(collection)
|
2657
|
-
? collection.split('')
|
2658
|
-
: slice(collection);
|
2962
|
+
if (collection && typeof collection.length == 'number') {
|
2963
|
+
return slice(collection);
|
2659
2964
|
}
|
2660
2965
|
return values(collection);
|
2661
2966
|
}
|
2662
2967
|
|
2663
2968
|
/**
|
2664
2969
|
* Examines each element in a `collection`, returning an array of all elements
|
2665
|
-
* that
|
2970
|
+
* that have the given `properties`. When checking `properties`, this method
|
2971
|
+
* performs a deep comparison between values to determine if they are equivalent
|
2972
|
+
* to each other.
|
2666
2973
|
*
|
2667
2974
|
* @static
|
2668
2975
|
* @memberOf _
|
2976
|
+
* @type Function
|
2669
2977
|
* @category Collections
|
2670
2978
|
* @param {Array|Object|String} collection The collection to iterate over.
|
2671
2979
|
* @param {Object} properties The object of property values to filter by.
|
2672
|
-
* @returns {Array} Returns a new array of elements that
|
2980
|
+
* @returns {Array} Returns a new array of elements that have the given `properties`.
|
2673
2981
|
* @example
|
2674
2982
|
*
|
2675
2983
|
* var stooges = [
|
2676
2984
|
* { 'name': 'moe', 'age': 40 },
|
2677
|
-
* { 'name': 'larry', 'age': 50 }
|
2678
|
-
* { 'name': 'curly', 'age': 60 }
|
2985
|
+
* { 'name': 'larry', 'age': 50 }
|
2679
2986
|
* ];
|
2680
2987
|
*
|
2681
2988
|
* _.where(stooges, { 'age': 40 });
|
2682
2989
|
* // => [{ 'name': 'moe', 'age': 40 }]
|
2683
2990
|
*/
|
2684
|
-
|
2685
|
-
var props = keys(properties);
|
2686
|
-
return filter(collection, function(object) {
|
2687
|
-
var length = props.length;
|
2688
|
-
while (length--) {
|
2689
|
-
var result = object[props[length]] === properties[props[length]];
|
2690
|
-
if (!result) {
|
2691
|
-
break;
|
2692
|
-
}
|
2693
|
-
}
|
2694
|
-
return !!result;
|
2695
|
-
});
|
2696
|
-
}
|
2991
|
+
var where = filter;
|
2697
2992
|
|
2698
2993
|
/*--------------------------------------------------------------------------*/
|
2699
2994
|
|
@@ -2758,30 +3053,79 @@
|
|
2758
3053
|
}
|
2759
3054
|
|
2760
3055
|
/**
|
2761
|
-
* Gets the first element of the `array`.
|
2762
|
-
* elements of the `array
|
3056
|
+
* Gets the first element of the `array`. If a number `n` is passed, the first
|
3057
|
+
* `n` elements of the `array` are returned. If a `callback` function is passed,
|
3058
|
+
* the first elements the `callback` returns truthy for are returned. The `callback`
|
3059
|
+
* is bound to `thisArg` and invoked with three arguments; (value, index, array).
|
3060
|
+
*
|
3061
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
3062
|
+
* callback will return the property value of the given element.
|
3063
|
+
*
|
3064
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
3065
|
+
* will return `true` for elements that have the propeties of the given object,
|
3066
|
+
* else `false`.
|
2763
3067
|
*
|
2764
3068
|
* @static
|
2765
3069
|
* @memberOf _
|
2766
3070
|
* @alias head, take
|
2767
3071
|
* @category Arrays
|
2768
3072
|
* @param {Array} array The array to query.
|
2769
|
-
* @param {Number} [n] The
|
2770
|
-
*
|
2771
|
-
*
|
2772
|
-
*
|
2773
|
-
*
|
3073
|
+
* @param {Function|Object|Number|String} [callback|n] The function called
|
3074
|
+
* per element or the number of elements to return. If a property name or
|
3075
|
+
* object is passed, it will be used to create a "_.pluck" or "_.where"
|
3076
|
+
* style callback, respectively.
|
3077
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3078
|
+
* @returns {Mixed} Returns the first element(s) of `array`.
|
2774
3079
|
* @example
|
2775
3080
|
*
|
2776
|
-
* _.first([
|
2777
|
-
* // =>
|
3081
|
+
* _.first([1, 2, 3]);
|
3082
|
+
* // => 1
|
3083
|
+
*
|
3084
|
+
* _.first([1, 2, 3], 2);
|
3085
|
+
* // => [1, 2]
|
3086
|
+
*
|
3087
|
+
* _.first([1, 2, 3], function(num) {
|
3088
|
+
* return num < 3;
|
3089
|
+
* });
|
3090
|
+
* // => [1, 2]
|
3091
|
+
*
|
3092
|
+
* var food = [
|
3093
|
+
* { 'name': 'banana', 'organic': true },
|
3094
|
+
* { 'name': 'beet', 'organic': false },
|
3095
|
+
* ];
|
3096
|
+
*
|
3097
|
+
* // using "_.pluck" callback shorthand
|
3098
|
+
* _.first(food, 'organic');
|
3099
|
+
* // => [{ 'name': 'banana', 'organic': true }]
|
3100
|
+
*
|
3101
|
+
* var food = [
|
3102
|
+
* { 'name': 'apple', 'type': 'fruit' },
|
3103
|
+
* { 'name': 'banana', 'type': 'fruit' },
|
3104
|
+
* { 'name': 'beet', 'type': 'vegetable' }
|
3105
|
+
* ];
|
3106
|
+
*
|
3107
|
+
* // using "_.where" callback shorthand
|
3108
|
+
* _.first(food, { 'type': 'fruit' });
|
3109
|
+
* // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
|
2778
3110
|
*/
|
2779
|
-
function first(array,
|
3111
|
+
function first(array, callback, thisArg) {
|
2780
3112
|
if (array) {
|
2781
|
-
var
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
3113
|
+
var n = 0,
|
3114
|
+
length = array.length;
|
3115
|
+
|
3116
|
+
if (typeof callback != 'number' && callback != null) {
|
3117
|
+
var index = -1;
|
3118
|
+
callback = createCallback(callback, thisArg);
|
3119
|
+
while (++index < length && callback(array[index], index, array)) {
|
3120
|
+
n++;
|
3121
|
+
}
|
3122
|
+
} else {
|
3123
|
+
n = callback;
|
3124
|
+
if (n == null || thisArg) {
|
3125
|
+
return array[0];
|
3126
|
+
}
|
3127
|
+
}
|
3128
|
+
return slice(array, 0, nativeMin(nativeMax(0, n), length));
|
2785
3129
|
}
|
2786
3130
|
}
|
2787
3131
|
|
@@ -2864,28 +3208,77 @@
|
|
2864
3208
|
}
|
2865
3209
|
|
2866
3210
|
/**
|
2867
|
-
* Gets all but the last element of `array`.
|
2868
|
-
* elements from the result.
|
3211
|
+
* Gets all but the last element of `array`. If a number `n` is passed, the
|
3212
|
+
* last `n` elements are excluded from the result. If a `callback` function
|
3213
|
+
* is passed, the last elements the `callback` returns truthy for are excluded
|
3214
|
+
* from the result. The `callback` is bound to `thisArg` and invoked with three
|
3215
|
+
* arguments; (value, index, array).
|
3216
|
+
*
|
3217
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
3218
|
+
* callback will return the property value of the given element.
|
3219
|
+
*
|
3220
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
3221
|
+
* will return `true` for elements that have the propeties of the given object,
|
3222
|
+
* else `false`.
|
2869
3223
|
*
|
2870
3224
|
* @static
|
2871
3225
|
* @memberOf _
|
2872
3226
|
* @category Arrays
|
2873
3227
|
* @param {Array} array The array to query.
|
2874
|
-
* @param {Number} [n=1] The
|
2875
|
-
*
|
2876
|
-
*
|
2877
|
-
*
|
3228
|
+
* @param {Function|Object|Number|String} [callback|n=1] The function called
|
3229
|
+
* per element or the number of elements to exclude. If a property name or
|
3230
|
+
* object is passed, it will be used to create a "_.pluck" or "_.where"
|
3231
|
+
* style callback, respectively.
|
3232
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3233
|
+
* @returns {Array} Returns a slice of `array`.
|
2878
3234
|
* @example
|
2879
3235
|
*
|
2880
|
-
* _.initial([
|
2881
|
-
* // => [
|
3236
|
+
* _.initial([1, 2, 3]);
|
3237
|
+
* // => [1, 2]
|
3238
|
+
*
|
3239
|
+
* _.initial([1, 2, 3], 2);
|
3240
|
+
* // => [1]
|
3241
|
+
*
|
3242
|
+
* _.initial([1, 2, 3], function(num) {
|
3243
|
+
* return num > 1;
|
3244
|
+
* });
|
3245
|
+
* // => [1]
|
3246
|
+
*
|
3247
|
+
* var food = [
|
3248
|
+
* { 'name': 'beet', 'organic': false },
|
3249
|
+
* { 'name': 'carrot', 'organic': true }
|
3250
|
+
* ];
|
3251
|
+
*
|
3252
|
+
* // using "_.pluck" callback shorthand
|
3253
|
+
* _.initial(food, 'organic');
|
3254
|
+
* // => [{ 'name': 'beet', 'organic': false }]
|
3255
|
+
*
|
3256
|
+
* var food = [
|
3257
|
+
* { 'name': 'banana', 'type': 'fruit' },
|
3258
|
+
* { 'name': 'beet', 'type': 'vegetable' },
|
3259
|
+
* { 'name': 'carrot', 'type': 'vegetable' }
|
3260
|
+
* ];
|
3261
|
+
*
|
3262
|
+
* // using "_.where" callback shorthand
|
3263
|
+
* _.initial(food, { 'type': 'vegetable' });
|
3264
|
+
* // => [{ 'name': 'banana', 'type': 'fruit' }]
|
2882
3265
|
*/
|
2883
|
-
function initial(array,
|
3266
|
+
function initial(array, callback, thisArg) {
|
2884
3267
|
if (!array) {
|
2885
3268
|
return [];
|
2886
3269
|
}
|
2887
|
-
var
|
2888
|
-
|
3270
|
+
var n = 0,
|
3271
|
+
length = array.length;
|
3272
|
+
|
3273
|
+
if (typeof callback != 'number' && callback != null) {
|
3274
|
+
var index = length;
|
3275
|
+
callback = createCallback(callback, thisArg);
|
3276
|
+
while (index-- && callback(array[index], index, array)) {
|
3277
|
+
n++;
|
3278
|
+
}
|
3279
|
+
} else {
|
3280
|
+
n = (callback == null || thisArg) ? 1 : callback || n;
|
3281
|
+
}
|
2889
3282
|
return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
|
2890
3283
|
}
|
2891
3284
|
|
@@ -2940,27 +3333,79 @@
|
|
2940
3333
|
}
|
2941
3334
|
|
2942
3335
|
/**
|
2943
|
-
* Gets the last element of the `array`.
|
2944
|
-
* elements of the `array
|
3336
|
+
* Gets the last element of the `array`. If a number `n` is passed, the last
|
3337
|
+
* `n` elements of the `array` are returned. If a `callback` function is passed,
|
3338
|
+
* the last elements the `callback` returns truthy for are returned. The `callback`
|
3339
|
+
* is bound to `thisArg` and invoked with three arguments; (value, index, array).
|
3340
|
+
*
|
3341
|
+
*
|
3342
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
3343
|
+
* callback will return the property value of the given element.
|
3344
|
+
*
|
3345
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
3346
|
+
* will return `true` for elements that have the propeties of the given object,
|
3347
|
+
* else `false`.
|
2945
3348
|
*
|
2946
3349
|
* @static
|
2947
3350
|
* @memberOf _
|
2948
3351
|
* @category Arrays
|
2949
3352
|
* @param {Array} array The array to query.
|
2950
|
-
* @param {Number} [n] The
|
2951
|
-
*
|
2952
|
-
*
|
2953
|
-
*
|
2954
|
-
*
|
3353
|
+
* @param {Function|Object|Number|String} [callback|n] The function called
|
3354
|
+
* per element or the number of elements to return. If a property name or
|
3355
|
+
* object is passed, it will be used to create a "_.pluck" or "_.where"
|
3356
|
+
* style callback, respectively.
|
3357
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3358
|
+
* @returns {Mixed} Returns the last element(s) of `array`.
|
2955
3359
|
* @example
|
2956
3360
|
*
|
2957
|
-
* _.last([
|
2958
|
-
* // =>
|
3361
|
+
* _.last([1, 2, 3]);
|
3362
|
+
* // => 3
|
3363
|
+
*
|
3364
|
+
* _.last([1, 2, 3], 2);
|
3365
|
+
* // => [2, 3]
|
3366
|
+
*
|
3367
|
+
* _.last([1, 2, 3], function(num) {
|
3368
|
+
* return num > 1;
|
3369
|
+
* });
|
3370
|
+
* // => [2, 3]
|
3371
|
+
*
|
3372
|
+
* var food = [
|
3373
|
+
* { 'name': 'beet', 'organic': false },
|
3374
|
+
* { 'name': 'carrot', 'organic': true }
|
3375
|
+
* ];
|
3376
|
+
*
|
3377
|
+
* // using "_.pluck" callback shorthand
|
3378
|
+
* _.last(food, 'organic');
|
3379
|
+
* // => [{ 'name': 'carrot', 'organic': true }]
|
3380
|
+
*
|
3381
|
+
* var food = [
|
3382
|
+
* { 'name': 'banana', 'type': 'fruit' },
|
3383
|
+
* { 'name': 'beet', 'type': 'vegetable' },
|
3384
|
+
* { 'name': 'carrot', 'type': 'vegetable' }
|
3385
|
+
* ];
|
3386
|
+
*
|
3387
|
+
* // using "_.where" callback shorthand
|
3388
|
+
* _.last(food, { 'type': 'vegetable' });
|
3389
|
+
* // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
|
2959
3390
|
*/
|
2960
|
-
function last(array,
|
3391
|
+
function last(array, callback, thisArg) {
|
2961
3392
|
if (array) {
|
2962
|
-
var
|
2963
|
-
|
3393
|
+
var n = 0,
|
3394
|
+
length = array.length;
|
3395
|
+
|
3396
|
+
if (typeof callback != 'number' && callback != null) {
|
3397
|
+
var index = length;
|
3398
|
+
callback = createCallback(callback, thisArg);
|
3399
|
+
while (index-- && callback(array[index], index, array)) {
|
3400
|
+
n++;
|
3401
|
+
}
|
3402
|
+
} else {
|
3403
|
+
n = callback;
|
3404
|
+
if (n == null || thisArg) {
|
3405
|
+
return array[length - 1];
|
3406
|
+
}
|
3407
|
+
}
|
3408
|
+
return slice(array, nativeMax(0, length - n));
|
2964
3409
|
}
|
2965
3410
|
}
|
2966
3411
|
|
@@ -3011,8 +3456,8 @@
|
|
3011
3456
|
* corresponding values.
|
3012
3457
|
* @example
|
3013
3458
|
*
|
3014
|
-
* _.object(['moe', 'larry'
|
3015
|
-
* // => { 'moe': 30, 'larry': 40
|
3459
|
+
* _.object(['moe', 'larry'], [30, 40]);
|
3460
|
+
* // => { 'moe': 30, 'larry': 40 }
|
3016
3461
|
*/
|
3017
3462
|
function object(keys, values) {
|
3018
3463
|
var index = -1,
|
@@ -3032,8 +3477,7 @@
|
|
3032
3477
|
|
3033
3478
|
/**
|
3034
3479
|
* Creates an array of numbers (positive and/or negative) progressing from
|
3035
|
-
* `start` up to but not including `
|
3036
|
-
* `range()` function. See http://docs.python.org/library/functions.html#range.
|
3480
|
+
* `start` up to but not including `end`.
|
3037
3481
|
*
|
3038
3482
|
* @static
|
3039
3483
|
* @memberOf _
|
@@ -3081,25 +3525,76 @@
|
|
3081
3525
|
}
|
3082
3526
|
|
3083
3527
|
/**
|
3084
|
-
* The opposite of `_.initial`, this method gets all but the first value of
|
3085
|
-
*
|
3528
|
+
* The opposite of `_.initial`, this method gets all but the first value of `array`.
|
3529
|
+
* If a number `n` is passed, the first `n` values are excluded from the result.
|
3530
|
+
* If a `callback` function is passed, the first elements the `callback` returns
|
3531
|
+
* truthy for are excluded from the result. The `callback` is bound to `thisArg`
|
3532
|
+
* and invoked with three arguments; (value, index, array).
|
3533
|
+
*
|
3534
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
3535
|
+
* callback will return the property value of the given element.
|
3536
|
+
*
|
3537
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
3538
|
+
* will return `true` for elements that have the propeties of the given object,
|
3539
|
+
* else `false`.
|
3086
3540
|
*
|
3087
3541
|
* @static
|
3088
3542
|
* @memberOf _
|
3089
3543
|
* @alias drop, tail
|
3090
3544
|
* @category Arrays
|
3091
3545
|
* @param {Array} array The array to query.
|
3092
|
-
* @param {Number} [n=1] The
|
3093
|
-
*
|
3094
|
-
*
|
3095
|
-
*
|
3546
|
+
* @param {Function|Object|Number|String} [callback|n=1] The function called
|
3547
|
+
* per element or the number of elements to exclude. If a property name or
|
3548
|
+
* object is passed, it will be used to create a "_.pluck" or "_.where"
|
3549
|
+
* style callback, respectively.
|
3550
|
+
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3551
|
+
* @returns {Array} Returns a slice of `array`.
|
3096
3552
|
* @example
|
3097
3553
|
*
|
3098
|
-
* _.rest([
|
3099
|
-
* // => [2,
|
3554
|
+
* _.rest([1, 2, 3]);
|
3555
|
+
* // => [2, 3]
|
3556
|
+
*
|
3557
|
+
* _.rest([1, 2, 3], 2);
|
3558
|
+
* // => [3]
|
3559
|
+
*
|
3560
|
+
* _.rest([1, 2, 3], function(num) {
|
3561
|
+
* return num < 3;
|
3562
|
+
* });
|
3563
|
+
* // => [3]
|
3564
|
+
*
|
3565
|
+
* var food = [
|
3566
|
+
* { 'name': 'banana', 'organic': true },
|
3567
|
+
* { 'name': 'beet', 'organic': false },
|
3568
|
+
* ];
|
3569
|
+
*
|
3570
|
+
* // using "_.pluck" callback shorthand
|
3571
|
+
* _.rest(food, 'organic');
|
3572
|
+
* // => [{ 'name': 'beet', 'organic': false }]
|
3573
|
+
*
|
3574
|
+
* var food = [
|
3575
|
+
* { 'name': 'apple', 'type': 'fruit' },
|
3576
|
+
* { 'name': 'banana', 'type': 'fruit' },
|
3577
|
+
* { 'name': 'beet', 'type': 'vegetable' }
|
3578
|
+
* ];
|
3579
|
+
*
|
3580
|
+
* // using "_.where" callback shorthand
|
3581
|
+
* _.rest(food, { 'type': 'fruit' });
|
3582
|
+
* // => [{ 'name': 'beet', 'type': 'vegetable' }]
|
3100
3583
|
*/
|
3101
|
-
function rest(array,
|
3102
|
-
|
3584
|
+
function rest(array, callback, thisArg) {
|
3585
|
+
if (typeof callback != 'number' && callback != null) {
|
3586
|
+
var n = 0,
|
3587
|
+
index = -1,
|
3588
|
+
length = array ? array.length : 0;
|
3589
|
+
|
3590
|
+
callback = createCallback(callback, thisArg);
|
3591
|
+
while (++index < length && callback(array[index], index, array)) {
|
3592
|
+
n++;
|
3593
|
+
}
|
3594
|
+
} else {
|
3595
|
+
n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
|
3596
|
+
}
|
3597
|
+
return slice(array, n);
|
3103
3598
|
}
|
3104
3599
|
|
3105
3600
|
/**
|
@@ -3107,16 +3602,23 @@
|
|
3107
3602
|
* should be inserted into `array` in order to maintain the sort order of the
|
3108
3603
|
* sorted `array`. If `callback` is passed, it will be executed for `value` and
|
3109
3604
|
* each element in `array` to compute their sort ranking. The `callback` is
|
3110
|
-
* bound to `thisArg` and invoked with one argument; (value).
|
3111
|
-
*
|
3605
|
+
* bound to `thisArg` and invoked with one argument; (value).
|
3606
|
+
*
|
3607
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
3608
|
+
* callback will return the property value of the given element.
|
3609
|
+
*
|
3610
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
3611
|
+
* will return `true` for elements that have the propeties of the given object,
|
3612
|
+
* else `false`.
|
3112
3613
|
*
|
3113
3614
|
* @static
|
3114
3615
|
* @memberOf _
|
3115
3616
|
* @category Arrays
|
3116
3617
|
* @param {Array} array The array to iterate over.
|
3117
3618
|
* @param {Mixed} value The value to evaluate.
|
3118
|
-
* @param {Function|String} [callback=identity
|
3119
|
-
*
|
3619
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
3620
|
+
* iteration. If a property name or object is passed, it will be used to create
|
3621
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
3120
3622
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3121
3623
|
* @returns {Number} Returns the index at which the value should be inserted
|
3122
3624
|
* into `array`.
|
@@ -3125,6 +3627,7 @@
|
|
3125
3627
|
* _.sortedIndex([20, 30, 50], 40);
|
3126
3628
|
* // => 2
|
3127
3629
|
*
|
3630
|
+
* // using "_.pluck" callback shorthand
|
3128
3631
|
* _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
|
3129
3632
|
* // => 2
|
3130
3633
|
*
|
@@ -3147,7 +3650,7 @@
|
|
3147
3650
|
high = array ? array.length : low;
|
3148
3651
|
|
3149
3652
|
// explicitly reference `identity` for better inlining in Firefox
|
3150
|
-
callback = callback ? createCallback(callback, thisArg) : identity;
|
3653
|
+
callback = callback ? createCallback(callback, thisArg, 1) : identity;
|
3151
3654
|
value = callback(value);
|
3152
3655
|
|
3153
3656
|
while (low < high) {
|
@@ -3185,13 +3688,22 @@
|
|
3185
3688
|
* element of `array` is passed through a callback` before uniqueness is computed.
|
3186
3689
|
* The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
|
3187
3690
|
*
|
3691
|
+
* If a property name is passed for `callback`, the created "_.pluck" style
|
3692
|
+
* callback will return the property value of the given element.
|
3693
|
+
*
|
3694
|
+
* If an object is passed for `callback`, the created "_.where" style callback
|
3695
|
+
* will return `true` for elements that have the propeties of the given object,
|
3696
|
+
* else `false`.
|
3697
|
+
*
|
3188
3698
|
* @static
|
3189
3699
|
* @memberOf _
|
3190
3700
|
* @alias unique
|
3191
3701
|
* @category Arrays
|
3192
3702
|
* @param {Array} array The array to process.
|
3193
3703
|
* @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
|
3194
|
-
* @param {Function} [callback=identity] The function called per
|
3704
|
+
* @param {Function|Object|String} [callback=identity] The function called per
|
3705
|
+
* iteration. If a property name or object is passed, it will be used to create
|
3706
|
+
* a "_.pluck" or "_.where" style callback, respectively.
|
3195
3707
|
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
3196
3708
|
* @returns {Array} Returns a duplicate-value-free array.
|
3197
3709
|
* @example
|
@@ -3207,6 +3719,10 @@
|
|
3207
3719
|
*
|
3208
3720
|
* _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math);
|
3209
3721
|
* // => [1, 2, 3]
|
3722
|
+
*
|
3723
|
+
* // using "_.pluck" callback shorthand
|
3724
|
+
* _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
|
3725
|
+
* // => [{ 'x': 1 }, { 'x': 2 }]
|
3210
3726
|
*/
|
3211
3727
|
function uniq(array, isSorted, callback, thisArg) {
|
3212
3728
|
var index = -1,
|
@@ -3270,7 +3786,7 @@
|
|
3270
3786
|
function without(array) {
|
3271
3787
|
var index = -1,
|
3272
3788
|
length = array ? array.length : 0,
|
3273
|
-
contains = cachedContains(arguments, 1
|
3789
|
+
contains = cachedContains(arguments, 1),
|
3274
3790
|
result = [];
|
3275
3791
|
|
3276
3792
|
while (++index < length) {
|
@@ -3295,8 +3811,8 @@
|
|
3295
3811
|
* @returns {Array} Returns a new array of grouped elements.
|
3296
3812
|
* @example
|
3297
3813
|
*
|
3298
|
-
* _.zip(['moe', 'larry'
|
3299
|
-
* // => [['moe', 30, true], ['larry', 40, false]
|
3814
|
+
* _.zip(['moe', 'larry'], [30, 40], [true, false]);
|
3815
|
+
* // => [['moe', 30, true], ['larry', 40, false]]
|
3300
3816
|
*/
|
3301
3817
|
function zip(array) {
|
3302
3818
|
var index = -1,
|
@@ -3374,7 +3890,8 @@
|
|
3374
3890
|
|
3375
3891
|
/**
|
3376
3892
|
* Binds methods on `object` to `object`, overwriting the existing method.
|
3377
|
-
*
|
3893
|
+
* Method names may be specified as individual arguments or as arrays of method
|
3894
|
+
* names. If no method names are provided, all the function properties of `object`
|
3378
3895
|
* will be bound.
|
3379
3896
|
*
|
3380
3897
|
* @static
|
@@ -3385,17 +3902,17 @@
|
|
3385
3902
|
* @returns {Object} Returns `object`.
|
3386
3903
|
* @example
|
3387
3904
|
*
|
3388
|
-
* var
|
3389
|
-
* 'label': '
|
3390
|
-
* 'onClick': function() { alert('clicked
|
3905
|
+
* var view = {
|
3906
|
+
* 'label': 'docs',
|
3907
|
+
* 'onClick': function() { alert('clicked ' + this.label); }
|
3391
3908
|
* };
|
3392
3909
|
*
|
3393
|
-
* _.bindAll(
|
3394
|
-
* jQuery('#
|
3395
|
-
* // =>
|
3910
|
+
* _.bindAll(view);
|
3911
|
+
* jQuery('#docs').on('click', view.onClick);
|
3912
|
+
* // => alerts 'clicked docs', when the button is clicked
|
3396
3913
|
*/
|
3397
3914
|
function bindAll(object) {
|
3398
|
-
var funcs = arguments,
|
3915
|
+
var funcs = concat.apply(arrayRef, arguments),
|
3399
3916
|
index = funcs.length > 1 ? 0 : (funcs = functions(object), -1),
|
3400
3917
|
length = funcs.length;
|
3401
3918
|
|
@@ -3447,7 +3964,7 @@
|
|
3447
3964
|
/**
|
3448
3965
|
* Creates a function that is the composition of the passed functions,
|
3449
3966
|
* where each function consumes the return value of the function that follows.
|
3450
|
-
*
|
3967
|
+
* For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
|
3451
3968
|
* Each function is executed with the `this` binding of the composed function.
|
3452
3969
|
*
|
3453
3970
|
* @static
|
@@ -3457,11 +3974,11 @@
|
|
3457
3974
|
* @returns {Function} Returns the new composed function.
|
3458
3975
|
* @example
|
3459
3976
|
*
|
3460
|
-
* var greet = function(name) { return 'hi
|
3977
|
+
* var greet = function(name) { return 'hi ' + name; };
|
3461
3978
|
* var exclaim = function(statement) { return statement + '!'; };
|
3462
3979
|
* var welcome = _.compose(exclaim, greet);
|
3463
3980
|
* welcome('moe');
|
3464
|
-
* // => 'hi
|
3981
|
+
* // => 'hi moe!'
|
3465
3982
|
*/
|
3466
3983
|
function compose() {
|
3467
3984
|
var funcs = arguments;
|
@@ -3564,6 +4081,10 @@
|
|
3564
4081
|
var args = slice(arguments, 1);
|
3565
4082
|
return setTimeout(function() { func.apply(undefined, args); }, 1);
|
3566
4083
|
}
|
4084
|
+
// use `setImmediate` if it's available in Node.js
|
4085
|
+
if (isV8 && freeModule && typeof setImmediate == 'function') {
|
4086
|
+
defer = bind(setImmediate, window);
|
4087
|
+
}
|
3567
4088
|
|
3568
4089
|
/**
|
3569
4090
|
* Creates a function that memoizes the result of `func`. If `resolver` is
|
@@ -3587,7 +4108,7 @@
|
|
3587
4108
|
function memoize(func, resolver) {
|
3588
4109
|
var cache = {};
|
3589
4110
|
return function() {
|
3590
|
-
var key = resolver ? resolver.apply(this, arguments) : arguments[0];
|
4111
|
+
var key = (resolver ? resolver.apply(this, arguments) : arguments[0]) + '';
|
3591
4112
|
return hasOwnProperty.call(cache, key)
|
3592
4113
|
? cache[key]
|
3593
4114
|
: (cache[key] = func.apply(this, arguments));
|
@@ -3609,11 +4130,11 @@
|
|
3609
4130
|
* var initialize = _.once(createApplication);
|
3610
4131
|
* initialize();
|
3611
4132
|
* initialize();
|
3612
|
-
* //
|
4133
|
+
* // `initialize` executes `createApplication` once
|
3613
4134
|
*/
|
3614
4135
|
function once(func) {
|
3615
|
-
var
|
3616
|
-
|
4136
|
+
var ran,
|
4137
|
+
result;
|
3617
4138
|
|
3618
4139
|
return function() {
|
3619
4140
|
if (ran) {
|
@@ -3631,7 +4152,7 @@
|
|
3631
4152
|
/**
|
3632
4153
|
* Creates a function that, when called, invokes `func` with any additional
|
3633
4154
|
* `partial` arguments prepended to those passed to the new function. This
|
3634
|
-
* method is similar to `bind`, except it does **not** alter the `this` binding.
|
4155
|
+
* method is similar to `_.bind`, except it does **not** alter the `this` binding.
|
3635
4156
|
*
|
3636
4157
|
* @static
|
3637
4158
|
* @memberOf _
|
@@ -3641,15 +4162,46 @@
|
|
3641
4162
|
* @returns {Function} Returns the new partially applied function.
|
3642
4163
|
* @example
|
3643
4164
|
*
|
3644
|
-
* var greet = function(greeting, name) { return greeting + '
|
4165
|
+
* var greet = function(greeting, name) { return greeting + ' ' + name; };
|
3645
4166
|
* var hi = _.partial(greet, 'hi');
|
3646
4167
|
* hi('moe');
|
3647
|
-
* // => 'hi
|
4168
|
+
* // => 'hi moe'
|
3648
4169
|
*/
|
3649
4170
|
function partial(func) {
|
3650
4171
|
return createBound(func, slice(arguments, 1));
|
3651
4172
|
}
|
3652
4173
|
|
4174
|
+
/**
|
4175
|
+
* This method is similar to `_.partial`, except that `partial` arguments are
|
4176
|
+
* appended to those passed to the new function.
|
4177
|
+
*
|
4178
|
+
* @static
|
4179
|
+
* @memberOf _
|
4180
|
+
* @category Functions
|
4181
|
+
* @param {Function} func The function to partially apply arguments to.
|
4182
|
+
* @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
|
4183
|
+
* @returns {Function} Returns the new partially applied function.
|
4184
|
+
* @example
|
4185
|
+
*
|
4186
|
+
* var defaultsDeep = _.partialRight(_.merge, _.defaults);
|
4187
|
+
*
|
4188
|
+
* var options = {
|
4189
|
+
* 'variable': 'data',
|
4190
|
+
* 'imports': { 'jq': $ }
|
4191
|
+
* };
|
4192
|
+
*
|
4193
|
+
* defaultsDeep(options, _.templateSettings);
|
4194
|
+
*
|
4195
|
+
* options.variable
|
4196
|
+
* // => 'data'
|
4197
|
+
*
|
4198
|
+
* options.imports
|
4199
|
+
* // => { '_': _, 'jq': $ }
|
4200
|
+
*/
|
4201
|
+
function partialRight(func) {
|
4202
|
+
return createBound(func, slice(arguments, 1), null, indicatorObject);
|
4203
|
+
}
|
4204
|
+
|
3653
4205
|
/**
|
3654
4206
|
* Creates a function that, when executed, will only call the `func`
|
3655
4207
|
* function at most once per every `wait` milliseconds. If the throttled
|
@@ -3783,11 +4335,11 @@
|
|
3783
4335
|
* }
|
3784
4336
|
* });
|
3785
4337
|
*
|
3786
|
-
* _.capitalize('
|
3787
|
-
* // => '
|
4338
|
+
* _.capitalize('moe');
|
4339
|
+
* // => 'Moe'
|
3788
4340
|
*
|
3789
|
-
* _('
|
3790
|
-
* // => '
|
4341
|
+
* _('moe').capitalize();
|
4342
|
+
* // => 'Moe'
|
3791
4343
|
*/
|
3792
4344
|
function mixin(object) {
|
3793
4345
|
forEach(functions(object), function(methodName) {
|
@@ -3796,9 +4348,7 @@
|
|
3796
4348
|
lodash.prototype[methodName] = function() {
|
3797
4349
|
var args = [this.__wrapped__];
|
3798
4350
|
push.apply(args, arguments);
|
3799
|
-
|
3800
|
-
var result = func.apply(lodash, args);
|
3801
|
-
return new lodash(result);
|
4351
|
+
return new lodash(func.apply(lodash, args));
|
3802
4352
|
};
|
3803
4353
|
});
|
3804
4354
|
}
|
@@ -3833,10 +4383,10 @@
|
|
3833
4383
|
* @example
|
3834
4384
|
*
|
3835
4385
|
* _.random(0, 5);
|
3836
|
-
* // => a number between
|
4386
|
+
* // => a number between 0 and 5
|
3837
4387
|
*
|
3838
4388
|
* _.random(5);
|
3839
|
-
* // => also a number between
|
4389
|
+
* // => also a number between 0 and 5
|
3840
4390
|
*/
|
3841
4391
|
function random(min, max) {
|
3842
4392
|
if (min == null && max == null) {
|
@@ -3851,7 +4401,7 @@
|
|
3851
4401
|
}
|
3852
4402
|
|
3853
4403
|
/**
|
3854
|
-
* Resolves the value of `property` on `object`. If `property` is a function
|
4404
|
+
* Resolves the value of `property` on `object`. If `property` is a function,
|
3855
4405
|
* it will be invoked and its result returned, else the property value is
|
3856
4406
|
* returned. If `object` is falsey, then `null` is returned.
|
3857
4407
|
*
|
@@ -3877,9 +4427,7 @@
|
|
3877
4427
|
* // => 'nonsense'
|
3878
4428
|
*/
|
3879
4429
|
function result(object, property) {
|
3880
|
-
|
3881
|
-
// https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L1419-1424
|
3882
|
-
var value = object ? object[property] : null;
|
4430
|
+
var value = object ? object[property] : undefined;
|
3883
4431
|
return isFunction(value) ? object[property]() : value;
|
3884
4432
|
}
|
3885
4433
|
|
@@ -3887,12 +4435,17 @@
|
|
3887
4435
|
* A micro-templating method that handles arbitrary delimiters, preserves
|
3888
4436
|
* whitespace, and correctly escapes quotes within interpolated code.
|
3889
4437
|
*
|
3890
|
-
* Note: In the development build `_.template` utilizes sourceURLs for easier
|
4438
|
+
* Note: In the development build, `_.template` utilizes sourceURLs for easier
|
3891
4439
|
* debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
|
3892
4440
|
*
|
3893
4441
|
* Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp`
|
3894
|
-
* build and
|
3895
|
-
*
|
4442
|
+
* build and using precompiled templates, or loading Lo-Dash in a sandbox.
|
4443
|
+
*
|
4444
|
+
* For more information on precompiling templates see:
|
4445
|
+
* http://lodash.com/#custom-builds
|
4446
|
+
*
|
4447
|
+
* For more information on Chrome extension sandboxes see:
|
4448
|
+
* http://developer.chrome.com/stable/extensions/sandboxingEval.html
|
3896
4449
|
*
|
3897
4450
|
* @static
|
3898
4451
|
* @memberOf _
|
@@ -3916,8 +4469,8 @@
|
|
3916
4469
|
* // => 'hello moe'
|
3917
4470
|
*
|
3918
4471
|
* var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
|
3919
|
-
* _.template(list, { 'people': ['moe', 'larry'
|
3920
|
-
* // => '<li>moe</li><li>larry</li
|
4472
|
+
* _.template(list, { 'people': ['moe', 'larry'] });
|
4473
|
+
* // => '<li>moe</li><li>larry</li>'
|
3921
4474
|
*
|
3922
4475
|
* // using the "escape" delimiter to escape HTML in data property values
|
3923
4476
|
* _.template('<b><%- value %></b>', { 'value': '<script>' });
|
@@ -3945,11 +4498,11 @@
|
|
3945
4498
|
* // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
|
3946
4499
|
*
|
3947
4500
|
* // using the `variable` option to ensure a with-statement isn't used in the compiled template
|
3948
|
-
* var compiled = _.template('
|
4501
|
+
* var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
|
3949
4502
|
* compiled.source;
|
3950
4503
|
* // => function(data) {
|
3951
4504
|
* var __t, __p = '', __e = _.escape;
|
3952
|
-
* __p += '
|
4505
|
+
* __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
|
3953
4506
|
* return __p;
|
3954
4507
|
* }
|
3955
4508
|
*
|
@@ -3966,24 +4519,27 @@
|
|
3966
4519
|
// http://ejohn.org/blog/javascript-micro-templating/
|
3967
4520
|
// and Laura Doktorova's doT.js
|
3968
4521
|
// https://github.com/olado/doT
|
4522
|
+
var settings = lodash.templateSettings;
|
3969
4523
|
text || (text = '');
|
3970
|
-
|
4524
|
+
|
4525
|
+
// avoid missing dependencies when `iteratorTemplate` is not defined
|
4526
|
+
options = defaults({}, options, settings);
|
4527
|
+
|
4528
|
+
var imports = defaults({}, options.imports, settings.imports),
|
4529
|
+
importsKeys = keys(imports),
|
4530
|
+
importsValues = values(imports);
|
3971
4531
|
|
3972
4532
|
var isEvaluating,
|
3973
|
-
result,
|
3974
|
-
settings = lodash.templateSettings,
|
3975
4533
|
index = 0,
|
3976
|
-
interpolate = options.interpolate ||
|
3977
|
-
source = "__p += '"
|
3978
|
-
variable = options.variable || settings.variable,
|
3979
|
-
hasVariable = variable;
|
4534
|
+
interpolate = options.interpolate || reNoMatch,
|
4535
|
+
source = "__p += '";
|
3980
4536
|
|
3981
4537
|
// compile regexp to match each delimiter
|
3982
4538
|
var reDelimiters = RegExp(
|
3983
|
-
(options.escape ||
|
4539
|
+
(options.escape || reNoMatch).source + '|' +
|
3984
4540
|
interpolate.source + '|' +
|
3985
4541
|
(interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
|
3986
|
-
(options.evaluate ||
|
4542
|
+
(options.evaluate || reNoMatch).source + '|$'
|
3987
4543
|
, 'g');
|
3988
4544
|
|
3989
4545
|
text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
|
@@ -3997,12 +4553,12 @@
|
|
3997
4553
|
source += "' +\n__e(" + escapeValue + ") +\n'";
|
3998
4554
|
}
|
3999
4555
|
if (evaluateValue) {
|
4556
|
+
isEvaluating = true;
|
4000
4557
|
source += "';\n" + evaluateValue + ";\n__p += '";
|
4001
4558
|
}
|
4002
4559
|
if (interpolateValue) {
|
4003
4560
|
source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
|
4004
4561
|
}
|
4005
|
-
isEvaluating || (isEvaluating = evaluateValue || reComplexDelimiter.test(escapeValue || interpolateValue));
|
4006
4562
|
index = offset + match.length;
|
4007
4563
|
|
4008
4564
|
// the JS engine embedded in Adobe products requires returning the `match`
|
@@ -4015,20 +4571,13 @@
|
|
4015
4571
|
// if `variable` is not specified and the template contains "evaluate"
|
4016
4572
|
// delimiters, wrap a with-statement around the generated code to add the
|
4017
4573
|
// data object to the top of the scope chain
|
4574
|
+
var variable = options.variable,
|
4575
|
+
hasVariable = variable;
|
4576
|
+
|
4018
4577
|
if (!hasVariable) {
|
4019
4578
|
variable = 'obj';
|
4020
|
-
|
4021
|
-
source = 'with (' + variable + ') {\n' + source + '\n}\n';
|
4022
|
-
}
|
4023
|
-
else {
|
4024
|
-
// avoid a with-statement by prepending data object references to property names
|
4025
|
-
var reDoubleVariable = RegExp('(\\(\\s*)' + variable + '\\.' + variable + '\\b', 'g');
|
4026
|
-
source = source
|
4027
|
-
.replace(reInsertVariable, '$&' + variable + '.')
|
4028
|
-
.replace(reDoubleVariable, '$1__d');
|
4029
|
-
}
|
4579
|
+
source = 'with (' + variable + ') {\n' + source + '\n}\n';
|
4030
4580
|
}
|
4031
|
-
|
4032
4581
|
// cleanup code by stripping empty strings
|
4033
4582
|
source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
|
4034
4583
|
.replace(reEmptyStringMiddle, '$1')
|
@@ -4041,24 +4590,23 @@
|
|
4041
4590
|
(isEvaluating
|
4042
4591
|
? ', __j = Array.prototype.join;\n' +
|
4043
4592
|
"function print() { __p += __j.call(arguments, '') }\n"
|
4044
|
-
:
|
4593
|
+
: ';\n'
|
4045
4594
|
) +
|
4046
4595
|
source +
|
4047
4596
|
'return __p\n}';
|
4048
4597
|
|
4049
|
-
//
|
4598
|
+
// Use a sourceURL for easier debugging and wrap in a multi-line comment to
|
4599
|
+
// avoid issues with Narwhal, IE conditional compilation, and the JS engine
|
4600
|
+
// embedded in Adobe products.
|
4050
4601
|
// http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
|
4051
|
-
var sourceURL =
|
4052
|
-
? '\n//@ sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']')
|
4053
|
-
: '';
|
4602
|
+
var sourceURL = '\n/*\n//@ sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
|
4054
4603
|
|
4055
4604
|
try {
|
4056
|
-
result = Function(
|
4605
|
+
var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
|
4057
4606
|
} catch(e) {
|
4058
4607
|
e.source = source;
|
4059
4608
|
throw e;
|
4060
4609
|
}
|
4061
|
-
|
4062
4610
|
if (data) {
|
4063
4611
|
return result(data);
|
4064
4612
|
}
|
@@ -4105,7 +4653,7 @@
|
|
4105
4653
|
|
4106
4654
|
/**
|
4107
4655
|
* The opposite of `_.escape`, this method converts the HTML entities
|
4108
|
-
* `&`, `<`, `>`, `"`, and `&#
|
4656
|
+
* `&`, `<`, `>`, `"`, and `'` in `string` to their
|
4109
4657
|
* corresponding characters.
|
4110
4658
|
*
|
4111
4659
|
* @static
|
@@ -4139,7 +4687,8 @@
|
|
4139
4687
|
* // => '105'
|
4140
4688
|
*/
|
4141
4689
|
function uniqueId(prefix) {
|
4142
|
-
|
4690
|
+
var id = ++idCounter;
|
4691
|
+
return (prefix == null ? '' : prefix + '') + id;
|
4143
4692
|
}
|
4144
4693
|
|
4145
4694
|
/*--------------------------------------------------------------------------*/
|
@@ -4157,13 +4706,13 @@
|
|
4157
4706
|
* @returns {Mixed} Returns `value`.
|
4158
4707
|
* @example
|
4159
4708
|
*
|
4160
|
-
* _
|
4709
|
+
* _([1, 2, 3, 4])
|
4161
4710
|
* .filter(function(num) { return num % 2 == 0; })
|
4162
4711
|
* .tap(alert)
|
4163
4712
|
* .map(function(num) { return num * num; })
|
4164
4713
|
* .value();
|
4165
|
-
* // => // [2,
|
4166
|
-
* // => [4,
|
4714
|
+
* // => // [2, 4] (alerted)
|
4715
|
+
* // => [4, 16]
|
4167
4716
|
*/
|
4168
4717
|
function tap(value, interceptor) {
|
4169
4718
|
interceptor(value);
|
@@ -4208,6 +4757,7 @@
|
|
4208
4757
|
// add functions that return wrapped values when chaining
|
4209
4758
|
lodash.after = after;
|
4210
4759
|
lodash.assign = assign;
|
4760
|
+
lodash.at = at;
|
4211
4761
|
lodash.bind = bind;
|
4212
4762
|
lodash.bindAll = bindAll;
|
4213
4763
|
lodash.bindKey = bindKey;
|
@@ -4241,6 +4791,7 @@
|
|
4241
4791
|
lodash.once = once;
|
4242
4792
|
lodash.pairs = pairs;
|
4243
4793
|
lodash.partial = partial;
|
4794
|
+
lodash.partialRight = partialRight;
|
4244
4795
|
lodash.pick = pick;
|
4245
4796
|
lodash.pluck = pluck;
|
4246
4797
|
lodash.range = range;
|
@@ -4347,9 +4898,11 @@
|
|
4347
4898
|
|
4348
4899
|
forOwn(lodash, function(func, methodName) {
|
4349
4900
|
if (!lodash.prototype[methodName]) {
|
4350
|
-
lodash.prototype[methodName]= function(
|
4351
|
-
var result = func(this.__wrapped__,
|
4352
|
-
return
|
4901
|
+
lodash.prototype[methodName]= function(callback, thisArg) {
|
4902
|
+
var result = func(this.__wrapped__, callback, thisArg);
|
4903
|
+
return callback == null || (thisArg && typeof callback != 'function')
|
4904
|
+
? result
|
4905
|
+
: new lodash(result);
|
4353
4906
|
};
|
4354
4907
|
}
|
4355
4908
|
});
|
@@ -4363,7 +4916,7 @@
|
|
4363
4916
|
* @memberOf _
|
4364
4917
|
* @type String
|
4365
4918
|
*/
|
4366
|
-
lodash.VERSION = '1.0.
|
4919
|
+
lodash.VERSION = '1.0.1';
|
4367
4920
|
|
4368
4921
|
// add "Chaining" functions to the wrapper
|
4369
4922
|
lodash.prototype.toString = wrapperToString;
|
@@ -4391,34 +4944,10 @@
|
|
4391
4944
|
each(['concat', 'slice', 'splice'], function(methodName) {
|
4392
4945
|
var func = arrayRef[methodName];
|
4393
4946
|
lodash.prototype[methodName] = function() {
|
4394
|
-
|
4395
|
-
return new lodash(result);
|
4947
|
+
return new lodash(func.apply(this.__wrapped__, arguments));
|
4396
4948
|
};
|
4397
4949
|
});
|
4398
4950
|
|
4399
|
-
// avoid array-like object bugs with `Array#shift` and `Array#splice`
|
4400
|
-
// in Firefox < 10 and IE < 9
|
4401
|
-
if (hasObjectSpliceBug) {
|
4402
|
-
each(['pop', 'shift', 'splice'], function(methodName) {
|
4403
|
-
var func = arrayRef[methodName],
|
4404
|
-
isSplice = methodName == 'splice';
|
4405
|
-
|
4406
|
-
lodash.prototype[methodName] = function() {
|
4407
|
-
var value = this.__wrapped__,
|
4408
|
-
result = func.apply(value, arguments);
|
4409
|
-
|
4410
|
-
if (value.length === 0) {
|
4411
|
-
delete value[0];
|
4412
|
-
}
|
4413
|
-
return isSplice ? new lodash(result) : result;
|
4414
|
-
};
|
4415
|
-
});
|
4416
|
-
}
|
4417
|
-
|
4418
|
-
// add pseudo private property to be used and removed during the build process
|
4419
|
-
lodash._each = each;
|
4420
|
-
lodash._iteratorTemplate = iteratorTemplate;
|
4421
|
-
|
4422
4951
|
/*--------------------------------------------------------------------------*/
|
4423
4952
|
|
4424
4953
|
// expose Lo-Dash
|
@@ -4439,8 +4968,8 @@
|
|
4439
4968
|
// check for `exports` after `define` in case a build optimizer adds an `exports` object
|
4440
4969
|
else if (freeExports) {
|
4441
4970
|
// in Node.js or RingoJS v0.8.0+
|
4442
|
-
if (
|
4443
|
-
(
|
4971
|
+
if (freeModule) {
|
4972
|
+
(freeModule.exports = lodash)._ = lodash;
|
4444
4973
|
}
|
4445
4974
|
// in Narwhal or RingoJS v0.7.0-
|
4446
4975
|
else {
|