-
Notifications
You must be signed in to change notification settings - Fork 5
Recipes
Equivalents for frequent operations and well-known operators.
This is only for things not explicitly covered by the API.
You can either use the examples directly, or create Custom Operators from them.
- find (first)
- find (last)
- forEach
- join
- reverse
- slice
-
Border Values -
min
/max
/average
Equivalent to find(condition)
can have several forms...
-
pipe(iterable, first(condition))
- the simplest, and best-performing pipe(iterable, filter(condition), first())
pipe(iterable, filter(condition), take(1))
Equivalent to finding the last matching value:
import {pipe, filter, last} from 'iter-ops';
pipe(iterable, filter(condition), last())
// or even simpler:
pipe(iterable, last(condition))
And if you want N
last matching values:
pipe(iterable, filter(condition), takeLast(N))
Operator tap offers the same logic, to tap into each value, without changing the output.
Strings can be joined like this: aggregate(a => a.join(separator))
, or you can define your own operator:
import {pipe, aggregate} from 'iter-ops';
function join(separator?: string) {
return aggregate(a => a.join(separator));
}
We do not have a dedicated join
operator, because operator aggregate makes it more generic and flexible,
so you can have your own join
operator that handles any type, and not just strings.
If the input is indexed (array-like), then the most efficient way is to use reverse helper on the source:
import {pipe, reverse} from 'iter-ops';
pipe(
reverse(['word']), //=> Iterable<string> => 'd', 'r', 'o', 'w'
// ...operators
)
Otherwise, the reversal is only possible on a complete dataset, so you have to aggregate the values first:
import {pipe, aggregate, spread} from 'iter-ops';
pipe(iterable,
aggregate(arr => arr.reverse()), // aggregate and reverse the entire array
spread() // spread the array
);
For arrays, slice(start, end) can take negative indexes, relative to the end of the array. This is not possible with iterators, which can only go from start till end.
However, for any combination of positive indexes, we can replicate the behavior:
const start = 3, end = 7; // start + end indexes
pipe(iterable, skip(start), take(end - start));
- To produce a
min
value from an iterable of numbers:
import {pipe, reduce} from 'iter-ops';
const input = [3, 0, -2, 5, 9, 4];
const i = pipe(input, reduce((p, c) => p < c ? p : c)); // IterableExt<number>
console.log(i.first); //=> -2
- To produce a
max
value from an iterable of numbers:
import {pipe, reduce} from 'iter-ops';
const input = [3, 0, -2, 5, 9, 4];
const i = pipe(input, reduce((p, c) => p > c ? p : c)); // IterableExt<number>
console.log(i.first); //=> 9
- To produce
min
+max
values in a single iteration:
import {pipe, reduce} from 'iter-ops';
const input = [3, 0, -2, 5, 9, 4];
const i = pipe(input, reduce((p, c) => {
p.min = c < p.min ? c : p.min ?? c;
p.max = c > p.max ? c : p.max ?? c;
return p;
}, {min: undefined as number, max: undefined as number}));
//=> IterableExt<{min: number, max: number}>
console.log(i.first); //=> { min: -2, max: 9 }
It will produce {min: undefined, max: undefined}
when the input is empty.
- To produce an average value from an iterable of numbers:
import {pipe, reduce} from 'iter-ops';
const input = [3, 0, -2, 5, 9, 4];
const i = pipe(input, reduce((p, c, idx, state) => {
state.sum = (state.sum ?? p) + c;
return p && state.sum / (idx + 1);
})); // IterableExt<number>
console.log(i.first); //=> 3.1666(6)
It will produce undefined
when the input is empty.
See also: Custom Operators