Perl相当于java Iterator

时间:2013-02-25 16:01:51

标签: perl perl-module

在java中,对于表示集合的类,如果它实现了可迭代接口,则可以使用foreach循环在不知道集合的情况下迭代集合。

我们可以在perl中做类似的事情吗?假设我的perl类是一个集合。迭代集合的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

如果您使用Perl哈希代替Collection,那么您可以使用each来迭代它。

每次调用each %hash都会返回下一个键/值对,或者最后一个空列表。

答案 1 :(得分:1)

Perl没有Java风格的迭代器,因为它不需要它们。 Perl内置了相当强大的哈希和列表,可以取代您需要的大多数自定义集合,并且您可以轻松地遍历它们。如果你想对每个元素做一些事情(特别是如果你想建立一个结果列表),你可以传递一个代码引用的函数map

但是,如果你真的想要这种Java主义,你可以构建自己的迭代器类。它不必实现或扩展任何特定的接口,导致Perl duck-types - 而普通人无论如何都不使用迭代器,因此首先没有标准接口。它与foreach没有任何关系。 :P

真的,最好只使用标准的集合类型。我从来没遇到需要定制系列的情况。

答案 2 :(得分:0)

Perl的两个内置集合 - 数组和散列 - 有多种迭代方式:

  1. foreach循环:这循环(但不是懒惰地遍历)给定列表中的每个项目。在哈希上使用它可能是错误的,你应该迭代valueskeys

    foreach my $key (keys %hash) {
      do something;
    }
    
  2. each迭代器:您可以使用each函数迭代“集合”。每次调用它时,它都会返回一个键/索引列表和一个值。如果没有其他项目,则会返回错误值:

    while (my ($key, $value) = each %hash) {
      do something;
    }
    

    每个数组/哈希只能有一个这样的迭代器。在数组上使用each是一个相当新的功能。

  3. each成语可以通过闭包扩展来创建自定义迭代器:

    my %hash = ...;
    my @keys = keys %hash; # cache the current keys
    my $i = 0;
    my $iter = sub {
      return unless $i < @keys;
      my $key = $keys[$i++];
      return ($key, $hash{$key});
    };
    ...;
    while (my ($key, $value) = $iter->()) {
      do something;
    }
    

答案 3 :(得分:0)

你可以通过使用闭包和函数编程技术在perl中创建任意复杂的迭代器,因为当你需要高于perl内置迭代数组和散列的能力时。这是一个简单的例子来说明这种技术 - 在这种情况下,它非常无用,因为对于这种特殊情况,迭代器是不必要的。但正如我所说,这种技术可以在其他场景中有用。此示例将向后遍历数组,跳过我们要排除的元素(在本例中为字母“c”)。

sub gen_iter {
    my @collection = @_;
    return sub {
        while (my $item = pop @collection) {
            next if $item eq 'c';
            return $item;
        }
    }
}

my $it = gen_iter((qw/a b c d e f g/));

# prints 'gfedba'
while (my $item = $it->()) {
    print $item;
}

我建议抓住免费的电子书'High-Order Perl'并消化迭代器的章节。它有一些很好的,有用的例子。