-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathunderscore_lodash_immutable.javascript.txt
757 lines (633 loc) · 45.4 KB
/
underscore_lodash_immutable.javascript.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
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
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ UNDERSCORE LODASH IMMUTABLE ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
ITERABLE VS IITERABLE
SET VS ISET
MAP VS IMAP
ARR VS IARR #JavaScript's vs Immutable's
COLL vs ICOLL #Underscore/Lodash's vs Immutable's
┏━━━━━━━━━━━━━━━━━━━━━━━┓
┃ UNDERSCORE LODASH ┃
┗━━━━━━━━━━━━━━━━━━━━━━━┛
VERSIONS ==> #Underscore 1.8.3, Lodash 3.9.0
#Is a Node module or a client-side script
#Can also require only a specific category, e.g. "lodash/array" or "lodash/array/chunk"
#Superset of Underscore:
# - after || or ##: only for Lo-dash
# - after ||| or ###: only for Underscore
# - with | alternatives: prefer first names
#Lodash: more features and much faster. Not superset in few cases:
# - allKeys|mapObject() -> rename to keysIn|mapValues() (exist only in Lodash)
# - extendOwn|matcher() -> rename to assign|matches() (exist in both Lodash and Underscore)
# - first|head|last|initial|rest|tail() with two args -> rename to take|drop[Right]()
# (exist in both Lodash and Underscore)
# - extend|defaults() and LFUNC as an OBJ iterates over own+inherited (Underscore)
# - LFUNC as an OBJ does deep comparison (Lodash)
# - flatten() deep by default (Lodash)
# - memoize.cache different
# - LCHAIN deferred calls
lodash [MODE...] ##Command line to create builds ./lodash[.min].js (must npm install -g lodash-cli)
##MODE... can be:
## - one of:
## - compat (déf): supports old browsers
## - modern: only browsers supporting EcmaScript 5 (IE >=9)
## - plus any of:
## - strict: EcmaScript5 strict mode
## - modularize: put it in several files, for either a category or a single function to
## include
## Also available as Node module "lodash-node" (all functions) or "lodash.FUNC"
## (a single function)
-d|p ##Only creates [non-]minified version
-m [FILE] ##Generates a source map
-o FILE ##Uses a different DIR/FILE output
-c ##Prints to stdout instead
-s ##Silent mode
category=CAT... ##Include only part of it, among "array", "chain", "collection", "date", "function", "lang",
##"object", "number", "string", "utility"
include=FUNC... ##
minus|plus=FUNC|CAT... ##Other ways to include|exclude
exports=EXP... ##Among "amd", "commonjs", "es", "global", "iojs", "node", "npm", "none", "umd"
##"es" and "npm": only with modularize
##"amd": can use moduleId=MODULE_NAME
grunt-lodash ##Grunt plugin (0.4.0):
## - TARGET:
## - dest FILE
## - options:
## - modifier: "modern", etc.
## - modularize BOOL
## - category|include|minus|plus|exports STR_ARR
## - template|settings|moduleId STR
## - flags|shortFlags STR_ARR: other command line flags
┌──────────┐
│ MAIN │
└──────────┘
__ #Based on Underscore: is actually an improved superset, some names are changed but aliases
#maintain compatibility, and new methods are added.
#Often require("lodash") is assigned to _, but since Node REPL uses it for last results,
#can assign to __ instead (but can use _ if not in REPL)
__.noConflict() #Reverts _ to its previous value, and returns LODASH
__.runInContext([OBJ]) ##Returns a copy of __, after mixing in the global object with OBJ (e.g. for mocking)
OBJ[VARR] #Means OBJ[VAR] but:
## - VARR can be "VAR.VAR2..." or [ "VAR", "VAR2", ... ]
## - only for Lodash
COLL #Means either ARR|OBJ|STR, to iterate over the values (chars for STR)
#OBJ should not have a property length.
#For OBJ, only own enumerable properties are being iterated.
RCOLL|ROBJ|RARR|RSTR #Same but iterates from right to left
COLL_ELEM #Element of a COLL, i.e. VAL, single element OBJ or single char STR
LFUNC #FUNC(VAL, KEY, COLL)->VAL2 fired for each element, that can be instead (if COLL is OBJ_ARR):
# - STR:
# - if THIS not bound, same as FUNC(OBJ2) { return OBJ2[VARR_STR] }
## - if THIS bound, same as FUNC(OBJ2) { return OBJ2[VARR_STR] === this }
# - OBJ3: same as FUNC(OBJ2) { return OBJ2 contains OBJ3 }
## Only Lodash does deep comparison, and check only own properties (not inherited)
#Can always be followed by THIS argument.
#LFUNC is actually VAL passed to __.iteratee||callback(VAL[, THIS])->FUNC(VAL, KEY, COLL):
# - can augment LFUNC by reassigning __.callback, e.g.:
# __.callback = __.wrap( __.callback, function( FUNC, VAL, THIS ) {
# if ( TEST ) {
# return FUNC( VAL, THIS );
# } else {
# return function( VAL, THIS ) { return BOOL; }
# }
# } );
__(VAL) #Returns a LCHAIN:
# - OBJ wrapping VAL: get VAL with LCHAIN.value|toJSON|valueOf||run()
# - LCHAIN.FUNC(...) calls __|ARR|STR.FUNC(VAL, ...)->LCHAIN2
# - does not return LCHAIN2 if FUNC() returns non-OBJ, unless LCHAIN.chain() fired before
# or __.chain(VAL) used instead of __(VAL)
##LCHAIN performance:
## - deferred: only fires LCHAIN functions when:
## - value|toJSON|valueOf||run() called, returning final VAL. If called again, fire LCHAIN again
## - commit(): same but returns LCHAIN
## - returning non-OBJ
## - pipelined, i.e. chaining reuse same variable (no temp variables), so is faster
## - lazy evaluated / shortcut fusion, i.e. each element goes through the whole LCHAIN
## instead of all element going through each step. E.g. if finished by __.take(NUM) will because
## much faster because stops processing after NUM elements.
__.toString() #Same as __.value().toString()
__.tap(COLL, LFUNC) #Fires LFUNC (which can modify each VAL, but should not return it) then returns COLL
__.thru(COLL, LFUNC) ##Fires LFUNC which can modify VAL by returning it
__.plant(VAL) ##Changes initial VAL from __(VAL), cloning LCHAIN
__.reverse() ##Changes initial ARR from __(ARR) to __(ARR.reverse())
┏━━━━━━━━━━━━━━━┓
┃ IMMUTABLE ┃
┗━━━━━━━━━━━━━━━┛
VERSION ==> #3.7.6
GOAL ==> #Provide:
# - IARR|IMAP|ISET: ARR|MAP|SET like JavaScript but immutable (setters create copy)
# - ISEQ: deferring, pipeline, lazy-evaluation like Lodash chain
# - ISTACK: like IARR, but optimized for FIFO
# - ordered IMAP|ISET
# - IRECORD: IMAP with define set of keys, and default values
IVARR #Similar to VARR but using IITERABLE|SET|ARR|MAP
#Each intermediate|final value must be an IITERABLE
NATIVE JAVASCRIPT ==> #IITERABLE implements all ARR|MAP|SET methods, except:
# - no: length (use size), Array.from(), fill|copyWithin()
# - only on:
# - ICOLL|ISEQ: size
# - IARR|IMAP|ISET|ISTACK: clear()
# - IARR|IMAP|ISET: delete()
# - IARR|IMAP: set()
# - IARR|ISTACK: push|pop|shift|unshift()
# - ISET: add()
# - ARR.concat(VAL) -> IITERABLE.concat(VAL|IITERABLE2...)
LODASH ==> #When signature specified below, has same behavior as Lodash not Underscore.
┌──────────────────┐
│ IMMUTABILITY │
└──────────────────┘
IMMUTABILITY ==> #Setters creates copies:
# - unless setters did not change anything
# - efficient: copies are as deep for what changed, shallow otherwise
# - only for Immutable setters. IITERABLE.VAR = VAL will do nothing and return VAL.
#Use cases:
# - object which should be used but not modified
# - fast track changes: === instead of deep comparison
# - i.e. consumer gets new objects instead of keeping references
RETURN VALUE ==> #Is the same object, unless specified otherwise
ISET|IARR|IMAP|ISTACK. #Opts-in|out of immutability, i.e. setters will return same object instead of copy
as[Im]Mutable() #To do for performance optimization when many setters are called on same object,
#to avoid too many intermediate copies.
ISET|IARR|IMAP|ISTACK.withMutations
(FUNC(ISET|IARR|IMAP|ISTACK)) #Calls asMutable() then FUNC() then asImmutable()
┌───────────┐
│ TYPES │
└───────────┘
IMMUTABLE.Iterable (ITERABLE)
IMMUTABLE.Collection (ICOLL) #Child of IITERABLE
IMUTABL.Iterable.Indexed|Keyed|Set
(IINDEXED|IITERABLE.KEYED|SET) #Child of IITERABLE
IMMUTABLE.Seq|Collection.
Indexed|Keyed|Set
(ISEQ|ICOLL.INDEXED|KEYED|SET) #Child of IINDEXED and ICOLL|ISEQ
IMMUTABLE.Seq (ISEQ) #Child of IITERABLE
#Like ICOLL but deferred (unless ISEQ.cacheResult()),
#pipelined, lazy-evaluated (like Lodash chain)
IMMUTABLE.List (IARR) #Child of ICOLL.INDEXED
#Immutable ARR
IMMUTABLE.Stack (ISTACK) #Child of ICOLL.INDEXED
#Immutable FIFO
IMMUTABLE.Map (IMAP) #Child of ICOLL.KEYED
#Immutable MAP
IMMUTABLE.Set (ISET) #Child of ICOLL.ISET
#Immutable SET
IMMUTABLE.OrderedMap|OrderedSet #Child of IMAP|ISET
#Makes it iterate in the same order as items were set|added.
IMMUTABLE.Record(OBJ[, 'NAME']) #Child of IMAP
->IRECORD_TYPE #Like IMAP except:
new IRECORD_TYPE(OBJ2)->IRECORD # - only keys present in OBJ can be set (otherwise silently not set)
# - OBJ are default values
# - IRECORD.VAR = VAL throws error
┌─────────────────────────────┐
│ CONVERSION/CONSTRUCTION │
└─────────────────────────────┘
DEEP ==> #Only fromJS|toJS() are deep. Everything else shallow.
IMMUTABLE.fromJS(VAL) #Returns, using according to VAL:
->ILIST|IMAP|VAL # - ARR: ILIST()
# - plain OBJ: IMAP()
# - others: as is
IITERABLE.toJS|toJSON()->ARR|OBJ #
IITERABL.toArray|Object()->ARR|OBJ#
Set|List|Stack|Seq[.Set|Indexed]
.of(VAL...)->ISET|ILIST|etc. #Like creating empty, then setting|adding each VAL
[I]MAP -> [I]ARR|[I]SET #{ VAR: VAL ... } -> [[KEY, VAL]...]
[I]ARR|[I]SET -> [I]MAP #[VAL...] -> { VAL: VAL ... }
... -> ISET #Removes duplicates
IARR|ISTACK(IITERABLE|ARR|SET|MAP)#
IITERABLE.toList|Stack() #
IMAP(IITERABLE|ARR|SET|MAP|OBJ) #
IITERABLE.to[Ordered]Map() #
ISET([IITERABLE|ARR|SET|MAP]) #Use values
IITERABLE.to[Ordered]Set() #
ISET.fromKeys(IITERABLE|OBJ|MAP) #Use keys
IITERABLE.toSeq()->ISEQ #Uses toKeyedSeq|toIndexedSeq|toSetSeq() according to IITERABLE type
IITERABLE.toKeyedSeq()->ISEQ.KEYED #Not from [[KEY, VAL]]
IINDEXED.fromEntrySeq()
->ISEQ.KEYED #From [[KEY, VAL]]
IITERABLE.toIndexedSeq()
->ISEQ.INDEXED #
IITERABLE.key|value|entrySeq()
->ISEQ.INDEXED #Like keys|values|entries() except returns as ISEQ.INDEXED
IITERABLE.toSetSeq()->ISEQ.SET #
┏━━━━━━━━━┓
┃ ALL ┃
┗━━━━━━━━━┛
┌───────────────┐
│ BASIC GET │
└───────────────┘
__.size(COLL) #Returns ARR.length, STR.length or __.keys(OBJ).length
ICOLL|ISEQ.size -#
__.keys(OBJ) #Like Object.keys(), except crossbrowser and if not OBJ, returns [] instead of throwing an error
__.||keysIn|||allKeys(OBJ) #Like for (var VAR in OBJ), except crossbrowser and return as ARR
__.values(OBJ) #Same as __.keys() but for values
__.||valuesIn(OBJ) #Same as __.keysIn() but for values
__.functions|methods(OBJ) #Same as __.keysIn(), but only for FUNC members
__.get(OBJ, VARR[, VAL2]) ##Returns OBJ[VARR]
##VAL2 is default value.
IITERABLE.get('VAR')->VAL -#
IITERABLE.getIn(IVARR)->VAL -#
__.result(...) #Like OBJ.get(...), except that if returns a FUNC, returns FUNC() instead
__.has(OBJ, VARR) #Same as hasOwnProperty() but crossbrowser
IITERABLE.has('VAR')->BOOL -#
IITERABLE.hasIn(IVARR)->BOOL -#
┌───────────────┐
│ BASIC SET │
└───────────────┘
__.set(OBJ, VARR, VAL) ##Assigns OBJ[VARR] = VAL
IARR|IMAP.set('VAR', VAL) -#
IARR|IMAP.setIn(IVARR, VAL) -#
ISET.add(VAL) -#
IARR|IMAP|ISET.delete|remove
(NUM|'KEY'|VAL) -#
IAR|IMAP.deleteIn|removeIn(IVARR)-#
IARR|ISTACK|IMAP|ISET.clear() -#
ISTACK.unshiftAll
(IITERABLE|ARR|SET|MAP) -#Similar to ISTACK.unshift()
┌───────────────────────┐
│ ASSIGNING/MERGING │
└───────────────────────┘
IARR|IMAP.update
('VAR', [VAL2, ]FUNC(VAL)->VAL) -#
IARR|IMAP.updateIn
(IVARR, [VAL2, ]FUNC(VAL)->VAL) -#
IARR|IMAP.update
(FUNC(IARR|IMAP)->IARR|IMAP) -#Like IARR|IMAP.set[In]() but with a function
__.assign||extend|||extendOwn #Assign own enumerable properties of OBJ2... to OBJ, then return OBJ
(OBJ, OBJ2...[, FUNC[, THIS]]) #If FUNC, values being assigned are filtered first by
#FUNC.call(THIS, OLD_VAL, NEW_VAL, "KEY", OBJ, OBJ2)->VAL (excludes if undefined)
__.extend(...) ###Same as __.assign(...) but for own+shared enumerable properties
__.merge(...) ##Same as __.assign() but if both OBJ.KEY: OBJ3 and OBJ2.KEY: OBJ4 exists, recursively
##__.assign(OBJ3, OBJ4)
IARR|IMAP.merge[Deep]
(IITERABLE|ARR|MAP|SET|OBJ) -#
IARR|IMAP.merge[Deep]In
(IVARR,IITERABLE|ARR|MAP|SET|OBJ)-#Like __.extend|merge()
IARR|IMAP.merge[Deep]With
(FUNC(VAL, VAL2,'KEY')->VAL,VAL2)-#Like IARR|IMAP.merge[Deep]() but with custom merge function
__.defaults(OBJ, OBJ2...) #Same as __.extend(), except it doesn't assign if OLD_VAL !== undefined
MERGEDEFAULTS(...) ####Same for __.merge(). Is Node module "merge-defaults"
__.create(OBJ[, OBJ2]) #Like Object.create(), except OBJ2 is simpler: {VAR: VAL} instead of
#{VAR: {value: VAL, enumerable: true, configurable: true, writable: true}}
#Which means returns OBJ2, where OBJ2.__proto__ pointe vers OBJ
__.mixin([OBJ, ]OBJ2[, OBJ3]) #Same as __.assign(), except:
# - doesn't return OBJ, but modify it directly
# - only copy OBJ2.FUNC members
## - if OBJ3.chain true (déf) and OBJ is __ (def), OBJ2.FUNC can be chained (they will take
## current chain value as first arg), e.g. __(VAL).FUNC(...) will call OBJ2.FUNC(VAL,...)
## - only Lodash can use non-default OBJ
┌──────────────────────┐
│ CLONING/CREATING │
└──────────────────────┘
__.toArray(COLL) #For:
# - ARR: does nothing
# - OBJ: transform to VAL_ARR
# - STR: transform to STR_ARR (of characters)
__.clone #Returns OBJ by copy, for own+shared enumerable (Underscore) / own enumerable (Lodash) members.
(OBJ||[,BOOL][,FUNC[,THIS]]) #Nested OBJ are by copy if BOOL true, by reference otherwise (déf: false)
#FUNC: like __.assign()
__.cloneDeep(OBJ[, ...]) ##Same as __.clone(OBJ, true, ...)
__.toPlainObject(OBJ) ##Make enumerable shared properties become enumerable own.
__.fill(ARR, VAL[, NUM[, NUM2]]) ##Fills ARR with VAL (from NUM to NUM2)
__.times(NUM, FUNC[, THIS]) #Fires FUNC(INDEX) NUM times, and returns ARR concatenating all return values
IMMUTABLE.Repeat(VAL[, NUM])
->COLLINDEXED -#Repeats VAL NUM times (def: infinite)
┌─────────────┐
│ FINDING │
└─────────────┘
__.find|detect||findLast #Returns the first COLL_ELEM that returns true with LFUNC(), or undefined if none if found
([R]COLL, LFUNC) #(for ARR|STR, prefer using __.findIndex())
IITERABLE.find[Last](FUNC[, VAL2])
->VAL -#Like _.find(FUNC) with default VAL2
__.findWhere(...) #Same as __.find() but COLL can only be OBJ_ARR
__.findKey||findLastKey(...) #Same as __.find() but returns only the "KEY" (undefined if none)
IKEYED.[last]keyOf(VAL)->'KEY' -#
IKEYED.find[Last]Key(FUNC)->'KEY'-#
__.find[Last]Index([R]ARR, LFUNC) #Same as __.find() but returns only the KEY_NUM (-1 if none)
IINDXD.find[Last]Index(FUNC)->NUM-#
IITERABLE.find[Last]Entry
(FUNC[, VAL2])->[KEY, VAL] -#Like IITERABLE.find[Last](...) but returns [KEY, VAL]
__.[lastI|i]ndexOf
([R]ARR, VAL[, NUM]) #Like ARR.[lastI|i]ndexOf(VAL, NUM), using ===
__.sortedIndex||sortedLastIndex #Returns index where VAL would be inside sorted ARR (must be sorted).
(ARR, VAL[, LFUNC]) #If LFUNC, do __.map(ARR, LFUNC) first (result ARR must be sorted).
#If several possible positions, choose first|last one.
┌─────────────┐
│ TESTING │
└─────────────┘
__.isEqual||eq #Deep comparison of own enumerable properties.
(OBJ, OBJ2||[, FUNC[, THIS]]) #Uses either === or FUNC (same one as __.assign())
__.isMatch(...) #Same but only checks if OBJ includes OBJ2
IMMUTABLE.is(VAL, VAL2) -#Like === but:
-# - deep comparison of IITERABLE (but not OBJ), which must still be same type
-# - NaN === NaN
IITERABLE.equals(VAL) -#Same as IMMUTABLE.is(IITERABLE, VAL)
IITERABLE.hashCode()->NUM -#Numeric checksum of IITERABLE deep content (not identity)
__.include|contains
(COLL, VAL[, INT]) #Returns true if VAL is a value of COLL (using ===), from index INT (déf: 0, can be negative)
IITERABLE.includes|contains
(COLL, VAL)->BOOL -#
__.every|all(COLL, LFUNC->BOOL) #Returns true if BOOL is always true
IITERABLE.every(FUNC)->BOOL -#
__.some|any(COLL, LFUNC->BOOL) #Returns true if BOOL is true at least once
IITERABLE.some(FUNC)->BOOL -#
┌───────────────┐
│ FILTERING │
└───────────────┘
__.take[Right]|||first|head|last
([R]ARR[, NUM]) #Returns NUM first|last elements (déf: 1)
IITERABLE.take[Right](NUM) -#
__.take[Right]While([R]ARR,LFUNC)##Returns elements until LFUNC returns false.
IITERABLE.takeWhile|Until(FUNC) -#
__.first|head|last([R]ARR) ##Same as __.take([R]ARR, 1)
IITERABLE.first|last()->VAL -#
__.drop*|||initial|rest|tail(...) #Same as __.take, but excludes instead of includes
IITERABLE.skip*(NUM ) -#
__.initial|rest|tail([R]ARR) ##Same as __.drop([R]ARR, 1)
IITERABLE.butLast|rest() -#
__.sample(COLL[, NUM]) #Keeps NUM random elements, in a random order.
#If no NUM, like 1 but returns a single COLL_ELEM (not a COLL)
__.at(COLL, KEY[_ARR]...) ##Excludes any VAL not with KEY[_ARR] from COLL, and returns as VAL_ARR
__.without(ARR, VAL...) #Excludes any VAL... from ARR
__.where(OBJ_ARR, OBJ2) #Excludes any OBJ not containing OBJ2 from OBJ_ARR
__.filter|select(COLL, LFUNC) #Excludes any VAL where LFUNC() returns false
#Similar to native ARR.filter()
IITERABLE.filter(FUNC) -#
__.reject(COLL, LFUNC) #Inverse
IITERABLE.filterNot(FUNC) -#
__.omit|pick(OBJ, LFUNC) #Same as __.filter|reject() but:
# - returns as __.clone(OBJ, false)
# - LFUNC cannot be OBJ, and can be STR[_ARR]..., meaning the properties names to exclude.
__.pullAt|pull|remove(...) ##Same as __.at|without|filter(...) but removes elements from ARR too, and only works on ARR
__.compact(ARR) #Excludes any false, null, 0 or "" from ARR
__.uniq|unique(ARR[,BOOL][,LFUNC])#Returns ARR without duplicates. If ARR is sorted, use BOOL true to make it faster.
#If LFUNC, do __.map(ARR, LFUNC) first (result ARR must be sorted).
__.difference(ARR, ARR2...) #Excludes any VAL of ARR2... from ARR
ISET.subtract
(IITERABLE|ARR|SET|MAP) -#
__.intersection(ARR...) #Returns an ARR2 with values present in all ARR..., without duplicates
ISET.intersect
(IITERABLE|ARR|SET|MAP) -#
__.union(ARR...) #Same for values present in any ARR...
ISET.union|merge
(IITERABLE|ARR|SET|MAP) -#
__.xor(ARR...) #Same for values present in only one ARR...
IITERABLE.isSubset|Superset
(IITERABLE2)->BOOL -#
┌────────────────┐
│ PROCESSING │
└────────────────┘
__.each|forEach||[Right] #Similar to ARR.forEach() but returns COLL, and uses __.toArray()
([R]COLL, LFUNC) ##If LFUNC() returns false, stops the iteration.
IITERABLE.forEach(FUNC) -#
__.forOwn|In[Right]([R]OBJ,LFUNC)##Same as __.forEach() but only for OBJ and more efficient for it
##If In, also iterated over inherited enumerable properties.
__.map|collect(COLL, LFUNC) #Similar to ARR.map() but returns COLL, and uses __.toArray()
IITERABLE.map(FUNC) -#
__.||mapValues|||mapObject
(OBJ, LFUNC) #Same as __.map(...) but LFUNC must not return the OBJ but only its value (the key is kept)
__.mapKeys(OBJ, LFUNC) ##Same for keys
IKEYED.mapKeys(FUNC) -#
IKEYED.mapEntries
(FUNC([KEY, VAL], NUM, IKEYED)
->[KEY, VAL][, THIS]) -#Like IKEYED.mapKeys(...) but settings both key and value
__.invoke(OBJ_ARR,FUNC|VARR[,...])#Each OBJ = FUNC(...) or OBJ[VARR](...), with OBJ as this
__.reduce[Right]|inject|foldl|r
([R]COLL, LFUNC[, VAL3]) #Same as ARR.reduce[Right]() but returns COLL, and uses __.toArray()
IITERABLE.reduce[Right](...)->VAL-#
__.transform(...) ##Same as __.reduce(), except:
## - LFUNC() must not return value, but manipulate VAL
## - can stop the iterations by returning false in LFUNC
## - Déf VAL3 is [] or {} depending on COLL
__.pluck(OBJ_ARR, VARR) #Same as __.map(OBJ_ARR, OBJ => OBJ[VARR])
__.invert(OBJ[, BOOL]) #Invert keys and values, and only keep own enumerable properties.
#If multiple keys per same values, keep only last one if BOOL false (def), or create ARR.
IKEYED.flip() -#
__.partition(COLL, LFUNC) #Returns [ ARR, ARR2 ], where ARR has the VALs where LFUNC returned true, ARR2 false
__.groupBy(COLL, LFUNC->VAL2) #Returns { VAR2: VAL_ARR }
IITERABLE.groupBy(FUNC) -#
__.countBy(COLL, LFUNC->VAL2) #Returns { VAR2: VAL_ARR.length }
IITERABLE.countBy(FUNC)->NUM -#
IITERABLE.count
([FUNC(VAL, KEY, IITERABLE)->BOOL
[, THIS]])->NUM -#Like __.filter().length
__.indexBy(COOL, LFUNC->VAL2) #Returns { VAR2: VAL_ARR[-1] }
IINDEXED.interpose(VAL) -#Adds VAL between each element
IARR.setSize(NUM) -#Truncates or fills with undefined
┌──────────────────────┐
│ ARRAY DIMENSIONS │
└──────────────────────┘
__.flatten(ARR[, BOOL]) #Erase 1 (if BOOL true) or all levels of depth
##(if BOOL false (déf))
###(if BOOL true (déf))
__.flattenDeep(ARR) ##Same as __.flatten(ARR, true)
IITERABLE.flatten([BOOL|NUM]) -#Like _.flatten() but:
-# - can specify NUM levels of depth
-# - each level of depth must contain other IITERABLE2
IITERABLE.flatMap(...) -#Like map(...) + flatten(true)
__.chunk(ARR[, NUM]) ##Returns as ARR_ARR, where each sublevel has NUM (def: 1) elements (except maybe the last
##one)
__.zip(ARR...) #Returns ARR... as ARR_ARR, where ARR numéro NUM has the element numéro NUM of each ARR...
IINDEXED.zip(IINDEXED2...) -#
__.unzip(ARR_ARR) #Same but use ARR_ARR instead of ARR..., which will effectively inverse __.zip()
__.zipWith(ARR..., FUNC[, THIS]) ##Same as __.zip() but groups elements into final ARR2 by calling accumulator
##FUNC(VAL2, VAL, INDEX, ARR)->VAL2 where VAL2 is the accumulated value (initially the first
##VAL), VAL the next one, ARR the whole group and INDEX the index of VAL in ARR
IINDEXD.zipWith(FUNC(VAL...)->VAL,
IITERABLE2[_ARR]...) -#
__.unzipWith(ARR_ARR, ...) ##Same as __.zip(ARR..., ...) but use ARR_ARR instead of ARR...
IINDEXED.interleave(IITERABLE2...)#Like zip() + flatten()
__.pairs(OBJ) #Transforms to [ [ KEY, VAL ]... ]
__.zipObject|object(ARR_ARR) #Inverse.
__.zipObject|object(ARR[, ARR2]) #Here ARR are the keys and ARR2 the values (déf: [])
┌─────────────┐
│ SORTING │
└─────────────┘
__.sortBy(COLL, LFUNC) #Sorts COLL according to LFUNC return value.
IITERABLE.sortBy(FUNC) -#
__.sortByAll(COLL,LFUNC[_ARR]...)##Same but use several LFUNC in priority order.
__.sortByOrder(..., BOOL_ARR) ##Same as __.sortByAll(...) but specifies asc|desc with BOOL true|false
__.shuffle(COLL) #Shuffles COLL, after applying __.toArray()
#Based on Math.random
┌───────────────────┐
│ TYPE CHECKING │
└───────────────────┘
__.isBoolean(VAL) #
__.isNumber(VAL) #NaN is a NUM
__.isString(VAL) #
__.isObject(VAL) #
__.isPlainObject(VAL) ##
__.isArray(VAL) #Like Array.isArray()
__.isTypedArray(VAL) ##
__.isFunction(VAL) #
__.isNative(VAL) ##Native FUNC
__.isDate(VAL) #
__.isRegExp(VAL) #
__.isError(VAL) #
__.isArguments(VAL) #True if "arguments"
__.isElement(VAL) #Is a DOM ELEMENT
ITYPE.isITYPE(VAL) -#E.g. Immutable.Set.isSet(VAL)
-#Notes:
-# - not for ICOLL[.*]
-# - IITERABLE.KEYED|INDEXED|ISET: use IMMUTABLE.Iterable.isKeyed|Indexed|Associative(VAL)
IMMUTABLE.Iterable.isOrdered(VAL)
->BOOL -#
__.isFinite(VAL) #Same as isFinite(VAL), except it doesn't returns true for BOOL or ""
__.isNaN(VAL) #Same as isNaN(VAL), except it doesn't returns true for undefined and non-NUM
__.isNull(VAL) #
__.isUndefined(VAL) #
__.isEmpty(VAL) #True if Object.keys(OBJ)|ARR|STR.length == 0
IITERABLE.isEmpty()->BOOL -#
┌────────────────────────┐
│ FUNCTION ARGUMENTS │
└────────────────────────┘
__.FUNC.placeholder ##Value signifying unknown parameter yet (def: __), e.g.:
## - __.bind(FUNC(a,b,c), THIS, 1, __, 3)(2)
## - __.curry(FUNC(a,b,c))(__, 2)(1, 3)
##E.g.: __.bind.placeholder (def: __)
__.bind(FUNC[, THIS[, ...]]) #Like FUNC.bind(THIS, ...).
##Can use __.FUNC.placeholder.
__.partial||partialRight #Like FUNC.bind(null, ...).
(FUNC[, ...]) #If Right, ... are appended, not prepended.
__.bindKey(OBJ, "FUNC"[, ...]) ##Like OBJ.FUNC.bind(OBJ, ...), except that it refers to FUNC as "FUNC", which means
##if OBJ.FUNC is reassigned, the bound function will refer to the new assigned function.
__.bindAll(OBJ[, "FUNC"...]) #Replace OBJ[.FUNC] by __.bind(FUNC, OBJ) so it is possible to pass OBJ.FUNC as arguments
#without doing OBJ.FUNC.bind(OBJ)
__.wrap(FUNC(...),FUNC2(FUNC,...))#Returns FUNC2.partial( FUNC )
__.createCallback(LFUNC[, NUM]) ##Like FUNC.bind(OBJ), except:
## - Only accepts max NUM arguments
## - can be LFUNC (i.e. STR or OBJ too)
__.negate(FUNC->BOOL) #Returns FUNC, but inverse return value
__.ary(FUNC, NUM) ##Returns FUNC, but can only take max NUM arguments (erased otherwise).
__.flowRight|compose||flow(FNC...)#Returns FUNC(FUNC2(etc.)) (flowRight) or FUNC2(FUNC(etc.)) (flow)
__.curry[Right](FUNC[, NUM]) ##Returns FUNC, but makes it possible to fire with only first arguments, in which case it
##returns a bound function, e.g: can be fired with f(1,2,3) or:
## - curry: f(1)(2)(3) or f(1,2)(3)
## - curryRight: f(3)(2)(1) or f(2,3)(1)
##Can use __.FUNC.placeholder
##NUM means only consider first NUM arguments (other are ignored)
__.rearg(FUNC, NUM[_ARR]...) ##Returns FUNC, but with different argument position (NUM starting at 0),
##e.g. [ 1, 0 ] to inverse two arguments positions.
__.restParam(FUNC[, NUM]) ##Make argument number NUM (def: last one) variadic, i.e. an ARR
__.spread(FUNC) ##Returns FUNC, but must call FUNC(ARGS_ARR) instead of FUNC(ARGS...)
┌────────────────────┐
│ FUNCTION CALLS │
└────────────────────┘
__.before(NUM, FUNC) #Returns FUNC that fire only the first NUM times, after wards it just returns last result.
__.once(FUNC) #Same as __.before(1, FUNC)
__.after(NUM, FUNC) #Returns FUNC that doesn't fire the first NUM-1 times.
#Goal is to invoke in a loop of NUM items so it fires at last iteration, but without
#having to check if it's the last iteration.
__.debounce(FUNC[, NUM[, OBJ]]) #Returns FUNC that invoked accordingly:
# - fires at beginning if OBJ.leading true (déf: false)
# - wait for NUM (def: 0) milliseconds.
# If invoked again, restart the waiting time (but doesn't fire)
# Expanded time cannot be more than OBJ.maxWait (déf: Infinity, needs to be > NUM)
# - fires at end if OBJ.trailing true (déf: true)
#Also adds FUNC.cancel(), which cancels currently delayed calls.
__.throttle(FUNC[, NUM[, OBJ]]) #Same except:
# - If invoked during the wait, doesn't restart waiting time (is just ignored)
# - OBJ.leading is true by déf
__.delay(FUNC, NUM[, ...]) #Same as setTimeout(FUNC[.bind(null, ...)], NUM)
__.defer(FUNC[, ...]) #Same as __.delay(FUNC, 0, ...)
__.memoize(FUNC[, FUNC2]) #Returns FUNC with a FUNC.cache OBJ
#Each time FUNC(...) is fired:
# - Sets FUNC.cache at key FUNC2(...) with value FUNC(...)
# - Gets cache is used if already existing (FUNC() is not performed)
#Déf FUNC2 caches according to first argument:
# - return "KEY" + FIRST_ARG,
# - where "KEY" is __.now() when lodash was loaded
##FUNC.cache is an instance of __.memoize.Cache, which can be substituted if having the same
##methods: get("KEY")->VAL, set("KEY", VAL)->CACHE, delete("KEY")->BOOL, has("KEY")->BOOL
#See fast-memoize for alternatives
┌──────────────────────┐
│ FUNCTION HELPERS │
└──────────────────────┘
__.constant(VAL) #Returns FUNC()->VAL
__.identity(VAL) #Returns VAL
__.noop() #Does nothing
__.matches|||matcher(OBJ) #Returns FUNC(OBJ2)->BOOL checking if OBJ2 includes OBJ
__.matchesProperty(VARR, VAL) ##Returns FUNC(OBJ)->BOOL checking if OBJ[VARR] === VAL
__.property(VARR) #Returns FUNC(OBJ)->OBJ[VARR]
__.propertyOf(OBJ) #Returns FUNC(VARR)->OBJ[VARR]
__.method(VARR[, ...]) ##Returns FUNC(OBJ) that fires OBJ[VARR](...)
__.methodOf(OBJ) ##Returns FUNC(VARR[, ...]) that fires OBJ[VARR](...)
__.attempt(FUNC[, ...]) ##Like FUNC(...) but if ERROR thrown, returns it instead
┌────────────┐
│ STRING │
└────────────┘
__.starts|endsWith
(STR, STR2[, NUM]) ##
__.camelCase(STR) ##aBcDe
__.capitalize(STR) ##Abcde
__.kebabCase(STR) ##a-bc-de
__.snakeCase(STR) ##a_bc_de
__.startCase(STR) ##A Bc De
__.repeat(STR, NUM) ##Concatenates STR NUM times
__.pad[Left|Right]
(STR, NUM[, STR2]) ##Adds STR2 (def: " ") on left and|or right of STR, so that it is of Unicode length STR
__.trim[Left|Right](STR[, STR2]) ##STR2 (def: whitespaces)
__.trunc(STR[, NUM][, STR2] ##Truncates STR at max NUM (def: 30) length chars, adding ellipsis STR2 (def: "…")
[, REGEXP|STR3]) ##If REGEXP|STR3 defining words, make sure only full words are output.
__.trunc(STR[, OBJ]) ##Same using OBJ.length|omission|separator
__.words(STR[, REGEXP]) ##Splits as STR_ARR. REGEXP is not the delimited, but the words (def: a word only contains
##[[:alnum:]], and a uppercase means a new word)
__.[un]escape(STR) #HTML escape: & < > " ' ` to ampersand sequences
__.escapeRegExp(STR) ##RegExp escape: \ / ^ $ . | ? * + ( ) [ ] { }
__.deburr(STR) ##Replaces accents by letter without accent
__.parseInt(STR[, NUM]) ##Same as native, but crossbrowser
┌───────────────┐
│ TEMPLATES │
└───────────────┘
__.template(STR[, OBJ[, OBJ2]]) #Returns a FUNC(OBJ3) that interpolate following sequences, using OBJ3 as context
#(current context also used):
# <%= EXPR %>
## ${EXPR} -> VAL
# <%- EXPR %> -> __.escape(VAL)
# <% EXPR %> -> executes EXPR, then returns ""
# Inside EXPR, executing %>...<% or print(STR) concatenates "..." to
# return value, without stopping EXPR
# "..." can contain other templates, recursively interpreted after insertion
# Ex:
# __.template('<% [a,b].forEach(function(c){ %> <%= c %> <% }) %>',
# {a:1,b:2}); // " 1 2 "
#If OBJ is provided, returns FUNC(OBJ) result directly.
#OBJ2 (def: from __.templateSettings) are options:
# - interpolate REGEXP: to replace <% %>, must be /...(...).../g
# For mustache-like: /{{([\s\S]+?)}}/g
# - escape|evaluate REGEXP: same for <%- %> and <% %>
# Default interpolations are /<%-([\s\S]+?)%>/g, etc.
## - imports OBJ: merged (with lower priority) into OBJ3
## - sourceURL STR: source of the template (like source maps: show original file in debugger)
TEMPLATE(STR[, OBJ[, OBJ2]]) ####Node module "template"
####Same but process templates recursively, and OBJ2 options have also:
#### - delims STR_ARR, e.g. [ '{{', '}}' ]
TEMPLATE.read(...) ####Same but STR is a filename
TEMPLATE.copy(STR, STR2[, OBJ ####Like TEMPLATE.read(), but copy to file STR2 instead of returning value.
[,OBJ2]]) ####Can use OBJ2.process: false to disable processing (so only copy file).
lodash template="GLOB_FILES" ##lodash-cli (see above). GLOB_FILES are Lodash templates files (e.g. containing <%= EXPR %>)
##Creates files which when required load: { FILENAME: FUNC(OBJ3) ... }
settings="OBJ2" ##Same OBJ2 as __.template()
jstify ##Browserify transform (0.10.0) that transforms "HTML" (Underscore/Lodash template) to template
##FUNC()
##Options:
## - engine "underscore(def)|lodash"
## - templateOpts OBJ2 (interpolate, etc.)
## - minifierOpts OBJ: passed to HTMLMinifier
┌──────────┐
│ MATH │
└──────────┘
__.add(NUM, NUM2) ##Returns NUM + NUM2
__.sum(COLL[, LFUNC]) ##Like __.reduce() with default LFUNC __.add()
__.min|max(COLL[, LFUNC]) #Returns the COLL_ELEM that returns the min|max value with LFUNC() (def: __.identity)
IITERABLE.min|max
([FUNC(VAL, VAL2)->NUM])->VAL -#Def FUNC: <
IITERABLE.minBy|maxBy
(FUNC2(VAL, KEY, IITERABLE)->VAL),
FUNC(VAL, VAL2)->NUM)->VAL -#Same but map values before
__.gt[e]|lt[e](VAL, VAL2) ##Returns BOOL
__.range([INT, ]INT2[, INT3]) #Like {INT..INT2..INT3} in Bash. INT is 0 by déf, INT3 is 1.
IMMUTABLE.Range(...)->COLLINDEXED-#
__.inRange(NUM[, NUM2], NUM3) ##NUM >= NUM2 (def: 0) && NUM < NUM3
__.now() #Same as (new Date()).getTime()
__.random([INT][, INT2][, BOOL]) #INT is min (déf: 0), INT2 max excluded (déf: 1), BOOL floating point (déf: false)
__.uniqueId([STR]) #Returns STR + NUM, where NUM is incrementing (relative to __)