137 lines
2.9 KiB
JavaScript
137 lines
2.9 KiB
JavaScript
'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;
|