loopus-lazy v1.3.2
Lazy collections for efficient in-memory data queries
Introduction
When working with in-memory data, a common practice is to use Array
-like objects and chain calls to filter()
, map()
or reduce()
methods.
Problem: each operation in the chain produces a new Array
, causing as many unnecessary copy workloads.
Lazy collections defer evaluation of the chain until the very last moment: when data is iterated.
Operations such as filter()
, map()
or reduce()
do not cause intermediate copy workloads, making the whole chain more efficient.
Basic example
import { Collection } from "loopus-lazy";
const collection = Collection.from([" Hello ", " World! "]) // Use an Array as source - could be any Iterable object
.map((s) => s.trim()) // No operation executed (yet)
.map((s) => s.toLowerCase()) // No operation executed (yet)
.filter((s) => s === "hello" || s === "world!"); // No operation executed (yet)
for (let s of collection) {
// Operations are evaluated here
// hello
// world
}
Get a Collection<T>
object
Collection.from
<T>(iterable: Iterable<T>): Collection<T>
Array
-like methods
concat
(...others: Iterable<T>[]): Collection<T>
every
(callback: Filter<T>): boolean
filter
(callback: Filter<T>): Collection<T>
find
(callback: Filter<T>): T | undefined
includes
(searchElement: T, equalityComparer?: EqualityComparer<T>): boolean
map
<M>(callback: Mapper<T, M>): Collection<M>
reduce
<R>(callback: Reducer<T, R>, initialValue: R): R
some
(callback: Filter<T>): boolean
Comparers
Comparers.default
Comparers.caseInsensitive
Comparers.searchable
EqualityComparers.default
EqualityComparers.caseInsensitive
EqualityComparers.searchable
Grouping
groupBy
<K>(keySelector: Mapper<T, K>): Collection<Group<T, K>>
const values = Collection.from([ { fruit: "Apple", color: "Red", }, { fruit: "Banana", color: "Yellow", }, { fruit: "Cherry", color: "Red", }, { fruit: "Tomato", color: "Red", }, { fruit: "Orange", color: "Orange", }, ]); const result = values .groupBy((x) => x.color) .map((g) => ({ color: g.key, count: g.count() })) // g is a Collection .toArray(); expect(result).toStrictEqual([ { color: "Red", count: 3 }, { color: "Yellow", count: 1 }, { color: "Orange", count: 1 }, ]);
Join & Merge
join
(separator?: string): string
const values = Collection.from(["hello", "world", "!"]); const result = values.join(); expect(result).toBe("hello world !");
mergeMap
<M>(callback: Mapper<T, Iterable<M>>): Collection<M>
const values = Collection.from([ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]); const result = values.mergeMap((x) => x).toArray(); expect(result).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]);
Pagination
skip
(count: number): Collection<T>
take
(count: number): Collection<T>
const pageSize = 25; function getPage<T>(data: Iterable<T>, pageIndex: number): Iterable<T> { return Collection.from(data) .skip(pageIndex * pageSize) .take(pageSize); }
Sorting
orderBy
<K>(keySelector: Selector<T, K>, mode: "asc" | "desc" = "asc", keyComparer?: Comparer<K>): Collection<T>
thenBy
<K>(keySelector: Selector<T, K>, mode: "asc" | "desc" = "asc", keyComparer?: Comparer<K>): Collection<T>
const values = Collection.from([ { firstName: "Tyrell", lastName: "WELLICK", expectedOrder: 3, }, { firstName: "Angela", lastName: "MOSS", expectedOrder: 2, }, { firstName: "Elliot", lastName: "ALDERSON", expectedOrder: 1, }, { firstName: "Darlene", lastName: "ALDERSON", expectedOrder: 0, }, ]); const result = values .orderBy((x) => x.lastName) .thenBy((x) => x.firstName) .map((x) => x.expectedOrder) .toArray(); expect(result).toStrictEqual([0, 1, 2, 3]);
Utils
average
(): number | undefined
count
(): number
first
(): T | undefined
min
(): number | undefined
max
(): number | undefined
sum
(): number
toArray
(): Array<T>