In Java it is possible to declare and fold infinite streams as so
List<Integer> collect = Stream.iterate(0, i -> i + 2)
.map(i -> i * 3)
.filter(i -> i % 2 == 0)
.limit(10)
.collect(Collectors.toList());
// -> [0, 6, 12, 18, 24]
In JavaScript I could use generator functions to yield and spread stream of values.
// Limit the value in generator
let generator = (function* () {
for (let i=0; i<10; i++) {
yield i
}
})()
[ ...generator ]
.map(i => i * 3)
.filter(i => i % 2 === 0)
// -> [0, 6, 12, 18, 24]
But how could I stream and fold an infinite stream? I know I could iterate and limit the stream with for (n of generator) loop. But is it possible with fluent API such as Java example?
Here is an alternative approach to the given answer.
First create a functional API.
const itFilter = p => function* (ix) {
for (const x of ix)
if (p(x))
yield x;
};
const itMap = f => function* (ix) {
for (const x of ix)
yield f(x);
};
const itTake = n => function* (ix) {
let m = n;
for (const x of ix) {
if (m-- === 0)
break;
yield x;
}
};
const comp3 = f => g => h => x =>
f(g(h(x))); const xs = [1,2,3,4,5,6,7,8,9,10];
const stream = comp3(itTake(3))
(itFilter(x => x % 2 === 0))
(itMap(x => x * 3));
console.log(
Array.from(stream(xs))
);
Next, define a Box type to allow method chaining for arbitrarily functional APIs.
function Box(x) {
return new.target ? (this.x = x, this) : new Box(x)
}
Box.prototype.map = function map(f) {return new Box(f(this.x))};
Box.prototype.fold = function fold(f) {return f(this.x)};
Finally, use the new Box type to chain methods.
const itFilter = p => function* (ix) {
for (const x of ix)
if (p(x))
yield x;
};
const itMap = f => function* (ix) {
for (const x of ix)
yield f(x);
};
const itTake = n => function* (ix) {
let m = n;
for (const x of ix) {
if (m-- === 0)
break;
yield x;
}
};
const xs = [1,2,3,4,5,6,7,8,9,10];
function Box(x) {
return new.target ? (this.x = x, this) : new Box(x)
}
Box.prototype.map = function map(f) {return new Box(f(this.x))};
Box.prototype.fold = function fold(f) {return f(this.x)};
const stream = Box(xs)
.map(itMap(x => x * 3))
.map(itFilter(x => x % 2 === 0))
.map(itTake(3))
.fold(x => x);
console.log(
Array.from(stream)
);
Box gives you a fluent API for free.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With