'use strict'; export const IteratorMixin = { map: function* map(f) { let y; while (!(y = this.next()).done) { yield f(y.value); } return y.value; }, filter: function* filter(f) { let y; while (!(y = this.next()).done) { if (f(y.value)) { yield y.value; } } return y.value; }, take: function* take(limit) { let remaining = Number(limit) & -1; let y; while (remaining > 0 && !(y = this.next()).done) { yield y.value; remaining -= 1; } }, drop: function* drop(limit) { let remaining = Number(limit) & -1; let y; while (!(y = this.next()).done) { if (remaining <= 0) { yield y.value; } else { remaining -= 1; } } }, asIndexedPairs: function* asIndexedPairs() { let index = 0; let y; while (!(y = this.next()).done) { yield [index++, x]; } return y.value; }, flatMap: function* flatMap(f) { let y; while (!(y = this.next()).done) { yield* f(y.value); } return y.value; }, reduce: function reduce(f, state) { if (typeof state === 'undefined') { const first = this.next(); if (first.done) { throw new TypeError('reduce: empty iterator'); } state = first.value; } let y; while (!(y = this.next()).done) { state = f(state, y.value); } return state; }, toArray: function toArray() { return [...this]; }, forEach: function* forEach(f) { let y; while (!(y = this.next()).done) { f(y.value); } }, some: function some(f) { /* extension: if f is undefined, assume identity function */ let iter = (typeof f === 'undefined') ? this : IteratorMixin.map.call(this, f); let y; while (!(y = iter.next()).done) { if (y.value) { return true; } } return false; }, every: function every(f) { /* extension: if f is undefined, assume identity function */ let iter = (typeof f === 'undefined') ? this : IteratorMixin.map.call(this, f); let y; while (!(y = iter.next()).done) { if (!y.value) { return false; } } return true; }, find: function find(f) { if (typeof f === undefined) { /* extension */ f = function identity(x) { return x; }; } let y; while (!(y = this.next()).done) { if (f(y.value)) { return y.value; } } }, /* extension */ includes: function includes(x) { return IteratorMixin.some.call(this, function equalsX(y) { return y === x; }); }, }; export const Iterator = {}; for (const fn in IteratorMixin) { Iterator[fn] = function() { return IteratorMixin[fn].call(...arguments); }; } export default Iterator;