Iterator 为什么生成器不支持map()?
在我看来,生成器(其功能非常类似于数组)应该支持非常基本的列表操作,如Iterator 为什么生成器不支持map()?,iterator,generator,ecmascript-6,map-function,Iterator,Generator,Ecmascript 6,Map Function,在我看来,生成器(其功能非常类似于数组)应该支持非常基本的列表操作,如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) y
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中看到迭代器的转换器:-)
生成器,其功能非常类似于阵列
否,请停止并区分迭代器和生成器:
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;
}
- 迭代器是具有符合迭代器协议的
方法的对象.next()
- 生成器是由生成器函数(
)创建的迭代器。它的函数*
方法接受一个参数,该参数是生成器函数中每个.next()
的结果。它还有yield
和.return()
方法.throw()
下一个
,也不关心最终结果,就像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;
};
这些应该足以满足最开始和最常见的用例。一个合适的库可以将其扩展到生成器,以便适当地传递值,还可以解决迭代器在耗尽之前只能使用一次的问题(与数组不同)。区分生成器和迭代器就像区分贵宾犬和狗一样——贵宾犬就是狗,虽然不是所有的狗都是卷毛狗。与犬科动物的情况相反,不是生成器的迭代器古怪且难以使用,因此我将兴趣限制在生成器上(以及通过
for..of
语法进行访问)不应该是生成器函数。@Malvolio:事实上,生成器比日常迭代器更古怪,更难使用。您很少遇到它们-所有[Symbol.iterator]
方法都返回迭代器,而不是生成器。通过的访问发电机不会使用其全部功率。