window takes a sequence and groups it into "windows" of a certain length. This works well with infinite sequences where you want to process some number of values at a time.
// Grab numbers in groups of 10.
const sequence: Seq<number[]> = Seq.infinite().window(10)
By default, only triggers chained responses when the window fills, guaranteeing the window is the exact size expect. Set allowPartialWindow to false to allow the trailing edge of a sequence to not be divisible by the window size.
tap lets you run side-effect generating functions on a sequence. Allows you to "tap in to" a data flow. Very useful for logging and debugging what values are flowing through the chain at a given location.
type Person = { name: string; friends: Person[] }
const sequence: Seq<Friend> = Seq.fromArray([person1, person2])
.map(person => person.friends)
.flat()
type flat = <U>(this: Seq<U[]>) => Seq<U>
flatMap
flatMap is used when mapping a list to each items related items. For example, if you wanted to map from a list of people to each persons list of friends. Despite each mapping function returning an array, the final output is a flatten array of all the results concattenated.
Similar to [].map().flat(), but in leisure the item mappings won't execute until enough of the resulting values have been realized to trigger each map.
type Person = { name: string; friends: Person[] }
const sequence: Seq<Friend> = Seq.fromArray([person1, person2]).flatMap(
person => person.friends,
)
type distinctBy = <U>(fn: (value: T) => U) => Seq<T>
partitionBy
Given a sequence, splits the values into two separate sequences. One represents the values where the partition function is true and the other for false.
type reduce = <A>(fn: (sum: A, value: T, index: number) => A, initial: A) => A
chain
This method is helpful for chaining. Shocking, I know. Let's you "map" the entire sequence in a chain, rather than per-each-item. Allows adding arbitrary sequence helpers and methods to chain, even if they are written in user-land and not on the Seq prototype.
// Same as `Seq.interpose(Seq.infinite(), Seq.infinite())`
const sequence = Seq.infinite().chain(seq => seq.interpose(Seq.infinite()))
type chain = <U>(fn: (value: Seq<T>) => U) => U
some
Exactly the same as Array.prototype.some, but lazy. See more here.
// Find the first even random number.
const areAnyEven = Seq.random()
.map(num => Math.round(num * 1000))
.some(num => num % 2 === 0)
type some = (fn: (value: T, index: number) => unknown) => boolean
every
Exactly the same as Array.prototype.every, but lazy. See more here.
// Fails fast if there are negative numbers
const areAllPositive = Seq.random()
.map(num => Math.round(num * 1000) - 500)
.every(num => num > 0)
type every = (fn: (value: T, index: number) => unknown) => boolean
take
Given a sequence of unknown length, create a sub sequence of just the first X number of items.
Lazily combines a second sequence with this current one to produce a tuple with the current step in each of the two positions. Useful for zipping a sequence of keys with a sequence of values, before converting to a Map of key to value.
Takes a second sequence and lazily combines it to produce an arbitrary value by mapping the current value of the two positions through a user-supplied function. Useful for table (row/col) math.
type zip2 = <T2, T3>(
seq2: Seq<T2>,
seq3: Seq<T3>,
) => Seq<[T | undefined, T2 | undefined, T3 | undefined]>
zip2With
Takes two sequences and lazily combine them with this sequence to produce an arbitrary value by mapping the current value of the three positions through a user-supplied function.
type averageBy = (fn: (value: T) => number) => number
frequencies
Given a non-infinite sequence, return a Map which counts the occurances of each unique value. This realizes the entire sequence.
// Returns a Map of numbers from 0->100 and how many times they randomly occured in this set of 500.
const freq = Seq.random()
.map(num => Math.round(num * 100))
.take(500)
.frequencies()
type frequencies = () => Map<T, number>
groupBy
Group a sequence by the return of a mapping function. This realizes the entire sequence.
// Random generates 1000 years between 0-2000 and
// groups them by decade.
const groupedByDecade = Seq.random()
.map(num => Math.round(num * 2000))
.take(100)
.groupBy(year => Math.round(year / 10))