JavaScript:折叠无限流(生成器函数)

标签 javascript ecmascript-6 functional-programming stream generator

在 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/

相关文章:

javascript - 为什么 CodePen 和 Chrome 的传播运算符有不同的结果?

Javascript在try block 内设置const变量

scala - 做某事最多 N 次或直到在 Scala 中满足条件

javascript - jquery使用匹配相同顺序的json填充选择选项

javascript - 在 Jquery 中查找与选择器速度

javascript - 使用导出函数编写 javascript 解构时出现语法错误

java - Java 中的 TotallyLazy 函数代码

java - 清理Java8中的数据列表

javascript - 检查所有在 wamp 中不起作用的复选框

javascript - 始终在文本后面附加 svg 图标