2.0.0 • Published 3 years ago

lazy-sequences v2.0.0

Weekly downloads
2
License
MIT
Repository
github
Last release
3 years ago

lazy-sequences

A TypeScript and JavaScript library providing lazy sequences with a "fluent", functional programming friendly API. The purpose is to make it simple and efficient to generate and operate on sequences of potentially infinite elements.

Quick examples

Generation

// Infinite sequence of the numbers 0, 1, 2, ...
const s = Seq.enumFrom(0);
// Infinite sequence of the numbers 1, 2, 4, 8, 16, ...
const s = Seq.iterate(x => 2*x, 1);
// Infinitely repeating cycle of 1, 2, 3, 1, 2, 3, ...
const s = Seq.cycle([1, 2, 3]);

Operations

// Neat and efficient method chaining (the below will only iterate 'sequence' once)
const sumDoubles = sequence
    .map(x => 2 * x)
    .sum()
// Most of the fp collection operations available at the tap of a '.'
const strangeString = sequence
    .filter(str => str.length < 10)
    .map(str => str.toUpperCase())
    .map(str => str.slice(0,4))
    .reduce((accum, str) => accum.concat(str), '');

Installation

$ npm install --save lazy-sequences

Or whatever the equivalent is for your favorite package manager. That should set you up regardless of whether you prefer JS or TS. To actually use the library, you'd typically just:

// Using typescript or some other platform with ES modules
import Seq from 'lazy-sequences';

// Or
import { Seq } from 'lazy-sequences';
// Using node/commonjs style requires
const { Seq } = require('lazy-sequences');

// Or
const S = require('lazy-sequences').default;

Async sequences

In addition to regular lazy sequences, lazy-sequences also provides async lazy sequences. Just like Seq, in some sense, is a fluent/functional wrapper of Iterables, AsyncSeq is kind of a wrapper of AsyncIterable. A quick example:

import AsyncSeq from 'lazy-sequences/Async';
// Or in commonjs:
// const { AsyncSeq } = require('lazy-sequences/Async');

const seq = new AsyncSeq(someAsyncIterable);

// seq2: AsyncSeq<string>
const seq2 = seq
    .map(x => x.foo())
    .map(foo => foo.toString());

// result: boolean
const result = await seq2.any(s => s.indexOf('foo') !== -1);

Note that to use asynchronous sequences you may have to add a shim for Symbol.asyncIterator. If so, it should be defined before importing AsyncSeq. So, something like this in TypeScript:

if (
  typeof (Symbol as any).asyncIterator
    === "undefined"
) {
  (Symbol as any).asyncIterator =
    Symbol.asyncIterator
      || Symbol("asyncIterator");
}

import AsyncSeq from 'lazy-sequences/Async';

Or something like this in JS (assuming commonjs):

if (typeof Symbol.asyncIterator === "undefined") {
    Symbol.asyncIterator = Symbol.asyncIterator || Symbol("asyncIterator");
}

const { AsyncSeq } = require('lazy-sequences/Async');