6

Perlのハッシュについて学習しようとしている簡単なスクリプトがあります。

#!/usr/bin/perl

my %set = (
    -a => 'aaa',
    -b => 'bbb',
    -c => 'ccc',
    -d => 'ddd',
    -e => 'eee',
    -f => 'fff',
    -g => 'ggg'
);

print "Iterate up to ggg...\n";
while ( my ($key, $val) = each %set ) {
    print "$key -> $val \n";
    last if ($val eq 'ggg');
}
print "\n";

print "Iterate All...\n";
while ( my ($key, $val) = each %set ) {
    print "$key -> $val \n";
}
print "\n";

私は出力に驚いています:-

Iterate upto ggg...
-a -> aaa
-c -> ccc
-g -> ggg

Iterate All...
-f -> fff
-e -> eee
-d -> ddd
-b -> bbb

キーがハッシュ化されているため、内部の順序に応じて最初の出力が「n」要素になる可能性があることを理解しています。しかし、なぜ後で配列をループすることができないのですか?どうしたの ?

ありがとう、

4

2 に答える 2

18

each反復を追跡するためにハッシュに関連付けられたポインターを使用します。最初のwhileが2番目のwhileループと異なることを認識せず、それらの間で同じポインターを保持します。

ほとんどの人eachはこの(そして他の)理由で避け、代わりにkeys:を選びます

for my $key (keys %hash){
    say "$key => $hash{$key}";
}

これにより、反復順序も制御できます。

for my $key (sort keys %hash){
    say "$key => $hash{$key}";
}

とにかく、ループを早く終了する場合は、を避けてくださいeach

ところで、関数型プログラミングの支持者は、この機会を利用して、隠れた状態の欠点を指摘する必要があります。ステートレス操作(「テーブル内の各ペアをループする」)のように見えるものは、実際には非常にステートフルです。

于 2009-07-14T06:09:38.287 に答える
10

あなたはそれぞれのperldocを読むことができます

perldoc -f each

ハッシュが完全に読み取られると、リストコンテキストではnull配列が返され(割り当てられるとfalse(0)値が生成されます)、スカラーコンテキストでは「undef」が返されます。その後の「each」への次の呼び出しは、再び反復を開始します。プログラム内のすべての「each」、「keys」、および「values」関数呼び出しによって共有される、ハッシュごとに1つのイテレータがあります。ハッシュからすべての要素を読み取るか、「keysHASH」または「valuesHASH」を評価することでリセットできます。

したがって、コードで%setキーを使用して、(「最後の」ステートメントのために)再度反復することができます。

print "Iterate upto ggg...\n";
while ( my ($key, $val) = each %set ) {
    print "$key -> $val \n";
    last if ($val eq 'ggg');
}
print "\n";
keys %set;
print "Iterate All...\n";
while ( my ($key, $val) = each %set ) {
    print "$key -> $val \n";
}
print "\n";
于 2009-07-14T06:15:04.267 に答える