4

次のように宣言された配列のハッシュがあります。

my %hash;
push @{ $hash{ $value1[$_] } }, [ $value1[$_], $value2[$_], $value3[$_], $value4[$_], $value5[$_] ] for 0 .. $#value1;

次を使用して各キーの値を検査できるようにしたい:

open KEYS, '>keys.txt' or die "Can't write to 'keys.txt'\n";

for my $key ( sort keys %hash ) {
    print KEYS "Key: $key contains the values: ";
    for my $value ( @{$hash{$value1}} ) {
        print KEYS "$value ";
    }   
    print KEYS "\n";
}
close(KEYS);

Data::Dumper を使用してキーと関連する値を視覚化することはできますが、上記のコードからの出力は、各キーの値ではなくメモリ ロケーションを示します。例えば:

Key: 'Value1' contains the values: ARRAY(0x7fcd8645ba68) 

各配列に同じ数の値をプッシュしていますが、各キーには異なる数の値が含まれています

私がこれについて行っている方法に何か問題がありますか?

4

2 に答える 2

6

まず、内側のループでは、

for my $value ( @{$hash{$value1}} ) {
    print KEYS "$value ";
}   

一体何$value1ですか?を使いたかったのだと思います$key。未定義の値と宣言されていない変数について常にuse strict; use warnings警告を受けます。

次に、実行するとどうなるか見てみましょう

my %hash;
push @{ $hash{ $value1[$_] } }, "(value$_)" for 0 .. $#value1;

代わりに、ハッシュの arrayref に文字列をプッシュするだけです。次に、出力は次のようになります

Key: Value1 contains the values: (value0)
Key: Value2 contains the values: (value1)
Key: Value3 contains the values: (value2)

あはは!その arrayref にプッシュしたものはすべてそのまま出力されます。のような匿名の配列参照をプッシュする[...]と、その参照の文字列化が得られます: ARRAY(0x1234567)

おそらく、その配列参照の内容が必要です。簡単: 逆参照するだけです。

...;
print KEYS "[@$value] ";

またはそのようなもの。ここ"[...]"では、出力を視覚的にグループ化するためだけに使用されています。


スタイルノート:

openレキシカルファイルハンドルを持つ3-arg を考慮してください:

my $filename = "keys.txt";
open my $keys, "<", $filename or die "Can't open $filename: $!";

または自動エラー処理を使用します。

use autodie;
open my $keys, "<", "keys.txt";

いずれにせよ、通常は、エラー メッセージに失敗の理由$!を含めることが重要です。そうしないと、ほとんど役に立ちません。

loop を使用する代わりに、好みに応じてmapandを使用すると、コードがよりエレガントになる場合があります。join私はおそらくループを次のように書いたでしょう

use feature 'say';
for my $key ( sort keys %hash ) {
    say {$keys} "Key: $key contains the values: "
      . join " ", map { "[@$_]" } @{ $hash{$key} };
}
于 2013-06-27T11:59:42.790 に答える
3

これは、値のリストではなく配列参照をプッシュしているためです。

比較

push @array, [ $foo ];

push @array, $foo;

どちら@arrayの にも 1 つの要素が含まれますが、前者は を含む arrayref を保持しますが$foo、後者は のみを保持し$fooます。

push最初の引数の後に角括弧をなくしても問題ありません。

于 2013-06-27T11:59:29.437 に答える