为什么生成器不支持map()? [英] Why do generators not support map()?

查看:112
本文介绍了为什么生成器不支持map()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我来说,似乎非常自然,发生器非常像数组,它应该支持非常基本的列表操作,如 map() filter() reduce()。我是否缺少某些东西?



我为地图编写了代码,看起来很简单,但是会很多更好地将所有功能嵌入到所有生成器中:

  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不包括Array迭代方法,也许会在ES7中看到迭代器的变换器: - )


生成器,其功能非常类似数组


不,请停止并区分生成器中的迭代器




  • 迭代器是一个符合迭代器的 .next()方法的对象协议。

  • 生成器是由生成器函数( function * )创建的迭代器。它的 .next()方法接受一个参数,它是生成函数内每个 yield 的结果。它也有 .return() .throw()方法。



    • 您将对迭代器感兴趣,我们不会将值传递给 next ,而不在乎关于最终结果 - 就像 for 循环一样。我们可以轻松地以所需的方法扩展它们:

        var IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([] [Symbol。迭代器]())); 
      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
      };

      这些应该足以开始,最常见的用例。一个正确的库将它扩展到生成器,以便适​​当地传递值,并且还将处理迭代器在耗尽之前只能使用一次的问题(与数组相反)。


      It seems utterly natural to me that generators, which function very much like Arrays, should support the very basic list operations, like map(), filter(), and reduce(). Am I missing something?

      I wrote the code for map and it seems simple enough, but it would be much better to have all the functions embedded in all the generators:

      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;
      }
      

      I'm new to generators, so any comments on the code are welcome. In particular, is that the best way to write "the identity generator"?

      解决方案

      Why do generators not support map()?

      Because it's too easy to fill in as a userland implementation. ES3 didn't include Array iteration methods either, maybe will see transformers for iterators in ES7 :-)

      generators, which function very much like Arrays

      No, please stop and distinguish iterators from generators:

      • An iterator is an object with a .next() method that conforms to the iterator protocol.
      • A generator is an iterator created by a generator function (function*). Its .next() method takes an argument which is the result of each yield inside the generator function. It also has .return() and .throw() methods.

      You'll mostly be interested in iterators, where we don't pass values to next, and don't care about the end result - just like for of loops do. We can extend them with the desired methods easily:

      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;
      };
      

      These should suffice for the start, and most common use cases. A proper library will extend this to generators so that values are passed through appropriately, and also will deal with the problem that iterators can be used only once before they are exhausted (in contrast to arrays).

      这篇关于为什么生成器不支持map()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆