@mathscapes/iterflow
v1.0.0-rc1
Published
Lazy iterator utilities with built-in statistics and windowing for memory-efficient data processing
Downloads
63
Maintainers
Readme
Iterflow
Lazy iterators with built-in statistics and windowing. Zero dependencies.
import { iter } from '@mathscapes/iterflow';
// Rolling average of stock prices
const prices = [100, 102, 101, 105, 107, 110];
iter(prices)
.window(5)
.map(w => iter(w).mean())
.toArray();
// Process millions of records with constant memory
function* hugeDataset() {
for (let i = 0; i < 1000000; i++) {
yield { valid: i % 2 === 0, value: i };
}
}
iter(hugeDataset())
.filter(x => x.valid)
.map(x => x.value)
.take(1000)
.sum();Install
npm install @mathscapes/iterflowWhy?
Native arrays are eager. Native Iterator Helpers (ES2025) add lazy ops, but no statistics or windowing.
API Reference
Factory Function
iter<T>(src: Iterable<T>): Iterflow<T>Wrap any iterable.
Transform Methods
Transform methods return a new Iterflow<T> and are lazily evaluated. No computation happens until a terminal method is called.
.map<U>(fn: (v: T, i: number) => U): Iterflow<U>Transform each element..filter(fn: (v: T, i: number) => boolean): Iterflow<T>Keep matching elements..flatMap<U>(fn: (v: T, i: number) => Iterable<U>): Iterflow<U>Map and flatten..take(n: number): Iterflow<T>First n elements..drop(n: number): Iterflow<T>Skip first n elements..takeWhile(fn: (v: T, i: number) => boolean): Iterflow<T>Take while predicate is true..dropWhile(fn: (v: T, i: number) => boolean): Iterflow<T>Skip while predicate is true..distinct(): Iterflow<T>Remove duplicates..enumerate(): Iterflow<[number, T]>Yield [index, value] pairs..concat<U>(...others: Iterable<U>[]): Iterflow<T | U>Append iterables..window(size: number): Iterflow<T[]>Sliding windows..chunk(size: number): Iterflow<T[]>Fixed-size chunks.
Terminal Methods
Terminal methods consume the iterator and return concrete values.
.toArray(): T[]Collect to array..reduce<U>(fn: (acc: U, v: T, i: number) => U, init: U): UFold to single value..find(fn: (v: T, i: number) => boolean): T | undefinedFirst matching element..forEach(fn: (v: T, i: number) => void): voidExecute function for each..first(): T | undefinedFirst element..last(): T | undefinedLast element..count(): numberCount elements..some(fn: (v: T, i: number) => boolean): booleanAny match?.every(fn: (v: T, i: number) => boolean): booleanAll match?
Statistical Methods
Statistical methods only work on Iterflow<number> and throw EmptySequenceError on empty sequences.
.sum(): numberSum..mean(): numberArithmetic mean..median(): numberMedian (50th percentile)..min(): numberMinimum..max(): numberMaximum..variance(): numberPopulation variance.
Standalone Functions
import { sum, mean, median, min, max, variance } from '@mathscapes/iterflow';sum(src: Iterable<number>): numbermean(src: Iterable<number>): numbermedian(src: Iterable<number>): numbermin(src: Iterable<number>): numbermax(src: Iterable<number>): numbervariance(src: Iterable<number>): number
Error Classes
IterflowErrorBase error class.EmptySequenceErrorThrown by statistical methods on empty sequences. Hasop: stringproperty.
Type Exports
import type { Predicate, Mapper, Reducer, FlatMapper } from '@mathscapes/iterflow';Predicate<T>=(v: T, i: number) => booleanMapper<T, U>=(v: T, i: number) => UReducer<T, U>=(acc: U, v: T, i: number) => UFlatMapper<T, U>=(v: T, i: number) => Iterable<U>
Utility Functions
isIterable(v: unknown): v is Iterable<unknown>Type guard for iterables.
Benchmarks
Performance benchmarks comparing iterflow against Lodash, iter-ops, RxJS, and native methods are available in the benchmarks/ directory. See benchmarks/README.md for reproduction instructions.
Examples
See the examples/ directory for examples comparing iterflow with native JavaScript, Lodash, and RxJS.
TypeScript
Full type inference. Statistical methods are constrained to Iterflow<number>:
iter(['a', 'b', 'c']).sum() // TypeScript error
iter([1, 2, 3]).sum() // OK: numberLicense
MIT
