对我来说,生成器的功能非常类似于数组,应该支持非常基本的列表操作,例如map()
, filter()
, and 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 中看到迭代器的转换器:-)
生成器,其功能非常类似于数组
不,请停下来辨别一下迭代器 from 发电机:
- 迭代器是一个具有
.next()
符合迭代器协议的方法。
- 生成器是由生成器函数创建的迭代器(
function*
). Its .next()
方法接受一个参数,该参数是每个方法的结果yield
在生成器函数内部。它也有.return()
and .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;
};
这些对于开始和最常见的用例来说应该足够了。适当的库会将其扩展到生成器,以便正确地传递值,并且还将处理迭代器在耗尽之前只能使用一次的问题(与数组相反)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)