๐พIterator
extending built-in iterable iterators with methods map(), filter() ...
Last updated
Was this helpful?
extending built-in iterable iterators with methods map(), filter() ...
Last updated
Was this helpful?
JSโฉ iteration โฉ iterator โฉ Iterator (extension)
(deprecated , use Iterable+ext instead)
extending built-in iterable iterators with methods map()
, filter()
...
replit โฉ Iterator (old), Iterator.prototype (new)
// --------------------
// โญ Iterator
// --------------------
// ๐งจ ้ทๅ๏ผ
// โข must use function declaration. (can't use class declaration)
// โข the prototype of a class is unwritableโ
function Iterator() {} // function declaration
// โญ reassign/overwrite prototypeโ๏ธ
// โข prototype of all built-in (iterable) iterators
Iterator.prototype = Object.getPrototypeOf( // IteratorPrototype
Object.getPrototypeOf( // ArrayIteratorPrototype
[][Symbol.iterator]() // Array iterator
)
);
// โญ extending `Iterator.prototype`
// ---------------------------------
// - ๐ธ .filter() -> generator
// - ๐ธ .map() -> generator
// - ๐ธ .take() -> generator
//
// - ๐ธ .every() -> boolean
// - ๐ธ .some() -> boolean
// - ๐ธ .toArray() -> array
// - ๐ธ .forEach() -> (returns `undefined`)
// ๐ธ .filter()
Iterator.prototype.filter = function*(condition) {
for (const value of this) {
if (condition(value)) yield value;
}
};
// ๐ธ .map()
Iterator.prototype.map = function*(f) {
for (const value of this) { yield f(value) }
};
// ๐ธ .take()
// turn "infinite" iterator into "finite"
Iterator.prototype.take = function*(n) {
for (const value of this) {
if (n > 0) {
n -= 1;
yield value;
} else { return }
}
};
// ๐ธ .forEach()
Iterator.prototype.forEach = function(handle) {
for (const value of this) { handle(value) }
};
// ๐ธ .every()
Iterator.prototype.every = function(condition) {
for (const value of this) { if (!condition(value)) return false }
return true;
};
// ๐ธ .some()
Iterator.prototype.some = function(condition) {
for (const value of this) { if (condition(value)) return true }
return false;
};
// ๐ธ .toArray()
Iterator.prototype.toArray = function() {
return [...this];
};
// โญ๏ธ export
module.exports = Iterator;
๐พ replit โฉ Iterator, require๏ผ *integers()
// โญ import
const Iterator = require('./Iterator.js'); // extend iterators
const integers = require('./integers.js'); // infinite generator
// โ
test method chaining:
// Note:
// - each method returns a different generator
// (except for .forEach, which returns `undefined`)
integers() // ๐ generator: 0, 1, 2, ...
.filter(x => x > 0) // ๐ generator: 1, 2, 3, ...
.map(x => x * 2) // ๐ generator: 2, 4, 6, ...
.take(4) // ๐ generator: 2, 4, 6, 8
.forEach(x => console.log(x)) // ๐ console: 2, 4, 6, 8
;
// โญ prototype chain (of a String iterator)
let it = 'abc'[Symbol.iterator](); // iterator of String
let proto1 = Object.getPrototypeOf(it); // StringIteratorPrototype
let proto2 = Object.getPrototypeOf(proto1); // IteratorPrototype
let proto3 = Object.getPrototypeOf(proto2); // Object.prototype
let proto4 = Object.getPrototypeOf(proto3); // null
// log
[
// โญ iterator only iterates onceโ
it.toArray(), // [ 'a', 'b', 'c' ]
it.toArray(), // [] โญ `it` is "exhausted"โ
// โ
test prototype chain
it, // String iterator
it instanceof Iterator, // true
proto1, // StringIteratorPrototype
proto2 === Iterator.prototype, // true
proto3 === Object.prototype, // true
proto4 === null, // true
// โ
test .take()
integers().take(5).toArray(), // [ 0, 1, 2, 3, 4 ]
// โ
test .every(), .some()
integers() // 0, 1, 2, ...
.take(5) // 0, 1, 2, 3, 4
.every(x => x >= 0), // true
integers()
.take(5)
.every(x => x < 3), // false
integers()
.take(5)
.some(x => x < 3), // true
].forEach(x => { console.log(x) });
extended by Iterator
*zip() - zip a list of iterables into a single generator function.
require IteratorPrototype
printPrototypeChain() - print prototype chain of an object.
class โฉ ๐งจ ้ทๅ - can't overwrite class's prototype.
Set.prototype.values() - returns an iterator.
Object.values() - returns an arrayโ๏ธ