A TypeScript iterable utility library providing functional programming utilities for working with iterables as well as a class based interface with an easy chainable and typed API.
npm install it-al- 🔄 Lazy Evaluation - Iterator-based operations are efficient and composable
- 🍛 Currying Support - Most functions support both direct and curried forms
- đź”— Method Chaining - Fluent API via
IterandPeekableIterclasses - 🏷️ Type Safe - Full TypeScript support with proper type inference
- đź§© Functional - Supports composition via
pipeandapply
import { Iter, map, filter, take } from 'it-al';
// Functional style
const result = pipe([
map((x: number) => x * 2),
filter((x: number) => x > 5),
take(3)
])([1, 2, 3, 4, 5, 6]);
// Method chaining style
const result2 = Iter.from([1, 2, 3, 4, 5, 6])
.map(x => x * 2)
.filter(x => x > 5)
.take(3)
.toArray();| Function | Description | Signature |
|---|---|---|
map |
Transform each item in an iterable | <T, U>(iter: Iterable<T>, fn: IterFn<T, U>) => IterableIterator<U> |
filter |
Filter items based on a predicate | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> |
flat |
Flatten nested iterables by depth | <T, D>(iter: Iterable<T>, depth?: D) => IterableIterator<FlatItem<T, D>> |
enumerate |
Return index-value pairs | <T>(iter: Iterable<T>) => IterableIterator<[number, T]> |
pluck |
Extract a property from each item | <T, K>(iter: Iterable<T>, key: K) => IterableIterator<T[K]> |
tap |
Run side effects without modifying items | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> |
scan |
Like reduce but yields intermediate values | <T, U>(iter: Iterable<T>, fn, start?: U) => IterableIterator<U> |
| Function | Description | Signature |
|---|---|---|
take |
Take first n items | <T>(iter: Iterable<T>, n: number) => IterableIterator<T> |
skip |
Skip first n items | <T>(iter: Iterable<T>, n: number) => IterableIterator<T> |
takeWhile |
Take items while predicate is true | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> |
skipWhile |
Skip items while predicate is true | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> |
until |
Take items until predicate is true | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> |
chunk |
Split into chunks of size n | <T>(iter: Iterable<T>, n: number) => IterableIterator<T[]> |
windows |
Create sliding windows of size n | <T>(iter: Iterable<T>, n: number) => IterableIterator<T[]> |
| Function | Description | Signature |
|---|---|---|
reduce |
Reduce to a single value | <T, U>(iter: Iterable<T>, fn, start: U) => U |
sum |
Sum all numbers | (iter: Iterable<number>) => number |
product |
Multiply all numbers | (iter: Iterable<number>) => number |
average |
Average all numbers | (iter: Iterable<number>) => number |
count |
Count items | <T>(iter: Iterable<T>) => number |
join |
Join items into string | <T>(iter: Iterable<T>, delimiter?: string) => string |
groupBy |
Group items by key | <T, U>(iter: Iterable<T>, fn) => Map<U, T[]> |
| Function | Description | Signature |
|---|---|---|
find |
Find first matching item | <T>(iter: Iterable<T>, fn: IterFn<T>) => T | null |
findIndex |
Find index of first match | <T>(iter: Iterable<T>, fn: IterFn<T>) => number |
includes |
Check if value exists | <T>(iter: Iterable<T>, value: T) => boolean |
some |
Test if any item matches | <T>(iter: Iterable<T>, fn: IterFn<T>) => boolean |
every |
Test if all items match | <T>(iter: Iterable<T>, fn: IterFn<T>) => boolean |
first |
Get first item | <T>(iter: Iterable<T>) => T |
last |
Get last item | <T>(iter: Iterable<T>) => T | undefined |
isEmpty |
Check if empty | (iter: Iterable<unknown>) => boolean |
search |
Recursively search object | <U>(obj: unknown, fn) => IterableIterator<KeyValuePair<U>> |
| Function | Description | Signature |
|---|---|---|
uniqueBy |
Get unique items by selector | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> |
partition |
Split into passed/failed arrays | <T>(iter: Iterable<T>, fn: IterFn<T>) => [T[], T[]] |
| Function | Description | Signature |
|---|---|---|
zip |
Combine multiple iterables | <I>(...iters: I, stopOnMin?: boolean) => ZipOutput<I> |
unzip |
Transpose iterable of arrays | <T>(iter: Iterable<T>) => UnzipOutput<T> |
| Function | Description | Signature |
|---|---|---|
range |
Generate range of numbers | (stop: number, start?: number, step?: number) => IterableIterator<number> |
repeat |
Repeat iterable n times | <T>(iter: Iterable<T>, n: number) => IterableIterator<T> |
cycle |
Cycle through iterable infinitely | <T>(iter: Iterable<T>) => IterableIterator<T> |
gen |
Create infinite generator | <T>(fn: (n: number) => T) => () => IterableIterator<T> |
| Function | Description | Signature |
|---|---|---|
entries |
Get key-value pairs | <T>(input: T) => IterableIterator<Entry<T>> |
allEntries |
Get entries including Symbols | <T>(input: T) => IterableIterator<Entry<T>> |
fromEntries |
Create object from entries | <K, V>(iter: Iterable<[K, V]>) => Record<K, V> |
| Function | Description | Signature |
|---|---|---|
pipe |
Compose functions left-to-right | <I, O>(fns: Function[]) => (item: I) => O |
apply |
Apply functions in order | <I, O>(input: I, fns: Function[]) => O |
peekable |
Create peekable iterable | <T>(iter: Iterable<T>) => Peekable<T> |
isIterable |
Check if value is iterable | <T>(x: unknown) => x is Iterable<T> |
isNonStringIterable |
Check iterable (not string) | <T>(x: unknown) => x is Iterable<T> |
isAsyncIterable |
Check if async iterable | <T>(x: unknown) => x is AsyncIterable<T> |
Chainable wrapper around iterables providing a fluent API.
| Method | Description | Return Type |
|---|---|---|
Iter#from(iterable) |
Create an Iter from any iterable | Iter<T> |
Iter#safeFrom(maybeIterable?) |
Create an Iter from unknown input, returns empty Iter if not iterable | Iter<T> |
Iter#fromAsync(iterable) |
Create an Iter from async iterable or promises | Iter<T> |
Iter#fromEntries(obj) |
Create an Iter from object entries | Iter<[K, V]> |
Iter#safeFromEntries(obj?) |
Create an Iter from object entries, returns empty Iter if null/undefined | Iter<[K, V]> |
Iter#fromRange(stop, start?, step?) |
Create an Iter from a numeric range | Iter<number> |
Iter#gen(fn) |
Create infinite Iter using generator function | () => Iter<T> |
Iter#zip(iterables, stopOnMin?) |
Zip multiple iterables into tuples | Iter<[...]> |
Iter#search(obj, fn, skipAfterYield?) |
Recursively search object for matching values | Iter<KeyValuePair<U>> |
Returns a new Iter<T> instance for continued chaining.
| Method | Description |
|---|---|
Iter#flatMap(fn) |
Map and flatten in one step |
Iter#flat(depth?) |
Flatten nested iterables |
Iter#map(fn) |
Transform each item |
Iter#filter(fn) |
Filter items by predicate |
Iter#filterNullish() |
Remove null and undefined values |
Iter#unique() |
Remove duplicate values |
Iter#enumerate() |
Add index to each item as [index, value] |
Iter#uniqueBy(fn) |
Remove duplicates by selector function |
Iter#tap(fn) |
Run side effects without modifying items |
Iter#scan(fn, start?) |
Like reduce but yields intermediate values |
Iter#pluck(key) |
Extract property from each item |
Iter#take(n) |
Take first n items |
Iter#chunk(n) |
Split into chunks of size n |
Iter#skip(n) |
Skip first n items |
Iter#takeWhile(fn) |
Take items while predicate is true |
Iter#skipWhile(fn) |
Skip items while predicate is true |
Iter#until(fn) |
Take items until predicate is true |
Iter#windows(size) |
Create sliding windows of size n |
Iter#apply(fn) |
Apply a function to the iterable |
Iter#peekable() |
Convert to PeekableIter |
Iter#repeat(times) |
Repeat the iterable n times |
Iter#cycle() |
Cycle through iterable infinitely |
Consumes the iterator and returns a final value.
| Method | Description | Return Type |
|---|---|---|
Iter#first() |
Get the first item | T |
Iter#last() |
Get the last item | T | undefined |
Iter#find(fn) |
Find first item matching predicate | T | null |
Iter#findIndex(fn) |
Find index of first match | number |
Iter#includes(value) |
Check if value exists | boolean |
Iter#count() |
Count total items | number |
Iter#isEmpty() |
Check if iterable is empty | boolean |
Iter#forEach(fn) |
Like Array.forEach but for Iter | void |
Iter#reduce(fn, start) |
Reduce to single value | U |
Iter#every(fn) |
Test if all items match predicate | boolean |
Iter#some(fn) |
Test if any item matches predicate | boolean |
Iter#unzip() |
Transpose iterable of arrays | UnzipOutput<T> |
Iter#partition(fn) |
Split into [passed, failed] arrays | [T[], T[]] |
Iter#join(delimiter?) |
Join items into string | string |
Iter#groupBy(fn) |
Group items by key | Map<K, T[]> |
Iter#sum() |
Sum all numbers | number |
Iter#product() |
Multiply all numbers | number |
Iter#average() |
Average all numbers | number |
Iter#min() |
Find minimum value | T |
Iter#max() |
Find maximum value | T |
Iter#collect(collector?) |
Collect using custom collector | U |
Iter#toArray() |
Collect all items into an array | T[] |
Iter#toSet() |
Collect all items into a Set | Set<T> |
Iter#toMap() |
Collect entries into a Map | Map<K, V> |
Extends Iter<T> with the ability to peek at the next value without consuming it.
const iter = PeekableIter.from([1, 2, 3]);
console.log(iter.peek()); // 1 (doesn't consume)
console.log(iter.first()); // 1 (consumes)| Method | Description | Return Type |
|---|---|---|
PeekableIter#peek() |
Look at next value without consuming it | T | undefined |
import { map, filter, pipe } from 'it-al';
// Curried form
const double = map((x: number) => x * 2);
const isPowerOfTwo = filter((x: number) => Math.sqrt(x, 2) % 1 === 0);
const result = pipe([double, isPowerOfTwo])([1, 2, 3, 4]);
// [2, 4, 8]import { Iter } from 'it-al';
const result = Iter.from([1, 2, 3, 4, 5])
.map(x => x * 2)
.filter(x => x > 5)
.take(2)
.toArray();
// [6, 8]import { map, take } from 'it-al';
const expensive = map((x: number) => {
console.log('Processing:', x);
return x * 2;
});
// Only processes first 3 items
const result = take(expensive([1, 2, 3, 4, 5, 6, 7, 8]), 3);
for (const _ of result) {}
// Logs: Processing: 1, 2, 3import { Iter } from 'it-al';
// Generate infinite sequence
const randomNumbers = Iter.gen((n) => Math.random());
// Generates 10 random numbers
const first10 = fibonacci().take(10).toArray();import { Iter } from 'it-al';
const data = [
{ category: 'A', value: 10 },
{ category: 'B', value: 20 },
{ category: 'A', value: 30 },
];
const grouped = Iter.from(data).groupBy(item => item.category);
// Map { 'A' => [{...}, {...}], 'B' => [{...}] }