对我来说,非常自然的是,生成器的功能非常类似于数组,应该支持非常基本的列表操作,例如map()
,filter()
和reduce()
。我想念什么吗?
我写了map
的代码,看起来很简单,但是将所有函数嵌入所有生成器中会更好:
let fancyGen = g => {
let rv = function*() {
for (let x of g)
yield x;
}
rv.map = function*(p) {
for (let x of g)
yield p(x);
}
return rv;
}
我是生成器新手,因此欢迎对代码进行任何注释。特别是写“身份生成器”的最佳方法吗?
为什么生成器不支持map()?
因为作为用户区的实现方式填写起来太容易了。 ES3也不包含数组迭代方法,也许会在ES7中看到迭代器的转换器:-)
生成器,其功能非常类似于数组
否,请停止并将迭代器与生成器:
区分开.next()
方法的对象。function*
)创建的迭代器。它的.next()
方法采用一个参数,该参数是生成器函数内部每个yield
的结果。它还具有.return()
和.throw()
方法。您将最感兴趣的是迭代器,我们不将值传递给next
,也不关心最终结果-就像for of
循环一样。我们可以轻松地用所需的方法扩展它们:
var IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
IteratorPrototype.map = function*(f) {
for (var x of this)
yield f(x);
};
IteratorPrototype.filter = function*(p) {
for (var x of this)
if (p(x))
yield x;
};
IteratorPrototype.scan = function*(f, acc) {
for (var x of this)
yield acc = f(acc, x);
return acc;
};
IteratorPrototype.reduce = function(f, acc) {
for (var x of this)
acc = f(acc, x);
return acc;
};
这些应该足够开始,并且是最常见的用例。适当的库会将其扩展到生成器,以便适当地传递值,并且还将解决迭代器在耗尽之前只能使用一次的问题(与数组相反)。
看看https://www.npmjs.com/package/fluent-iterable
它确实满足您的需求。