コレクションを表すクラスの Java では、反復可能なインターフェイスを実装すると、foreach ループを使用して、コレクションに関する知識がなくても、コレクションの反復処理を実行できます。
perl で似たようなことはできますか? 私の perl クラスがコレクションであるとします。コレクションを反復処理する最良の方法は何ですか?
コレクションを表すクラスの Java では、反復可能なインターフェイスを実装すると、foreach ループを使用して、コレクションに関する知識がなくても、コレクションの反復処理を実行できます。
perl で似たようなことはできますか? 私の perl クラスがコレクションであるとします。コレクションを反復処理する最良の方法は何ですか?
Collection の代わりに Perl ハッシュを使用すると、それeach
を反復処理するために使用できます。
を呼び出すたびにeach %hash
、次のキーと値のペア、または最後に空のリストが返されます。
Perl には Java スタイルの反復子がありません。必要がないからです。Perl にはかなり堅牢なハッシュとリストが組み込まれており、必要になるほとんどのカスタム コレクションに取って代わり、すでにそれらを簡単にループすることができます。そして、各要素で何かをしたい場合 (特に結果のリストを作成したい場合) にはmap
、コード ref を渡すことができるような関数があります。
ただし、この Java 主義が本当に必要な場合は、独自の反復子クラスを作成できます。特定のインターフェイスを実装または拡張する必要はありません。Perl のダック型が原因です。また、普通の人はとにかくイテレータを使用しないため、そもそも標準インターフェイスはありません。そして、それは何の関係もありませんforeach
。:P
実際には、標準のコレクション型をそのまま使用することをお勧めします。カスタム コレクションが必要なケースに遭遇したことはありません。
You can create arbitrarily complex iterators in perl by using closures and functional programming techniques, for when you need something above and beyond perl's built in ability to iterate over arrays and hashes. Here is is simplistic example to illustrate the technique - in this instance, its pretty useless since an iterator is unnecessary for this particular case. But as I said this technique can be applied usefully in other scenarios. This example will walk over an array backwards, skipping elements that we want excluded (in this case, the letter '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;
}
I recommend grabbing the free ebook 'High-Order Perl' and digesting the chapter on iterators. It has some great, useful examples.
Perl の 2 つの組み込みコレクション — 配列とハッシュ — にはさまざまな反復方法があります。
foreach
loops: これは、指定されたリスト内の各項目をループします (遅延反復ではありません)。ハッシュでこれを使用するのはおそらく間違っています。values
またはを反復処理する必要がありkeys
ます。
foreach my $key (keys %hash) {
do something;
}
イテレータ: 関数を使用each
して「コレクション」を反復処理できeach
ます。呼び出されるたびに、キー/インデックスのリストと値が返されます。それ以上アイテムがない場合は、false 値が返されます。
while (my ($key, $value) = each %hash) {
do something;
}
配列/ハッシュごとにそのような反復子を 1 つだけ持つことができます。このeach
on array の使用法はかなり新しい機能です。
この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;
}