在java中,对于表示集合的类,如果它实现了可迭代接口,则可以使用foreach循环在不知道集合的情况下迭代集合。
我们可以在perl中做类似的事情吗?假设我的perl类是一个集合。迭代集合的最佳方法是什么?
答案 0 :(得分:2)
如果您使用Perl哈希代替Collection,那么您可以使用each
来迭代它。
每次调用each %hash
都会返回下一个键/值对,或者最后一个空列表。
答案 1 :(得分:1)
Perl没有Java风格的迭代器,因为它不需要它们。 Perl内置了相当强大的哈希和列表,可以取代您需要的大多数自定义集合,并且您可以轻松地遍历它们。如果你想对每个元素做一些事情(特别是如果你想建立一个结果列表),你可以传递一个代码引用的函数map
。
但是,如果你真的想要这种Java主义,你可以构建自己的迭代器类。它不必实现或扩展任何特定的接口,导致Perl duck-types - 而普通人无论如何都不使用迭代器,因此首先没有标准接口。它与foreach
没有任何关系。 :P
真的,最好只使用标准的集合类型。我从来没遇到需要定制系列的情况。
答案 2 :(得分:0)
Perl的两个内置集合 - 数组和散列 - 有多种迭代方式:
foreach
循环:这循环(但不是懒惰地遍历)给定列表中的每个项目。在哈希上使用它可能是错误的,你应该迭代values
或keys
:
foreach my $key (keys %hash) {
do something;
}
each
迭代器:您可以使用each
函数迭代“集合”。每次调用它时,它都会返回一个键/索引列表和一个值。如果没有其他项目,则会返回错误值:
while (my ($key, $value) = each %hash) {
do something;
}
每个数组/哈希只能有一个这样的迭代器。在数组上使用each
是一个相当新的功能。
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'并消化迭代器的章节。它有一些很好的,有用的例子。