1.3.2 • Published 2 years ago

loopus-lazy v1.3.2

Weekly downloads
-
License
-
Repository
-
Last release
2 years ago

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>
1.3.2

2 years ago

1.3.1

2 years ago

1.3.0

2 years ago

1.2.0

2 years ago

1.1.0

2 years ago

1.0.0

2 years ago

0.3.0

2 years ago

0.2.0

2 years ago

0.1.0

2 years ago