Lambda迭代遍历迭代器(不可迭代) [英] Lambda iteration over an Iterator (not an Iterable)

查看:163
本文介绍了Lambda迭代遍历迭代器(不可迭代)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常读到在迭代器上调用Lambda函数是不可能的.直到现在我一直信奉这种信念.但是,阅读佛朗哥·庞蒂塞利(Franco Ponticelli)和李·麦科尔·西尔维斯特(Lee-McColl-Sylvester)所著的Professional Haxe一书,关于使对象成为可迭代对象或迭代器的原因使我想到了一个技巧,这似乎行得通.至少在我刚刚测试过的简单情况下.

I often read it's impossible to call Lambda functions on iterators. And I lived in that belief until now. However reading the book Professional Haxe by Franco Ponticelli and Lee-McColl-Sylvester about what makes an objet an Iterable or an Iterator made me think of one trick, that seems to work; at least in the simple case I just tested.

诀窍很简单,就是在Iterator类的内部声明一个Iterator()函数 ,并返回 itself (很奇怪,但不是那么不连贯).

The trick is simply to declare an iterator() function inside the Iterator class, returning itself (weird yes, but not that incoherent).

我不知道这在一般情况下是否行得通,但是这个简单的示例可以在Haxe 2和Haxe 3上编译并正常工作(

I don't know if this will work in the general case, but this simple examples compiles and works fine on both Haxe 2 and Haxe 3 (http://try.haxe.org/#b764F):

using Lambda;

class IntIter2 {
    var min : Int;
    var max : Int;

    public inline function new( min : Int, max : Int ) {
        this.min = min;
        this.max = max;
    }

    public inline function hasNext() { return min < max; }
    public inline function next() { return min++; }

    // here goes the magic/weirdness/abomination
    public function iterator():IntIter2 { return this; }
}

class Test {
    public static function main() {
        var evenNumbers = new IntIter2(3, 10)
            .filter( function (n:Int):Bool return n % 2 == 0 )
            .list()  // unneeded, in fact...
        ; 
        trace(evenNumbers.toString());      
        // list even numbers in the series, ie {4, 6, 8}
    }
}

为什么起作用(至少在这里)

在haXe标准库中,定义了两个非常常用的typedef:Iterator和Iterable.

"In the haXe standard library, two very commonly used typedefs are defined: Iterator and Iterable.

它们的定义如下:

typedef Iterator<T> = { 
    function hasNext() : Bool; 
    function next() : T;
}
typedef Iterable<T> = {
    function iterator() : Iterator<T>; 
}

"-Franco Ponticelli和Lee-McColl-Sylvester的Haxe Professional

" - Haxe Professional by Franco Ponticelli and Lee-McColl-Sylvester

因此,将iterator()添加到Iterator类使其可迭代,并且可与Lambda函数一起使用.还是总是那么简单?

Therefore adding iterator() to an Iterator class makes it Iterable, and usable with Lambda functions. Or is that always so simple?

推荐答案

在Haxe存储库中查看此(开放)问题:

Check out this (open) issue on the Haxe repository:

Lambda应该支持Iterator以及Iterable#1914

该线程中的最终注释实际上是您的建议-它可以起作用,但是更改迭代器"的定义以使每个迭代器本身都是可迭代的"是一项重大更改,不可能更改在Haxe 3期间.也许在Haxe 4期间:)

The final comment in the thread is actually what you're suggesting - and it could work, but changing the definition of "Iterator" so that every iterator is itself "iterable" is a breaking change and won't likely be changed during Haxe 3. Maybe for Haxe 4 :)

另一种选择是使用允许隐式转换的抽象来创建可与Iterable和Iterator一起使用的类型"Iter":

The other option is using abstracts, which allow implicit casting, to create a type "Iter" that works with both Iterable and Iterator:

abstract Iter<T>(Iterator<T>) from Iterator<T> to Iterator<T> {
  inline function new(it:Iterator<T>)
    this = it;

  @:from static public inline function fromIterable(it:Iterable<T>) {
    return new Iter(it.iterator());
  } 
}

我在对此问题的评论中写道: https://github .com/HaxeFoundation/haxe/issues/1914#issuecomment-19380450

I wrote about this in a comment on that issue: https://github.com/HaxeFoundation/haxe/issues/1914#issuecomment-19380450

您可以使用Iter创建可与Iterable和Iterator一起使用的自定义Lambda帮助程序.

You could use Iter to create your own custom Lambda helper that works with both Iterable and Iterator.

祝你好运:)

这篇关于Lambda迭代遍历迭代器(不可迭代)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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