Iterable Utilities
Functions to work with Iterables.
#
createIterablecreateIterable(function) => Iterable
Makes an Iterable
from a provided function. It could be a generator or a factory, but must return a new Iterator
every time.
const iterable = createIterable(function* () { while (true) yield Math.random();});
const [x, y] = iterable;const [z] = iterable;
// x === 0.6486486024235587// y === 0.3952175724953333// z === 0.8863071830215743
#
getIteratorgetIterator(iterable) => Iterator
Calls the Symbol.iterator
method of the iterable
for you.
const iterator = getIterator(`undercut`);
// Iterator {}
iterator.next();
// {value: "u", done: false}
#
getRecursiveMappergetRecursiveMapper(predicate, mapper) => Mapper
Creates a mapper function to use with the map
operation. Converts every incomming item into an Iterable of all nested bubitems. The predicate
helps to choose if the item should be iterated. The mapper
, if specified, allows to convert the item before checking it with the predicate
and iterating over it.
#
headhead(Iterable) => item
Returns the first item of the iterable
or undefined
.
const firstLetter = head(`undercut`);
// "u"
const firstItem = head([3, 2, 1]);
// 3
#
headTailheadTail(Iterable) => { head, tail }
Returns an object with the head
(the first item, if it exists) and the tail
(an iterator for remaining items, if there are some).
Missing tail
tells that the iterable
is empty and there is no head
value.
const htString = headTail(`undercut`);
// {head: "u", tail: Iterator}
const htArray = headTail([3, 2, 1]);
// {head: 3, tail: Iterator}
Having a tail
wich is an Iterator used to get remaining items allows you to check if there really was a head:
const noHead = head([]);
// undefined
const obscureHead = head([undefined]);
// undefined
const noHeadTail = headTail([]);
// {head: undefined, tail: undefined}
const obscureHeadTail = headTail([undefined]);
// {head: undefined, tail: Iterator}
Notice that in case of an empty iterable
there is no tail, but in case of an iterable
with more than 0 items there is a tail. This happens because of how Iterators work: you don't know if there is another item until you get done
set to true
, so you need to call next
one more time.
You may also use this for writing loops:
let head = undefined;let tail = [1, 2, 3];
// While there is a tail, split it into a head and a tail.while (({ head, tail } = headTail(tail)).tail) { console.log(head);}
// 1// 2// 3
#
tailtail(Iterable) => Iterator
Returns the tail
(an iterator for remaining items) of the iterable
. In case of an empty iterable
returns undefined
.
const remaining = tail([3, 2, 1]);
for (const item of remaining) { console.log(item);}
// 2// 1
Notice that you can't use it to check if there are multiple items. Iterators work this way that you need to call next
one more time to look into second done
flag.