62 lines
1.2 KiB
JavaScript
62 lines
1.2 KiB
JavaScript
/**
|
|
* Utility module to create and manipulate Iterators.
|
|
*
|
|
* @module iterator
|
|
*/
|
|
|
|
/**
|
|
* @template T,R
|
|
* @param {Iterator<T>} iterator
|
|
* @param {function(T):R} f
|
|
* @return {IterableIterator<R>}
|
|
*/
|
|
export const mapIterator = (iterator, f) => ({
|
|
[Symbol.iterator] () {
|
|
return this
|
|
},
|
|
// @ts-ignore
|
|
next () {
|
|
const r = iterator.next()
|
|
return { value: r.done ? undefined : f(r.value), done: r.done }
|
|
}
|
|
})
|
|
|
|
/**
|
|
* @template T
|
|
* @param {function():IteratorResult<T>} next
|
|
* @return {IterableIterator<T>}
|
|
*/
|
|
export const createIterator = next => ({
|
|
/**
|
|
* @return {IterableIterator<T>}
|
|
*/
|
|
[Symbol.iterator] () {
|
|
return this
|
|
},
|
|
// @ts-ignore
|
|
next
|
|
})
|
|
|
|
/**
|
|
* @template T
|
|
* @param {Iterator<T>} iterator
|
|
* @param {function(T):boolean} filter
|
|
*/
|
|
export const iteratorFilter = (iterator, filter) => createIterator(() => {
|
|
let res
|
|
do {
|
|
res = iterator.next()
|
|
} while (!res.done && !filter(res.value))
|
|
return res
|
|
})
|
|
|
|
/**
|
|
* @template T,M
|
|
* @param {Iterator<T>} iterator
|
|
* @param {function(T):M} fmap
|
|
*/
|
|
export const iteratorMap = (iterator, fmap) => createIterator(() => {
|
|
const { done, value } = iterator.next()
|
|
return { done, value: done ? undefined : fmap(value) }
|
|
})
|