iterator - 使用 Iterable 和 Iterator 角色实现可迭代类

标签 iterator raku

假设我们有以下类组成角色 Iterable :

class Word-Char does Iterable {
    has @.words;

    method !pairize($item) {
        return $item => $item.chars;
    }

    method iterator( Word-Char:D: ) {
        @!words.map({self!pairize($_)}).rotor(1).iterator
    }
}

我可以将对象分配给 Positional对象构造期间的变量并迭代该变量:
my @words = Word-Char.new: words => <the sky is blue>;
.say for @words;

输出:
(the => 3)
(sky => 3)
(is  => 2)
(blue => 4)

但是,如果对象被传递呢?我如何确保它仍然是可迭代的?:
my $w = Word-Char.new: words => <the sky is blue>;
sub f( $w ) {
    .say for $w
}
f($w);

输出 :
Word-Char.new(words => ["the", "sky", "is", "blue"])

目标 :

通过使用 Iterable , Iterator或两者兼而有之,如果可能的话,我希望能够在任何地方迭代实现这些角色的类的实例对象。现在我知道通过在对象构造期间将实例对象分配给 Positional变量,我可以获得类提供的可迭代项,但这不是我想要的。相反,我想传递对象本身并在我认为必要的任何地方/任何时候对其进行迭代。

最佳答案

在处理充当迭代器角色的标量值时,完成您尝试的最简单方法是告诉 perl6 您的标量值是可迭代的。你可以通过后缀 [] 来做到这一点。 .您的示例如下所示:

my $w = Word-Char.new: words => <the sky is blue>;
.say for $w[]

另一件事....

您的迭代代码有一个错误,它在返回之前不会自行重置 IterationEnd .快速修复如下所示:
class Word-Char does Iterable does Iterator {
    has @.words;
    has Int $!index = 0;

    method !pairize($item) {
        return $item => $item.chars;
    }

    method iterator() {self}
    method pull-one( --> Mu ) {
        if $!index < @!words.elems {
            my $item = @!words[$!index];
            $!index += 1;
            return self!pairize($item);
        }
        else {
            $!index = 0;
            return IterationEnd;
        }
    }
}

但是,这意味着您必须将所有迭代逻辑(及其属性)保留在主类中。另一种方法是使用匿名类,而不是使用 self :
class Word-Char does Iterable {
    has @.words;

    method !pairize($item) {
        return $item => $item.chars;
    }

    method iterator() {
        my @words = @!words;

        class :: does Iterator {
            has $.index is rw = 0;

            method pull-one {
              return IterationEnd if $!index >= @words.elems;
              @words[$!index++];
            }
        }.new;
    } 
}

上面的优点是你可以让你的迭代逻辑更清晰,并与对象的其余部分隔离。您也无需担心重置状态。

关于iterator - 使用 Iterable 和 Iterator 角色实现可迭代类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57121561/

相关文章:

raku - 如何习惯性地忽略未定义的数组元素(或首先避免将它们分配给数组)?

signature - Perl6 - $ : for in some subroutine Signatures 是什么

concurrency - 点击 IO::Notifications 时出现错误 "emit without supply or react"

regex - 匹配一个连接点使得 Match 不可变

java - entrySet() 如何在 HashMap 内部工作?

Java:迭代器

ruby - 在 Ruby 中循环遍历 Enumerator 的其余部分

c++ - 为图形编写 DFS 迭代器

c++11 - 在 C++ 中使用迭代器从 map 中删除项目

oop - 如何动态生成用于特征的值?