Perl には、each、keys(キーのリストを通じて)、foreach、そしてvaluesを使用してハッシュを反復処理するいくつかの方法があります。言語の初めから、ハッシュはデータへの迅速なアクセスのために使用されることが想定されていたため、反復処理の方法は性能と追加メモリの最小化を考慮して作成されました。
問題: これらの技術を使用する際には多くの落とし穴があります。反復処理中にハッシュを変更すること、イテレータを記憶すること、要素の順序、eachがハッシュに与える副作用、そして入れ子の反復処理中の予期しない動作のリスクです。
解決策: 安全で予測可能な反復処理を行うために、foreach my $key (sort keys %hash)を使用し、反復処理中にハッシュを変更しないようにし、eachのためには新しいサイクルの前にkeys %hashを使用して常にイテレータをリセットします。
コード例:
my %hash = ( a => 1, b => 2, c => 3 ); foreach my $key (sort keys %hash) { print "$key: $hash{$key} "; # 予測可能な順序 }
主な特徴:
keysを通じた反復はキーのリストのコピーを返し、順序は未定です。eachイテレータはハッシュに記憶され、異なるハッシュであれば同時に複数のサイクルが可能です。eachイテレータをリセットするには空のkeysの呼び出しを使用します。eachの間にハッシュを安全に変更できますか?
いいえ、これは制御不可能な結果を引き起こします:データがスキップされたり、何度もカウントされたりする可能性があります。
異なる2つのハッシュに対してeachを呼び出すと、共通のイテレータになりますか?
いいえ、イテレータは各ハッシュに対して独立しています。
同じハッシュに対してeachで2回のループを入れ子にできますか?
いいえ、イテレータが「ぶれ」、結果が予測不可能になります。そのような場合は、keysと入れ子のループを使用してください。
異なる部分の同じハッシュを使用して何度も呼び出される関数内でeachを使用してハッシュを反復処理する。イテレータがぶれ、データの一部が失われる。
利点:
欠点:
foreachとkeysを利用して反復処理を行い、明示的にキーを別の配列に保存して全てを網羅します。
利点:
欠点: