source: imaps-frontend/node_modules/immutable/README.md@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 28.2 KB
Line 
1# Immutable collections for JavaScript
2
3[![Build Status](https://github.com/immutable-js/immutable-js/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/immutable-js/immutable-js/actions/workflows/ci.yml?query=branch%3Amain) [Chat on slack](https://immutable-js.slack.com)
4
5[Read the docs](https://immutable-js.com/docs/) and eat your vegetables.
6
7Docs are automatically generated from [README.md][] and [immutable.d.ts][].
8Please contribute! Also, don't miss the [wiki][] which contains articles on
9additional specific topics. Can't find something? Open an [issue][].
10
11**Table of contents:**
12
13- [Introduction](#introduction)
14- [Getting started](#getting-started)
15- [The case for Immutability](#the-case-for-immutability)
16- [JavaScript-first API](#javascript-first-api)
17- [Nested Structures](#nested-structures)
18- [Equality treats Collections as Values](#equality-treats-collections-as-values)
19- [Batching Mutations](#batching-mutations)
20- [Lazy Seq](#lazy-seq)
21- [Additional Tools and Resources](#additional-tools-and-resources)
22- [Contributing](#contributing)
23
24## Introduction
25
26[Immutable][] data cannot be changed once created, leading to much simpler
27application development, no defensive copying, and enabling advanced memoization
28and change detection techniques with simple logic. [Persistent][] data presents
29a mutative API which does not update the data in-place, but instead always
30yields new updated data.
31
32Immutable.js provides many Persistent Immutable data structures including:
33`List`, `Stack`, `Map`, `OrderedMap`, `Set`, `OrderedSet` and `Record`.
34
35These data structures are highly efficient on modern JavaScript VMs by using
36structural sharing via [hash maps tries][] and [vector tries][] as popularized
37by Clojure and Scala, minimizing the need to copy or cache data.
38
39Immutable.js also provides a lazy `Seq`, allowing efficient
40chaining of collection methods like `map` and `filter` without creating
41intermediate representations. Create some `Seq` with `Range` and `Repeat`.
42
43Want to hear more? Watch the presentation about Immutable.js:
44
45[![Immutable Data and React](website/public/Immutable-Data-and-React-YouTube.png)](https://youtu.be/I7IdS-PbEgI)
46
47[README.md]: https://github.com/immutable-js/immutable-js/blob/main/README.md
48[immutable.d.ts]: https://github.com/immutable-js/immutable-js/blob/main/type-definitions/immutable.d.ts
49[wiki]: https://github.com/immutable-js/immutable-js/wiki
50[issue]: https://github.com/immutable-js/immutable-js/issues
51[Persistent]: https://en.wikipedia.org/wiki/Persistent_data_structure
52[Immutable]: https://en.wikipedia.org/wiki/Immutable_object
53[hash maps tries]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie
54[vector tries]: https://hypirion.com/musings/understanding-persistent-vector-pt-1
55
56## Getting started
57
58Install `immutable` using npm.
59
60```shell
61# using npm
62npm install immutable
63
64# using Yarn
65yarn add immutable
66
67# using pnpm
68pnpm add immutable
69
70# using Bun
71bun add immutable
72```
73
74Then require it into any module.
75
76<!-- runkit:activate -->
77
78```js
79const { Map } = require('immutable');
80const map1 = Map({ a: 1, b: 2, c: 3 });
81const map2 = map1.set('b', 50);
82map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50
83```
84
85### Browser
86
87Immutable.js has no dependencies, which makes it predictable to include in a Browser.
88
89It's highly recommended to use a module bundler like [webpack](https://webpack.js.org/),
90[rollup](https://rollupjs.org/), or
91[browserify](https://browserify.org/). The `immutable` npm module works
92without any additional consideration. All examples throughout the documentation
93will assume use of this kind of tool.
94
95Alternatively, Immutable.js may be directly included as a script tag. Download
96or link to a CDN such as [CDNJS](https://cdnjs.com/libraries/immutable)
97or [jsDelivr](https://www.jsdelivr.com/package/npm/immutable).
98
99Use a script tag to directly add `Immutable` to the global scope:
100
101```html
102<script src="immutable.min.js"></script>
103<script>
104 var map1 = Immutable.Map({ a: 1, b: 2, c: 3 });
105 var map2 = map1.set('b', 50);
106 map1.get('b'); // 2
107 map2.get('b'); // 50
108</script>
109```
110
111Or use an AMD-style loader (such as [RequireJS](https://requirejs.org/)):
112
113```js
114require(['./immutable.min.js'], function (Immutable) {
115 var map1 = Immutable.Map({ a: 1, b: 2, c: 3 });
116 var map2 = map1.set('b', 50);
117 map1.get('b'); // 2
118 map2.get('b'); // 50
119});
120```
121
122### Flow & TypeScript
123
124Use these Immutable collections and sequences as you would use native
125collections in your [Flowtype](https://flowtype.org/) or [TypeScript](https://typescriptlang.org) programs while still taking
126advantage of type generics, error detection, and auto-complete in your IDE.
127
128Installing `immutable` via npm brings with it type definitions for Flow (v0.55.0 or higher)
129and TypeScript (v2.1.0 or higher), so you shouldn't need to do anything at all!
130
131#### Using TypeScript with Immutable.js v4
132
133Immutable.js type definitions embrace ES2015. While Immutable.js itself supports
134legacy browsers and environments, its type definitions require TypeScript's 2015
135lib. Include either `"target": "es2015"` or `"lib": "es2015"` in your
136`tsconfig.json`, or provide `--target es2015` or `--lib es2015` to the
137`tsc` command.
138
139<!-- runkit:activate -->
140
141```js
142const { Map } = require('immutable');
143const map1 = Map({ a: 1, b: 2, c: 3 });
144const map2 = map1.set('b', 50);
145map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50
146```
147
148#### Using TypeScript with Immutable.js v3 and earlier:
149
150Previous versions of Immutable.js include a reference file which you can include
151via relative path to the type definitions at the top of your file.
152
153```js
154///<reference path='./node_modules/immutable/dist/immutable.d.ts'/>
155import { Map } from 'immutable';
156var map1: Map<string, number>;
157map1 = Map({ a: 1, b: 2, c: 3 });
158var map2 = map1.set('b', 50);
159map1.get('b'); // 2
160map2.get('b'); // 50
161```
162
163## The case for Immutability
164
165Much of what makes application development difficult is tracking mutation and
166maintaining state. Developing with immutable data encourages you to think
167differently about how data flows through your application.
168
169Subscribing to data events throughout your application creates a huge overhead of
170book-keeping which can hurt performance, sometimes dramatically, and creates
171opportunities for areas of your application to get out of sync with each other
172due to easy to make programmer error. Since immutable data never changes,
173subscribing to changes throughout the model is a dead-end and new data can only
174ever be passed from above.
175
176This model of data flow aligns well with the architecture of [React][]
177and especially well with an application designed using the ideas of [Flux][].
178
179When data is passed from above rather than being subscribed to, and you're only
180interested in doing work when something has changed, you can use equality.
181
182Immutable collections should be treated as _values_ rather than _objects_. While
183objects represent some thing which could change over time, a value represents
184the state of that thing at a particular instance of time. This principle is most
185important to understanding the appropriate use of immutable data. In order to
186treat Immutable.js collections as values, it's important to use the
187`Immutable.is()` function or `.equals()` method to determine _value equality_
188instead of the `===` operator which determines object _reference identity_.
189
190<!-- runkit:activate -->
191
192```js
193const { Map } = require('immutable');
194const map1 = Map({ a: 1, b: 2, c: 3 });
195const map2 = Map({ a: 1, b: 2, c: 3 });
196map1.equals(map2); // true
197map1 === map2; // false
198```
199
200Note: As a performance optimization Immutable.js attempts to return the existing
201collection when an operation would result in an identical collection, allowing
202for using `===` reference equality to determine if something definitely has not
203changed. This can be extremely useful when used within a memoization function
204which would prefer to re-run the function if a deeper equality check could
205potentially be more costly. The `===` equality check is also used internally by
206`Immutable.is` and `.equals()` as a performance optimization.
207
208<!-- runkit:activate -->
209
210```js
211const { Map } = require('immutable');
212const map1 = Map({ a: 1, b: 2, c: 3 });
213const map2 = map1.set('b', 2); // Set to same value
214map1 === map2; // true
215```
216
217If an object is immutable, it can be "copied" simply by making another reference
218to it instead of copying the entire object. Because a reference is much smaller
219than the object itself, this results in memory savings and a potential boost in
220execution speed for programs which rely on copies (such as an undo-stack).
221
222<!-- runkit:activate -->
223
224```js
225const { Map } = require('immutable');
226const map = Map({ a: 1, b: 2, c: 3 });
227const mapCopy = map; // Look, "copies" are free!
228```
229
230[React]: https://reactjs.org/
231[Flux]: https://facebook.github.io/flux/docs/in-depth-overview/
232
233
234## JavaScript-first API
235
236While Immutable.js is inspired by Clojure, Scala, Haskell and other functional
237programming environments, it's designed to bring these powerful concepts to
238JavaScript, and therefore has an Object-Oriented API that closely mirrors that
239of [ES2015][] [Array][], [Map][], and [Set][].
240
241[es2015]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla
242[array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
243[map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
244[set]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
245
246The difference for the immutable collections is that methods which would mutate
247the collection, like `push`, `set`, `unshift` or `splice`, instead return a new
248immutable collection. Methods which return new arrays, like `slice` or `concat`,
249instead return new immutable collections.
250
251<!-- runkit:activate -->
252
253```js
254const { List } = require('immutable');
255const list1 = List([1, 2]);
256const list2 = list1.push(3, 4, 5);
257const list3 = list2.unshift(0);
258const list4 = list1.concat(list2, list3);
259assert.equal(list1.size, 2);
260assert.equal(list2.size, 5);
261assert.equal(list3.size, 6);
262assert.equal(list4.size, 13);
263assert.equal(list4.get(0), 1);
264```
265
266Almost all of the methods on [Array][] will be found in similar form on
267`Immutable.List`, those of [Map][] found on `Immutable.Map`, and those of [Set][]
268found on `Immutable.Set`, including collection operations like `forEach()`
269and `map()`.
270
271<!-- runkit:activate -->
272
273```js
274const { Map } = require('immutable');
275const alpha = Map({ a: 1, b: 2, c: 3, d: 4 });
276alpha.map((v, k) => k.toUpperCase()).join();
277// 'A,B,C,D'
278```
279
280### Convert from raw JavaScript objects and arrays.
281
282Designed to inter-operate with your existing JavaScript, Immutable.js
283accepts plain JavaScript Arrays and Objects anywhere a method expects a
284`Collection`.
285
286<!-- runkit:activate -->
287
288```js
289const { Map, List } = require('immutable');
290const map1 = Map({ a: 1, b: 2, c: 3, d: 4 });
291const map2 = Map({ c: 10, a: 20, t: 30 });
292const obj = { d: 100, o: 200, g: 300 };
293const map3 = map1.merge(map2, obj);
294// Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 }
295const list1 = List([1, 2, 3]);
296const list2 = List([4, 5, 6]);
297const array = [7, 8, 9];
298const list3 = list1.concat(list2, array);
299// List [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
300```
301
302This is possible because Immutable.js can treat any JavaScript Array or Object
303as a Collection. You can take advantage of this in order to get sophisticated
304collection methods on JavaScript Objects, which otherwise have a very sparse
305native API. Because Seq evaluates lazily and does not cache intermediate
306results, these operations can be extremely efficient.
307
308<!-- runkit:activate -->
309
310```js
311const { Seq } = require('immutable');
312const myObject = { a: 1, b: 2, c: 3 };
313Seq(myObject)
314 .map(x => x * x)
315 .toObject();
316// { a: 1, b: 4, c: 9 }
317```
318
319Keep in mind, when using JS objects to construct Immutable Maps, that
320JavaScript Object properties are always strings, even if written in a quote-less
321shorthand, while Immutable Maps accept keys of any type.
322
323<!-- runkit:activate -->
324
325```js
326const { fromJS } = require('immutable');
327
328const obj = { 1: 'one' };
329console.log(Object.keys(obj)); // [ "1" ]
330console.log(obj['1'], obj[1]); // "one", "one"
331
332const map = fromJS(obj);
333console.log(map.get('1'), map.get(1)); // "one", undefined
334```
335
336Property access for JavaScript Objects first converts the key to a string, but
337since Immutable Map keys can be of any type the argument to `get()` is
338not altered.
339
340### Converts back to raw JavaScript objects.
341
342All Immutable.js Collections can be converted to plain JavaScript Arrays and
343Objects shallowly with `toArray()` and `toObject()` or deeply with `toJS()`.
344All Immutable Collections also implement `toJSON()` allowing them to be passed
345to `JSON.stringify` directly. They also respect the custom `toJSON()` methods of
346nested objects.
347
348<!-- runkit:activate -->
349
350```js
351const { Map, List } = require('immutable');
352const deep = Map({ a: 1, b: 2, c: List([3, 4, 5]) });
353console.log(deep.toObject()); // { a: 1, b: 2, c: List [ 3, 4, 5 ] }
354console.log(deep.toArray()); // [ 1, 2, List [ 3, 4, 5 ] ]
355console.log(deep.toJS()); // { a: 1, b: 2, c: [ 3, 4, 5 ] }
356JSON.stringify(deep); // '{"a":1,"b":2,"c":[3,4,5]}'
357```
358
359### Embraces ES2015
360
361Immutable.js supports all JavaScript environments, including legacy
362browsers (even IE11). However it also takes advantage of features added to
363JavaScript in [ES2015][], the latest standard version of JavaScript, including
364[Iterators][], [Arrow Functions][], [Classes][], and [Modules][]. It's inspired
365by the native [Map][] and [Set][] collections added to ES2015.
366
367All examples in the Documentation are presented in ES2015. To run in all
368browsers, they need to be translated to ES5.
369
370```js
371// ES2015
372const mapped = foo.map(x => x * x);
373// ES5
374var mapped = foo.map(function (x) {
375 return x * x;
376});
377```
378
379All Immutable.js collections are [Iterable][iterators], which allows them to be
380used anywhere an Iterable is expected, such as when spreading into an Array.
381
382<!-- runkit:activate -->
383
384```js
385const { List } = require('immutable');
386const aList = List([1, 2, 3]);
387const anArray = [0, ...aList, 4, 5]; // [ 0, 1, 2, 3, 4, 5 ]
388```
389
390Note: A Collection is always iterated in the same order, however that order may
391not always be well defined, as is the case for the `Map` and `Set`.
392
393[Iterators]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol
394[Arrow Functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
395[Classes]: https://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes
396[Modules]: https://www.2ality.com/2014/09/es6-modules-final.html
397
398
399## Nested Structures
400
401The collections in Immutable.js are intended to be nested, allowing for deep
402trees of data, similar to JSON.
403
404<!-- runkit:activate -->
405
406```js
407const { fromJS } = require('immutable');
408const nested = fromJS({ a: { b: { c: [3, 4, 5] } } });
409// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } }
410```
411
412A few power-tools allow for reading and operating on nested data. The
413most useful are `mergeDeep`, `getIn`, `setIn`, and `updateIn`, found on `List`,
414`Map` and `OrderedMap`.
415
416<!-- runkit:activate -->
417
418```js
419const { fromJS } = require('immutable');
420const nested = fromJS({ a: { b: { c: [3, 4, 5] } } });
421
422const nested2 = nested.mergeDeep({ a: { b: { d: 6 } } });
423// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } }
424
425console.log(nested2.getIn(['a', 'b', 'd'])); // 6
426
427const nested3 = nested2.updateIn(['a', 'b', 'd'], value => value + 1);
428console.log(nested3);
429// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }
430
431const nested4 = nested3.updateIn(['a', 'b', 'c'], list => list.push(6));
432// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }
433```
434
435## Equality treats Collections as Values
436
437Immutable.js collections are treated as pure data _values_. Two immutable
438collections are considered _value equal_ (via `.equals()` or `is()`) if they
439represent the same collection of values. This differs from JavaScript's typical
440_reference equal_ (via `===` or `==`) for Objects and Arrays which only
441determines if two variables represent references to the same object instance.
442
443Consider the example below where two identical `Map` instances are not
444_reference equal_ but are _value equal_.
445
446<!-- runkit:activate -->
447
448```js
449// First consider:
450const obj1 = { a: 1, b: 2, c: 3 };
451const obj2 = { a: 1, b: 2, c: 3 };
452obj1 !== obj2; // two different instances are always not equal with ===
453
454const { Map, is } = require('immutable');
455const map1 = Map({ a: 1, b: 2, c: 3 });
456const map2 = Map({ a: 1, b: 2, c: 3 });
457map1 !== map2; // two different instances are not reference-equal
458map1.equals(map2); // but are value-equal if they have the same values
459is(map1, map2); // alternatively can use the is() function
460```
461
462Value equality allows Immutable.js collections to be used as keys in Maps or
463values in Sets, and retrieved with different but equivalent collections:
464
465<!-- runkit:activate -->
466
467```js
468const { Map, Set } = require('immutable');
469const map1 = Map({ a: 1, b: 2, c: 3 });
470const map2 = Map({ a: 1, b: 2, c: 3 });
471const set = Set().add(map1);
472set.has(map2); // true because these are value-equal
473```
474
475Note: `is()` uses the same measure of equality as [Object.is][] for scalar
476strings and numbers, but uses value equality for Immutable collections,
477determining if both are immutable and all keys and values are equal
478using the same measure of equality.
479
480[object.is]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
481
482#### Performance tradeoffs
483
484While value equality is useful in many circumstances, it has different
485performance characteristics than reference equality. Understanding these
486tradeoffs may help you decide which to use in each case, especially when used
487to memoize some operation.
488
489When comparing two collections, value equality may require considering every
490item in each collection, on an `O(N)` time complexity. For large collections of
491values, this could become a costly operation. Though if the two are not equal
492and hardly similar, the inequality is determined very quickly. In contrast, when
493comparing two collections with reference equality, only the initial references
494to memory need to be compared which is not based on the size of the collections,
495which has an `O(1)` time complexity. Checking reference equality is always very
496fast, however just because two collections are not reference-equal does not rule
497out the possibility that they may be value-equal.
498
499#### Return self on no-op optimization
500
501When possible, Immutable.js avoids creating new objects for updates where no
502change in _value_ occurred, to allow for efficient _reference equality_ checking
503to quickly determine if no change occurred.
504
505<!-- runkit:activate -->
506
507```js
508const { Map } = require('immutable');
509const originalMap = Map({ a: 1, b: 2, c: 3 });
510const updatedMap = originalMap.set('b', 2);
511updatedMap === originalMap; // No-op .set() returned the original reference.
512```
513
514However updates which do result in a change will return a new reference. Each
515of these operations occur independently, so two similar updates will not return
516the same reference:
517
518<!-- runkit:activate -->
519
520```js
521const { Map } = require('immutable');
522const originalMap = Map({ a: 1, b: 2, c: 3 });
523const updatedMap = originalMap.set('b', 1000);
524// New instance, leaving the original immutable.
525updatedMap !== originalMap;
526const anotherUpdatedMap = originalMap.set('b', 1000);
527// Despite both the results of the same operation, each created a new reference.
528anotherUpdatedMap !== updatedMap;
529// However the two are value equal.
530anotherUpdatedMap.equals(updatedMap);
531```
532
533## Batching Mutations
534
535> If a tree falls in the woods, does it make a sound?
536>
537> If a pure function mutates some local data in order to produce an immutable
538> return value, is that ok?
539>
540> — Rich Hickey, Clojure
541
542Applying a mutation to create a new immutable object results in some overhead,
543which can add up to a minor performance penalty. If you need to apply a series
544of mutations locally before returning, Immutable.js gives you the ability to
545create a temporary mutable (transient) copy of a collection and apply a batch of
546mutations in a performant manner by using `withMutations`. In fact, this is
547exactly how Immutable.js applies complex mutations itself.
548
549As an example, building `list2` results in the creation of 1, not 3, new
550immutable Lists.
551
552<!-- runkit:activate -->
553
554```js
555const { List } = require('immutable');
556const list1 = List([1, 2, 3]);
557const list2 = list1.withMutations(function (list) {
558 list.push(4).push(5).push(6);
559});
560assert.equal(list1.size, 3);
561assert.equal(list2.size, 6);
562```
563
564Note: Immutable.js also provides `asMutable` and `asImmutable`, but only
565encourages their use when `withMutations` will not suffice. Use caution to not
566return a mutable copy, which could result in undesired behavior.
567
568_Important!_: Only a select few methods can be used in `withMutations` including
569`set`, `push` and `pop`. These methods can be applied directly against a
570persistent data-structure where other methods like `map`, `filter`, `sort`,
571and `splice` will always return new immutable data-structures and never mutate
572a mutable collection.
573
574## Lazy Seq
575
576`Seq` describes a lazy operation, allowing them to efficiently chain
577use of all the higher-order collection methods (such as `map` and `filter`)
578by not creating intermediate collections.
579
580**Seq is immutable** — Once a Seq is created, it cannot be
581changed, appended to, rearranged or otherwise modified. Instead, any mutative
582method called on a `Seq` will return a new `Seq`.
583
584**Seq is lazy** — `Seq` does as little work as necessary to respond to any
585method call. Values are often created during iteration, including implicit
586iteration when reducing or converting to a concrete data structure such as
587a `List` or JavaScript `Array`.
588
589For example, the following performs no work, because the resulting
590`Seq`'s values are never iterated:
591
592```js
593const { Seq } = require('immutable');
594const oddSquares = Seq([1, 2, 3, 4, 5, 6, 7, 8])
595 .filter(x => x % 2 !== 0)
596 .map(x => x * x);
597```
598
599Once the `Seq` is used, it performs only the work necessary. In this
600example, no intermediate arrays are ever created, filter is called three
601times, and map is only called once:
602
603```js
604oddSquares.get(1); // 9
605```
606
607Any collection can be converted to a lazy Seq with `Seq()`.
608
609<!-- runkit:activate -->
610
611```js
612const { Map, Seq } = require('immutable');
613const map = Map({ a: 1, b: 2, c: 3 });
614const lazySeq = Seq(map);
615```
616
617`Seq` allows for the efficient chaining of operations, allowing for the
618expression of logic that can otherwise be very tedious:
619
620```js
621lazySeq
622 .flip()
623 .map(key => key.toUpperCase())
624 .flip();
625// Seq { A: 1, B: 2, C: 3 }
626```
627
628As well as expressing logic that would otherwise seem memory or time
629limited, for example `Range` is a special kind of Lazy sequence.
630
631<!-- runkit:activate -->
632
633```js
634const { Range } = require('immutable');
635Range(1, Infinity)
636 .skip(1000)
637 .map(n => -n)
638 .filter(n => n % 2 === 0)
639 .take(2)
640 .reduce((r, n) => r * n, 1);
641// 1006008
642```
643
644## Comparison of filter(), groupBy(), and partition()
645
646The `filter()`, `groupBy()`, and `partition()` methods are similar in that they
647all divide a collection into parts based on applying a function to each element.
648All three call the predicate or grouping function once for each item in the
649input collection. All three return zero or more collections of the same type as
650their input. The returned collections are always distinct from the input
651(according to `===`), even if the contents are identical.
652
653Of these methods, `filter()` is the only one that is lazy and the only one which
654discards items from the input collection. It is the simplest to use, and the
655fact that it returns exactly one collection makes it easy to combine with other
656methods to form a pipeline of operations.
657
658The `partition()` method is similar to an eager version of `filter()`, but it
659returns two collections; the first contains the items that would have been
660discarded by `filter()`, and the second contains the items that would have been
661kept. It always returns an array of exactly two collections, which can make it
662easier to use than `groupBy()`. Compared to making two separate calls to
663`filter()`, `partition()` makes half as many calls it the predicate passed to
664it.
665
666The `groupBy()` method is a more generalized version of `partition()` that can
667group by an arbitrary function rather than just a predicate. It returns a map
668with zero or more entries, where the keys are the values returned by the
669grouping function, and the values are nonempty collections of the corresponding
670arguments. Although `groupBy()` is more powerful than `partition()`, it can be
671harder to use because it is not always possible predict in advance how many
672entries the returned map will have and what their keys will be.
673
674| Summary | `filter` | `partition` | `groupBy` |
675|:------------------------------|:---------|:------------|:---------------|
676| ease of use | easiest | moderate | hardest |
677| generality | least | moderate | most |
678| laziness | lazy | eager | eager |
679| # of returned sub-collections | 1 | 2 | 0 or more |
680| sub-collections may be empty | yes | yes | no |
681| can discard items | yes | no | no |
682| wrapping container | none | array | Map/OrderedMap |
683
684## Additional Tools and Resources
685
686- [Atom-store](https://github.com/jameshopkins/atom-store/)
687 - A Clojure-inspired atom implementation in Javascript with configurability
688 for external persistance.
689
690- [Chai Immutable](https://github.com/astorije/chai-immutable)
691 - If you are using the [Chai Assertion Library](https://chaijs.com/), this
692 provides a set of assertions to use against Immutable.js collections.
693
694- [Fantasy-land](https://github.com/fantasyland/fantasy-land)
695 - Specification for interoperability of common algebraic structures in JavaScript.
696
697- [Immutagen](https://github.com/pelotom/immutagen)
698 - A library for simulating immutable generators in JavaScript.
699
700- [Immutable-cursor](https://github.com/redbadger/immutable-cursor)
701 - Immutable cursors incorporating the Immutable.js interface over
702 Clojure-inspired atom.
703
704- [Immutable-ext](https://github.com/DrBoolean/immutable-ext)
705 - Fantasyland extensions for immutablejs
706
707- [Immutable-js-tools](https://github.com/madeinfree/immutable-js-tools)
708 - Util tools for immutable.js
709
710- [Immutable-Redux](https://github.com/gajus/redux-immutable)
711 - redux-immutable is used to create an equivalent function of Redux
712 combineReducers that works with Immutable.js state.
713
714- [Immutable-Treeutils](https://github.com/lukasbuenger/immutable-treeutils)
715 - Functional tree traversal helpers for ImmutableJS data structures.
716
717- [Irecord](https://github.com/ericelliott/irecord)
718 - An immutable store that exposes an RxJS observable. Great for React.
719
720- [Mudash](https://github.com/brianneisler/mudash)
721 - Lodash wrapper providing Immutable.JS support.
722
723- [React-Immutable-PropTypes](https://github.com/HurricaneJames/react-immutable-proptypes)
724 - PropType validators that work with Immutable.js.
725
726- [Redux-Immutablejs](https://github.com/indexiatech/redux-immutablejs)
727 - Redux Immutable facilities.
728
729- [Rxstate](https://github.com/yamalight/rxstate)
730 - Simple opinionated state management library based on RxJS and Immutable.js.
731
732- [Transit-Immutable-js](https://github.com/glenjamin/transit-immutable-js)
733 - Transit serialisation for Immutable.js.
734 - See also: [Transit-js](https://github.com/cognitect/transit-js)
735
736Have an additional tool designed to work with Immutable.js?
737Submit a PR to add it to this list in alphabetical order.
738
739## Contributing
740
741Use [Github issues](https://github.com/immutable-js/immutable-js/issues) for requests.
742
743We actively welcome pull requests, learn how to [contribute](https://github.com/immutable-js/immutable-js/blob/main/.github/CONTRIBUTING.md).
744
745Immutable.js is maintained within the [Contributor Covenant's Code of Conduct](https://www.contributor-covenant.org/version/2/0/code_of_conduct/).
746
747### Changelog
748
749Changes are tracked as [Github releases](https://github.com/immutable-js/immutable-js/releases).
750
751### License
752
753Immutable.js is [MIT-licensed](./LICENSE).
754
755### Thanks
756
757[Phil Bagwell](https://www.youtube.com/watch?v=K2NYwP90bNs), for his inspiration
758and research in persistent data structures.
759
760[Hugh Jackson](https://github.com/hughfdjackson/), for providing the npm package
761name. If you're looking for his unsupported package, see [this repository](https://github.com/hughfdjackson/immutable).
Note: See TracBrowser for help on using the repository browser.