Skip to content

Commit c515b61

Browse files
committed
start Seq
1 parent d213b3b commit c515b61

File tree

2 files changed

+397
-2
lines changed

2 files changed

+397
-2
lines changed

website/docs/Seq.mdx

Lines changed: 393 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,393 @@
1+
import Repl from '@/repl/Repl.tsx';
2+
import CodeLink from '@/mdx-components/CodeLink.tsx';
3+
4+
# Seq
5+
6+
`Seq` describes a lazy operation, allowing them to efficiently chain
7+
use of all the higher-order collection methods (such as <CodeLink to="map" /> and <CodeLink to="filter" />)
8+
by not creating intermediate collections.
9+
10+
<Signature code={`type Seq<K, V> extends Collection<K, V>`} />
11+
12+
**Seq is immutable** — Once a Seq is created, it cannot be
13+
changed, appended to, rearranged or otherwise modified. Instead, any
14+
mutative method called on a `Seq` will return a new `Seq`.
15+
16+
**Seq is lazy**`Seq` does as little work as necessary to respond to any
17+
method call. Values are often created during iteration, including implicit
18+
iteration when reducing or converting to a concrete data structure such as
19+
a <CodeLink to="../List" /> or JavaScript [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).
20+
21+
For example, the following performs no work, because the resulting
22+
`Seq`'s values are never iterated:
23+
24+
```js
25+
import { Seq } from 'immutable';
26+
const oddSquares = Seq([1, 2, 3, 4, 5, 6, 7, 8])
27+
.filter((x) => x % 2 !== 0)
28+
.map((x) => x * x);
29+
```
30+
31+
Once the `Seq` is used, it performs only the work necessary. In this
32+
example, no intermediate arrays are ever created, filter is called three
33+
times, and map is only called once:
34+
35+
```js
36+
oddSquares.get(1); // 9
37+
```
38+
39+
Any collection can be converted to a lazy Seq with `Seq()`.
40+
41+
```js
42+
import { Map } from 'immutable';
43+
44+
const map = Map({ a: 1, b: 2, c: 3 });
45+
const lazySeq = Seq(map);
46+
```
47+
48+
`Seq` allows for the efficient chaining of operations, allowing for the
49+
expression of logic that can otherwise be very tedious:
50+
51+
```js
52+
lazySeq
53+
.flip()
54+
.map((key) => key.toUpperCase())
55+
.flip();
56+
// Seq { A: 1, B: 1, C: 1 }
57+
```
58+
59+
As well as expressing logic that would otherwise seem memory or time
60+
limited, for example `Range` is a special kind of Lazy sequence.
61+
62+
<Repl
63+
defaultValue={`Range(1, Infinity)
64+
.skip(1000)
65+
.map((n) => -n)
66+
.filter((n) => n % 2 === 0)
67+
.take(2)
68+
.reduce((r, n) => r * n, 1);
69+
`}
70+
/>
71+
72+
Seq is often used to provide a rich collection API to JavaScript Object.
73+
74+
<Repl
75+
defaultValue={`Seq({ x: 0, y: 1, z: 2 })
76+
.map((v) => v * 2)
77+
.toObject();`}
78+
/>
79+
80+
## Construction
81+
82+
<MemberLabel label="Seq()" />
83+
84+
Creates a Seq.
85+
86+
<Signature
87+
code={`function Seq<S extends Seq>(seq: S): S;
88+
function Seq(collection: Collection.Keyed<K, V>): Seq.Keyed<K, V>;
89+
function Seq(collection: Collection.Set<T>): Seq.Set<T>;
90+
function Seq(collection: Collection.Indexed<T> | Iterable<T> | ArrayLike<T>): Seq.Indexed<T>;
91+
function Seq(obj: { [key: string]: V }): Seq.Keyed<string, V>;`}
92+
/>
93+
94+
Returns a particular kind of `Seq` based on the input.
95+
96+
* If a `Seq`, that same `Seq`.
97+
* If an `Collection`, a `Seq` of the same kind (Keyed, Indexed, or Set).
98+
* If an Array-like, an `Seq.Indexed`.
99+
* If an Iterable Object, an `Seq.Indexed`.
100+
* If an Object, a `Seq.Keyed`.
101+
102+
Note: An Iterator itself will be treated as an object, becoming a `Seq.Keyed`,
103+
which is usually not what you want. You should turn your Iterator Object into
104+
an iterable object by defining a Symbol.iterator (or @@iterator) method which
105+
returns `this`.
106+
107+
Note: `Seq` is a conversion function and not a class, and does not use the
108+
`new` keyword during construction.
109+
110+
## Static methods
111+
112+
<MemberLabel label="isSeq()" />
113+
114+
<Signature
115+
code={`function isSeq(maybeSeq: unknown): maybeSeq is Seq.Indexed | Seq.Keyed | Seq.Set;`}
116+
/>
117+
118+
## Members
119+
120+
<MemberLabel label="size" />
121+
122+
Some Seqs can describe their size lazily. When this is the case,
123+
size will be an integer. Otherwise it will be undefined.
124+
125+
<Signature code={`readonly size: number | undefined;`} />
126+
127+
For example, Seqs returned from <CodeLink to="map" /> or <CodeLink to="reverse" />
128+
preserve the size of the original `Seq` while <CodeLink to="filter" /> does not.
129+
130+
Note: <CodeLink to="../Range()" />,
131+
132+
<CodeLink to="../Repeat()" /> and `Seq`s made from
133+
<CodeLink to="../List" />s and <CodeLink to="../Map" />s will always have a
134+
size.
135+
136+
## Force evaluation
137+
138+
<MemberLabel label="cacheResult()" />
139+
140+
Because Sequences are lazy and designed to be chained together, they do
141+
not cache their results. For example, this <CodeLink to="map" /> function is called a total
142+
of 6 times, as each `join` iterates the `Seq` of three values.
143+
144+
<Signature code={`cacheResult(): this;`} />
145+
146+
```js
147+
var squares = Seq([1, 2, 3]).map((x) => x * x);
148+
squares.join() + squares.join();
149+
```
150+
151+
If you know a `Seq` will be used multiple times, it may be more
152+
efficient to first cache it in memory. Here, the <CodeLink to="map" /> function is called
153+
only 3 times.
154+
155+
```js
156+
var squares = Seq([1, 2, 3])
157+
.map((x) => x * x)
158+
.cacheResult();
159+
squares.join() + squares.join();
160+
```
161+
162+
Use this method judiciously, as it must fully evaluate a `Seq` which can be
163+
a burden on memory and possibly performance.
164+
165+
Note: after calling <CodeLink to="cacheResult" />, a `Seq` will always have a `size`.
166+
167+
## Sequence algorithms
168+
169+
<MemberLabel label="map()" />
170+
171+
Returns a new `Seq` with values passed through a
172+
`mapper` function.
173+
174+
<Signature
175+
code={`map<M>(mapper: (value: V, key: K, iter: this) => M, context?: unknown): Seq<K, M>;`}
176+
/>
177+
178+
<Repl defaultValue={`Seq([1, 2]).map((x) => 10 * x);`} />
179+
180+
Note: <CodeLink to="map" /> always returns a new instance, even if it produced the same
181+
value at every step.
182+
Note: used only for sets.
183+
184+
<MemberLabel label="flatMap()" />
185+
186+
Flat-maps the `Seq`, returning a `Seq` of the same type.
187+
188+
<Signature
189+
code={`flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: unknown): Seq<K, M>;`}
190+
/>
191+
192+
Similar to <CodeLink to="map" />(...).<CodeLink to="flatten" />(true).
193+
194+
Note: Used only for sets.
195+
196+
<MemberLabel label="filter()" />
197+
198+
Returns a new `Seq` with only the values for which the `predicate`
199+
function returns true.
200+
201+
<Signature
202+
code={`filter(predicate: (value: V, key: K, iter: this) => unknown, context?: unknown): this;`}
203+
/>
204+
205+
Note: <CodeLink to="filter" /> always returns a new instance, even if it results in
206+
not filtering out any values.
207+
208+
<MemberLabel label="partition()" />
209+
210+
Returns a new `Seq` with the values for which the `predicate` function returns false and another for which is returns true.
211+
212+
<Signature
213+
code={`partition<F extends V>(
214+
predicate: (this, value: V, key: K, iter) => value is F,
215+
context
216+
): [Seq<K, V>, Seq<K, F>];`}
217+
/>
218+
219+
<MemberLabel label="concat()" />
220+
221+
Returns a new `Seq` of the same type with other values and collection-like concatenated to this one.
222+
223+
<Signature code={`concat(...valuesOrCollections): Seq;`} />
224+
225+
All entries will be present in the resulting `Seq`, even if they have the same key.
226+
227+
<MemberLabel label="filterNot()" />
228+
229+
<MemberLabel label="reverse()" />
230+
231+
<MemberLabel label="sort()" />
232+
233+
<MemberLabel label="sortBy()" />
234+
235+
<MemberLabel label="groupBy()" />
236+
237+
## Value equality
238+
239+
<MemberLabel label="equals()" />
240+
241+
<MemberLabel label="hashCode()" />
242+
243+
## Reading values
244+
245+
<MemberLabel label="get()" />
246+
247+
<MemberLabel label="has()" />
248+
249+
<MemberLabel label="includes()" />
250+
251+
<MemberLabel label="first()" />
252+
253+
<MemberLabel label="last()" />
254+
255+
## Reading deep values
256+
257+
<MemberLabel label="getIn()" />
258+
259+
<MemberLabel label="hasIn()" />
260+
261+
## Persistent changes
262+
263+
<MemberLabel label="update()" />
264+
265+
## Conversion to JavaScript types
266+
267+
<MemberLabel label="toJS()" />
268+
269+
<MemberLabel label="toJSON()" />
270+
271+
<MemberLabel label="toArray()" />
272+
273+
<MemberLabel label="toObject()" />
274+
275+
## Conversion to Collections
276+
277+
<MemberLabel label="toMap()" />
278+
279+
<MemberLabel label="toOrderedMap()" />
280+
281+
<MemberLabel label="toSet()" />
282+
283+
<MemberLabel label="toOrderedSet()" />
284+
285+
<MemberLabel label="toList()" />
286+
287+
<MemberLabel label="toStack()" />
288+
289+
## Conversion to Seq
290+
291+
<MemberLabel label="toSeq()" />
292+
293+
<MemberLabel label="toKeyedSeq()" />
294+
295+
<MemberLabel label="toIndexedSeq()" />
296+
297+
<MemberLabel label="toSetSeq()" />
298+
299+
## Iterators
300+
301+
<MemberLabel label="keys()" />
302+
303+
<MemberLabel label="values()" />
304+
305+
<MemberLabel label="entries()" />
306+
307+
## Collections (Seq)
308+
309+
<MemberLabel label="keySeq()" />
310+
311+
<MemberLabel label="valueSeq()" />
312+
313+
<MemberLabel label="entrySeq()" />
314+
315+
## Side effects
316+
317+
<MemberLabel label="forEach()" />
318+
319+
## Creating subsets
320+
321+
<MemberLabel label="slice()" />
322+
323+
<MemberLabel label="rest()" />
324+
325+
<MemberLabel label="butLast()" />
326+
327+
<MemberLabel label="skip()" />
328+
329+
<MemberLabel label="skipLast()" />
330+
331+
<MemberLabel label="skipWhile()" />
332+
333+
<MemberLabel label="skipUntil()" />
334+
335+
<MemberLabel label="take()" />
336+
337+
<MemberLabel label="takeLast()" />
338+
339+
<MemberLabel label="takeWhile" />
340+
341+
<MemberLabel label="takeUntil()" />
342+
343+
## Combination
344+
345+
<MemberLabel label="flatten()" />
346+
347+
<MemberLabel label="reduce()" />
348+
349+
<MemberLabel label="reduceRight()" />
350+
351+
<MemberLabel label="every()" />
352+
353+
<MemberLabel label="some()" />
354+
355+
<MemberLabel label="join()" />
356+
357+
<MemberLabel label="isEmpty()" />
358+
359+
<MemberLabel label="count()" />
360+
361+
<MemberLabel label="countBy()" />
362+
363+
## Search for value
364+
365+
<MemberLabel label="find()" />
366+
367+
<MemberLabel label="findLast()" />
368+
369+
<MemberLabel label="findEntry()" />
370+
371+
<MemberLabel label="findLastEntry()" />
372+
373+
<MemberLabel label="findKey()" />
374+
375+
<MemberLabel label="findLastKey()" />
376+
377+
<MemberLabel label="keyOf()" />
378+
379+
<MemberLabel label="lastKeyOf()" />
380+
381+
<MemberLabel label="max()" />
382+
383+
<MemberLabel label="maxBy()" />
384+
385+
<MemberLabel label="min()" />
386+
387+
<MemberLabel label="minBy()" />
388+
389+
## Comparison
390+
391+
<MemberLabel label="isSubset()" />
392+
393+
<MemberLabel label="isSuperset()" />

0 commit comments

Comments
 (0)