Utility Methods for Iterables
class LazySeq<T>
A class-wrapper around iterables
The LazySeq<T>
class stores an iterable
of type T
and provides a number of methods to transform the iterable.
The general format for data manipulation is to start with some data in
a data structure such as an array, object, HashMap, etc. Create a new
LazySeq chain starting from the initial data, call various transformation
methods to map, group, filter, aggregate the data, and finally terminate the
chain by converting back to a data structure. Because most of the transformation
methods are lazy, the new terminating data structure can be built directly from the
transformed data in one pass.
Static Creation Methods
Creates a new LazySeq from any Iterable
Creates a new LazySeq from any iterator
Like the iterator protocol, the iterator function is called each time the LazySeq is iterated. Typically, you would use zero-argument generator function to create the iterator.
Example
const oddNums = LazySeq.ofIterator(function* () {
for (let i = 1; i < 10; i += 2) {
yield i;
}
});
Creates a new LazySeq from the keys and values of an object
Only the own properties of the object are included.
Creates a new LazySeq of numbers with a given start, end, and step
The range is inclusive of the start and exclusive of the end. The step defaults to 1 and can be negative. Note there is no infinite loop prevention, so make sure the step is not zero.
Transformation
Iterates the entries in the LazySeq
This is the default iteration when using for .. of
directly on the LazySeq
.
𝑜𝑏𝑗.aggregate<K, S>(
key: (x: T) => K & JsMapKey,
val: (x: T) => S,
combine: (s1: S, s2: S) => S
): LazySeq<readonly [K, S]>
Strictly combines entries which map to the same key
aggregate
strictly transforms each entry in the LazySeq using the provided
key
and val
functions. Entries which map to the same key are then combined
with the combine
function. Internally, this uses a javascript Map so the keys
must be strings or numbers.
For more complex keys, use instead LazySeq.toHashMap, LazySeq.buildHashMap, LazySeq.toOrderedMap, or LazySeq.buildOrderedMap.
Lazily appends the given value to the end of the LazySeq
Lazily splits the LazySeq into chunks of the given size
Each chunk except the final chunk will have exactly size
entries.
Lazily adds the specified iterable to the end of the LazySeq
In other words, when iterated the resulting LazySeq will first yield the
entries in the input LazySeq and then the entries in the iterable passed into concat
.
Example
const nums = LazySeq.of([1, 2, 3]).concat([4, 5, 6]);
for (const x of nums) {
console.log(x);
});
// the above prints 1, 2, 3, 4, 5, 6
Strictly calculates only the distinct entries in the LazySeq
Internally, this uses a javascript Set so the entries must be strings or numbers. For more complex entries, use instead LazySeq.distinctBy, LazySeq.toHashSet or LazySeq.toOrderedSet.
Strictly calculates only the entries with distinct properties in the LazySeq
This method is given one or more property-extraction functions. distinctBy
then
calculates the distinct entries in the LazySeq based on the tuple of those properties
using a HashMap internally, so properties must be ToHashable.
distinctBy
and LazySeq.toHashMap are very similar; the main difference is that when
you have multiple properties you want to use, distinctBy
internally handles creating a
custom key tuple.
See also LazySeq.distinctAndSortBy if you want to sort the entries by the properties.
Strictly calculates only the entries with distinct properties in the LazySeq and yields them in sorted order
This method is given one or more property-extraction functions. distinctAndSortBy
then
inserts them internally into a OrderedMap and yields them in ascending order.
Thus, all properties must implement ToComparable.
distinctAndSortBy
and LazySeq.toOrderedMap are very similar; the main difference is that when
you have multiple properties you want to use, distinctAndSortBy
internally handles creating a
custom key tuple.
Lazily skips over a given number of entries in the LazySeq
When the resulting LazySeq is iterated, the first n
entries will be skipped. If n
is
larger than the total number of entries, the resulting LazySeq will be empty.
Lazily skips over entries until the specified predicate is false
When the resulting LazySeq is iterated, each entry is passed to the predicate function. If an entry returns true, it is skipped. If an entry returns false, it is yielded and from then on the remainder of the entries are yielded unchanged. Thus, only the initial prefix of entries for which the predicate returns true are skipped.
Lazily filters the entries in the LazySeq to be only those returning true from a predicate function
This type signature using a type predicate to allow the correct type after filtering to be inferred.
Example
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
const animals: LazySeq<Fish | Bird> = LazySeq.of([sunfish, penguin, goldfish, albatross]);
const fish = animals.filter(isFish); // the type will be correctly inferred to be LazySeq<Fish>
Lazily filters the entries in the LazySeq to be only those returning true from a predicate function
Lazily map each entry to multiple values and flatten all the resulting values into a single sequence
𝑜𝑏𝑗.groupBy<PropFn extends ToHashable<T>, PropFns extends ToHashable<T>[]>(
propFn: PropFn,
...fs: PropFns
): LazySeq<[TupleOfHashProps<T, [PropFn, ...PropFns]>, ReadonlyArray<T>]>
Strictly group the values by one or more properties and yield the resulting groups
groupBy
takes one or more property-extraction functions and groups the values by the
tuple of these properties. For each tuple of properties, all values which have the same
tuple are combined into an array. Internally, this uses a HashMap so
the resulting groups appear in any order and thus properties must be hashable.
Use LazySeq.orderedGroupBy if the properties can only be compared but not hashed.
This function is very similar to LazySeq.toLookup, but the main advantage of groupBy
is that you do not need to create a custom key class for a tuple of multiple properties.
The TupleOfHashProps
type is a helper type which extracts the type of each property and creates
a tuple of those types.
Example
const seq = LazySeq.of([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
const groups = seq.groupBy(x => x % 2, x => x % 3);
// groups will consist of the following
// the first element of each group is the tuple of [x % 2, x % 3] and the second is the array of values
// [ [0, 0], [6, 12] ]
// [ [0, 1], [4, 10] ]
// [ [0, 2], [2, 8] ]
// [ [1, 0], [3, 9] ]
// [ [1, 1], [1, 7] ]
// [ [1, 2], [5, 11] ]
𝑜𝑏𝑗.orderedGroupBy<PropFn extends ToComparable<T>, PropFns extends ToComparable<T>[]>(
propfn: PropFn,
...fns: PropFns
): LazySeq<[TupleOfCmpProps<T, [PropFn, ...PropFns]>, ReadonlyArray<T>]>
Strictly group the values by one or more properties and yield the resulting groups
orderedGroupBy
takes one or more property-extraction functions and groups the values by the
tuple of these properties. For each tuple of properties, all values which have the same
tuple are combined into an array. Internally, this uses an OrderedMap so
the resulting groups will appear in ascending order of key.
This function is very similar to LazySeq.toOrderedLookup, but the main advantage of orderedGroupBy
is that you do not need to create a custom key class for a tuple of multiple properties.
The TupleOfCmpProps
type is a helper type which extracts the type of each property and creates
a tuple of those types.
Lazily apply a function to each entry in a LazySeq
Each element of the LazySeq is applied to the provided function f
, along with
the zero-based index of the element.
Lazily apply a function to each entry in a LazySeq and only include those which are not null or undefined
Each element of the LazySeq is applied to the provided function f
. If the result is not null or
undefined, it is included in the resulting LazySeq.
Lazily prepend the given value to the beginning of the LazySeq
Lazily adds the specified iterable to the beginning of the LazySeq
In other words, when iterated the resulting LazySeq will first yield the
entries in the iterable passed to prependAll
and then after that yield the
entries in the LazySeq.
Strictly sort the values in the LazySeq using the provided comparison function
This produces a new sorted LazySeq and thus is intended to be used in the middle of a chain of transformations. If you want to terminate the LazySeq into a sorted data structure, use LazySeq.toSortedArray or LazySeq.toOrderedMap.
Strictly sort the values in the LazySeq by the provided properties
sortBy
takes one or more property-extraction functions. The values are applied to each property-extraction
function and then sorted by the tuple of resulting properties.
This produces a new sorted LazySeq and thus is intended to be used in the middle of a chain of
transformations. If you want to terminate the LazySeq into a sorted data structure, use
LazySeq.toSortedArray or LazySeq.toOrderedMap.
Lazily create a LazySeq which iterates all but the first entry
If the LazySeq is empty, the resulting LazySeq will also be empty. If the LazySeq is not empty, all but the first entry will be included in the resulting LazySeq.
Example
const s = LazySeq.of([1, 2, 3, 4, 5]);
for (const x of s.tail()) {
console.log(x);
}
// prints 2, 3, 4, 5
Lazily take the initial specified number of entries in the LazySeq and ignore the rest
When the resulting LazySeq is iterated, the first n
entries will be yielded. If n
is
larger than the total number of entries, the entire LazySeq will be yielded. Any entries
beyond the first n
will be ignored.
Lazily takes entries while the specified predicate is true
When the resulting LazySeq is iterated, each entry is passed to the predicate function. If an entry returns true, it is yielded. As soon as an entry returns false, it is not yielded and no more entries are processed.
Lazily combine the LazySeq with an iterable entry by entry into tuples of size 2
Both the LazySeq and the iterable are jointly iterated element-by-element. The elements are combined into a tuple of size 2. As soon as one of the iterators is exhausted, the iteration ends and any remaining elements in the other iterator are ignored.
Example
const s1 = LazySeq.of([1, 2, 3]);
const s2 = LazySeq.of(['a', 'b', 'c']);
const s3 = s1.zip(s2);
for (const [x, y] of s3) {
console.log(x, y);
}
// prints 3 lines:
// 1 a
// 2 b
// 3 c
Query
Check if all entries in the LazySeq return true from the provided function
If the LazySeq is empty, this function returns true.
Check if any entry in the LazySeq return true from the provided function
If the LazySeq is empty, this function returns false.
Returns true if the LazySeq is empty
Search for an entry which returns true when provided to f
.
If found, the element is returned. Otherwise, undefined
is returned.
Returns the first entry of the LazySeq or undefined if the LazySeq is empty.
Returns the length of the LazySeq
Returns the maximum value in the LazySeq
If the LazySeq is empty, undefined
is returned. Otherwise, each function passed to maxBy
is applied to each entry in the LazySeq and the entry with the maximum value is returned.
Returns the minimum value in the LazySeq
If the LazySeq is empty, undefined
is returned. Otherwise, each function passed to minBy
is applied to each entry in the LazySeq and the entry with the minimum value is returned.
Sums up the entries in the LazySeq
Applies the passed function to each entry in the LazySeq and sums up the results. If the LazySeq is empty, 0 is returned.
Conversion
Converts the LazySeq to a readonly array
Converts the LazySeq to an Array
In the spirit of immutability, you should prefer LazySeq.toRArray which returns a readonly array.
𝑜𝑏𝑗.toSortedArray(
prop: ToComparable<T>,
...props: ReadonlyArray<ToComparable<T>>
): ReadonlyArray<T>
Sorts the entries in the LazySeq and returns a readonly array
The entries are sorted by the properties returned by the passed functions.
𝑜𝑏𝑗.toHashMap<K, S extends NotUndefined>(
f: (x: T) => readonly [K & HashKey, S],
merge?: (v1: S, v2: S) => S
): HashMap<K & HashKey, S>
Converts the entries in the LazySeq to a HashMap
This is a convenience function for HashMap.from which creates a HashMap from a function which converts the entries in the LazySeq to a tuple of a key and a value. When a duplicate key is found, the provided merge function is used to determine the value; see the docs for HashMap.from for details. If you don't wish to merge values, LazySeq.toLookup and LazySeq.toLookupMap keep all the duplicate values.
Converts the entries in the LazySeq to a HashMap
This is a convenience function for HashMap.build which creates a HashMap from a key extraction function. With duplicate keys, the later value is used. See the docs for HashMap.build for details. If you don't wish to overwrite values, LazySeq.toLookup and LazySeq.toLookupMap keep all the duplicate values.
𝑜𝑏𝑗.buildHashMap<K, S extends NotUndefined>(
key: (x: T) => K & HashKey,
val: (old: S | undefined, t: T) => S
): HashMap<K & HashKey, S>
Converts the entries in the LazySeq to a HashMap
This is a convenience function for HashMap.build which creates a HashMap from a key extraction function and a value extraction function. See the docs for HashMap.build for details. If you don't wish to merge values, LazySeq.toLookup and LazySeq.toLookupMap keep all the duplicate values.
𝑜𝑏𝑗.toOrderedMap<K, S extends NotUndefined>(
f: (x: T) => readonly [K & OrderedMapKey, S],
merge?: (v1: S, v2: S) => S
): OrderedMap<K & OrderedMapKey, S>
Converts the entries in the LazySeq to an OrderedMap
This is a convenience function for OrderedMap.from which creates an OrderedMap from a function which converts the entries in the LazySeq to a tuple of a key and a value. When a duplicate key is found, the provided merge function is used to determine the value; see the docs for OrderedMap.from for details. If you don't wish to overwrite values, LazySeq.toOrderedLookup and LazySeq.toOrderedLookup keep all the duplicate values.
Converts the entries in the LazySeq to an OrderedMap
This is a convenience function for OrderedMap.build which creates an OrderedMap from a key extraction function. When a duplicate key is found, the value is overwritten with the later value. See the docs for OrderedMap.build for details. If you don't wish to overwrite values, LazySeq.toOrderedLookup and LazySeq.toLookupOrderedMap keep all the duplicate values.
𝑜𝑏𝑗.buildOrderedMap<K, S extends NotUndefined>(
key: (x: T) => K & OrderedMapKey,
val: (old: S | undefined, t: T) => S
): OrderedMap<K & OrderedMapKey, S>
Converts the entries in the LazySeq to an OrderedMap
This is a convenience function for OrderedMap.build which creates an OrderedMap from a key extraction function and a value extraction function. See the docs for OrderedMap.build for details. If you don't wish to merge values, LazySeq.toOrderedLookup and LazySeq.toLookupOrderedMap keep all the duplicate values.
𝑜𝑏𝑗.toRMap<K, S>(
f: (x: T) => readonly [K & JsMapKey, S],
merge?: (v1: S, v2: S) => S
): ReadonlyMap<K, S>
Converts the entries of the LazySeq to a readonly JS Map
This function builds a JS Map from the entries in the LazySeq. Each entry in the LazySeq is convered to a tuple of key and value using the provided function. If a duplicate key is found, the provided merge function is called to determine the value for the key. If no merge function is provided, the last value for the key is used. If you don't wish to merge values, LazySeq.toRLookup keeps all the duplicate values.
𝑜𝑏𝑗.toMutableMap<K, S>(
f: (x: T) => readonly [K & JsMapKey, S],
merge?: (v1: S, v2: S) => S
): Map<K, S>
Converts the entries of the LazySeq to a JS Map
This function builds a JS Map from the entries in the LazySeq. Each entry in the LazySeq is convered to a tuple of key and value using the provided function. If a duplicate key is found, the provided merge function is called to determine the value for the key. If no merge function is provided, the last value for the key is used.
In the spirit of immutability, LazySeq.toRMap is preferred over this function unless neccisary.
𝑜𝑏𝑗.toObject<S>(
f: (x: T) => readonly [string, S],
merge?: (v1: S, v2: S) => S
): { [key: string]: S }
Converts the entries of the LazySeq to a JS Object
This function builds a javascript object from the entries in the LazySeq. Each entry in the LazySeq is convered to a tuple of key and value using the provided function. If a duplicate key is found, the provided merge function is called to determine the value for the key. If no merge function is provided, the last value for the key is used.
𝑜𝑏𝑗.toObject<S>(
f: (x: T) => readonly [number, S],
merge?: (v1: S, v2: S) => S
): { [key: number]: S }
Converts the entries of the LazySeq to a JS Object
This function builds a javascript object from the entries in the LazySeq. Each entry in the LazySeq is convered to a tuple of key and value using the provided function. If a duplicate key is found, the provided merge function is called to determine the value for the key. If no merge function is provided, the last value for the key is used.
Converts the entries in the LazySeq to a HashSet
This is a convenience function for HashSet.build which creates a HashSet from a function which converts the entries in the LazySeq to a hashable value.
Converts the entries in the LazySeq to an OrderedSet
This is a convenience function for OrderedSet.build which creates an OrderedSet from a function which converts the entries in the LazySeq to an orderable value.
Converts the entries in the LazySeq to a JS Set
toRSet
converts the entries in the LazySeq to a readonly
JS Set.
Converts the entries in the LazySeq to a JS Set
toRSet
converts the entries in the LazySeq to a mutable
JS Set.
In the spirit of immutability, LazySeq.toRSet is preferred over this function unless neccisary.
Reduce all the entries in the LazySeq to a single value
fold
reduces all the entries in the LazySeq to a single value using the provided function. The function
combines elements in order from the LazySeq, with the first element being combined with the zero value, and
then the result of that combination is combined with the second element, and so on.
Reduce all the entries in the LazySeq to a single value
reduce
works the same as Array.reduce.
When given with no initial value, the accumulator is initialized to the first element of the LazySeq and the combining function
is called starting with the second value. An error is thrown if the LazySeq is empty.
Reduce all the entries in the LazySeq to a single value
reduce
works the same as Array.reduce
and when givin an initial value is the same as LazySeq.fold. The initial value is combined with the first element, the result
of that combination is combined with the second element, and so on.
Apply a function to the LazySeq
Applies the provided function f
to this
and returns the result. This is a convenience function
which allows you to continue to chain operations without having to create a new
temporary variable.
Grouping
Group entries in the LazySeq by a key, returning a HashMap with an array of values
The key function is used to extract a key for each entry and then entries are grouped by a key. All the values that have the same key are collected into an array and returned in a HashMap.
𝑜𝑏𝑗.toLookup<K, S>(
key: (x: T) => K & HashKey,
val: (x: T) => S
): HashMap<K & HashKey, ReadonlyArray<S>>
Group entries in the LazySeq by a key, returning a HashMap with an array of values
Each element in the LazySeq is converted to a key and a value using the provided functions. The keys are used to group the values into an array and the result is returned in a HashMap.
𝑜𝑏𝑗.toOrderedLookup<K>(
key: (x: T) => K & OrderedMapKey
): OrderedMap<K & OrderedMapKey, ReadonlyArray<T>>
Group entries in the LazySeq by a key, returning an OrderedMap with an array of values
The key function is used to extract a key for each entry and then entries are grouped by a key. All the values that have the same key are collected into an array and returned in an OrderedMap.
𝑜𝑏𝑗.toOrderedLookup<K, S>(
key: (x: T) => K & OrderedMapKey,
val: (x: T) => S
): OrderedMap<K & OrderedMapKey, ReadonlyArray<S>>
Group entries in the LazySeq by a key, returning an OrderedMap with an array of values
Each element in the LazySeq is converted to a key and a value using the provided functions. The keys are used to group the values into an array and the result is returned in an OrderedMap.
𝑜𝑏𝑗.toLookupMap<K1, K2>(
key1: (x: T) => K1 & HashKey,
key2: (x: T) => K2 & HashKey
): HashMap<K1 & HashKey, HashMap<K2 & HashKey, T>>
Group entries in the LazySeq by two keys, returning a HashMap of HashMaps
All entries in the LazySeq are first grouped by key1
. For each key1
, all the values that share the same key1
are then grouped by key2
. Entries with the same key1
and key2
overwrite previous entries with the same keys
(see the more general toLookupMap
for a version with a merge function). The result is a HashMap of
HashMaps.
𝑜𝑏𝑗.toLookupMap<K1, K2, S extends NotUndefined>(
key1: (x: T) => K1 & HashKey,
key2: (x: T) => K2 & HashKey,
val: (x: T) => S,
mergeVals?: (v1: S, v2: S) => S
): HashMap<K1 & HashKey, HashMap<K2 & HashKey, S>>
Group entries in the LazySeq by two keys, returning a HashMap of HashMaps
All entries in the LazySeq are passed to the provided functions to extract a key1
, key2
, and value.
They are then first grouped by key1
. For each key1
, all the values that share the same key1
are then grouped by key2
. Entries with the same key1
and key2
are either merged using the mergeVals
function
if it is provided, otherwise values later in the LazySeq overwrite previous values with the same keys.
The result is a HashMap of HashMaps.
𝑜𝑏𝑗.toLookupOrderedMap<K1, K2>(
key1: (x: T) => K1 & OrderedMapKey,
key2: (x: T) => K2 & OrderedMapKey
): OrderedMap<K1 & OrderedMapKey, OrderedMap<K2 & OrderedMapKey, T>>
Group entries in the LazySeq by two keys, returning an OrderedMap of OrderedMaps
All entries in the LazySeq are first grouped by key1
. For each key1
, all the values that share the same key1
are then grouped by key2
. Entries with the same key1
and key2
overwrite previous entries with the same keys
(see the more general toLookupOrderedMap
for a version with a merge function). The result is an OrderedMap of
OrderedMaps.
𝑜𝑏𝑗.toLookupOrderedMap<K1, K2, S>(
key1: (x: T) => K1 & OrderedMapKey,
key2: (x: T) => K2 & OrderedMapKey,
val: (x: T) => S,
mergeVals?: (v1: S, v2: S) => S
): OrderedMap<K1 & OrderedMapKey, OrderedMap<K2 & OrderedMapKey, S>>
Group entries in the LazySeq by two keys, returning an OrderedMap of OrderedMaps
All entries in the LazySeq are passed to the provided functions to extract a key1
, key2
, and value.
They are then first grouped by key1
. For each key1
, all the values that share the same key1
are then grouped by key2
. Entries with the same key1
and key2
are either merged using the mergeVals
function
if it is provided, otherwise values later in the LazySeq overwrite previous values with the same keys.
The result is a OrderedMap of OrderedMaps.
Group entries in the LazySeq by a key, returning a Javascript Map with an array of values
The key function is used to extract a key for each entry and then entries are grouped by a key. All the values that have the same key are collected into an array and returned in an JS Map.
Group entries in the LazySeq by a key, returning a Javascript Map with an array of values
Each element in the LazySeq is converted to a key and a value using the provided functions. The keys are used to group the values into an array and the result is returned in an JS Map.