I'm studying how to use generator in JavaScript.
Since generator returns iterator, I thought I could use it like iterable.filter()
like array.prototype.filter
.
But, iterable object does not have filter, map, forEach, reduce method.
So, I made a generator version of filter, map, reduce, forEach method like the below.
My current code
'use strict';
function* range(n) {
for (let i = 1; i <= n; i++) {
yield i;
}
}
function* filter(context, predicate) {
for (let i of context) {
if (predicate(i) === true) {
yield i;
}
}
}
function isEven(value) {
return value % 2 === 0;
}
console.log(
...filter(range(10), isEven)
);
This code does work, but rather than filter(range(10), isEven)
, I want to use it like range(10).filter(isEven)
.
Is there any way to accomplish what I want?
I was looking into ES6 Proxy, Reflect, but hmm... I'm not sure if these ES6 things help me.
How I want to use
range(10)
.filter(isEven) //generator version of filter
.map(multiplyBy5) //generator version of map
.forEach(console.log); //generator version of forEach
Another Try - Nah... hahaha...
This code works as well, but this is like a joke...
'use strict';
function* filter(predicate) {
for (let i of this) {
if(predicate(i) === true) {
yield i;
}
}
}
function* map(project) {
for (let i of this) {
yield project(i);
}
}
function* range(end) {
for (let i = 0; i <= end; i++) {
yield i;
}
}
const isEven = (v) => v % 2 === 0;
const multiplyBy = (v) => (by) => v * by;
var range10_filterByEven = filter.bind(range(10), isEven);
var range10_filterByEven_multiplyBy10 = map.bind(range10_filterByEven(), multiplyBy(10));
console.log(
...range10_filterByEven_multiplyBy10() //0 20 40 60 80 100
);
Looks better although this is not how I want it to be.
'use strict';
function filter(predicate) {
return function* f() {
for (let i of this) {
if(predicate(i) === true) {
yield i;
}
}
}
}
function map(project) {
return function* m() {
for (let i of this) {
yield project(i);
}
}
}
function range(end) {
return function* r() {
for (let i = 0; i <= end; i++) {
yield i;
}
}
}
const isEven = (v) => v % 2 === 0;
const multiplyBy = (v) => (by) => v * by;
function pipe() {
return [...arguments].reduce(function(chain, current) {
return current.bind(chain());
})}
console.log(
...pipe(
range(10),
filter(isEven),
map(multiplyBy(10))
)()
);