在 Java 中,可以这样声明和折叠无限流
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]
在 JavaScript 中,我可以使用生成器函数来生成和传播值流。
// 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]
但是我怎样才能流式传输和折叠无限流呢?我知道我可以使用 for (n of generator)
循环迭代和限制流。但是是否可以使用流畅的 API(例如 Java 示例)?
最佳答案
这是给定答案的另一种方法。
1。函数式 API
首先创建一个函数式 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))
);
2。盒型
接下来,定义一个 Box
类型以允许任意功能 API 的方法链接。
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)};
3。方法链
最后,使用新的 Box
类型来链接方法。
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
免费为您提供流畅的 API。
关于JavaScript:折叠无限流(生成器函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54241668/