19

私はPerlにかなり慣れていないので、これが簡単な質問のように思えたら許してください...

とにかく、配列のハッシュがあり、ハッシュ内の配列の 1 つを取得しようとしていますが、取得できるのは配列のスカラー サイズだけです。

%HoA = a hash of arrays
$key = some key in the hash

foreach $nextItem (@HoA{$key}) {
  do a bunch of stuff with $nextItem
}

これを行うと、$nextItem は常に配列のサイズになり、ループは 1 回だけ実行されます。以下を印刷してみました。

@HoA{$key}
$HoA{$key}
@$HoA{$key}

最初の 2 つはスカラー サイズを提供し、3 番目は何も提供しません...ここで何が欠けていますか?

更新:私の問題が実際に配列をハッシュに追加する方法にあるのかどうか疑問に思っています。これが私がやっていることです:

@HoA{$key} = split(/ /, $list);

それは配列をハッシュに貼り付けますか、それとも配列サイズをハッシュに貼り付けますか?

更新 2: 次のコード ブロックを試しました。

my $key = "TEST";
my %HoA = ();
my @testarray = (1, 2, 3);
@HoA{$key} = @testarray;
print Dumper(%HoA);

出力は次のとおりです。

$VAR1 = 'TEST';
$VAR2 = 1;

配列の最初の値だけを貼り付けるのはなぜですか?

4

4 に答える 4

19

この方法で配列を参照してみてください。

%HoA = a hash of arrays
$key = some key in the hash

foreach $nextItem (@{$HoA{$key}}) {
  do a bunch of stuff with $nextItem
}

で配列参照を取得し、$HoA{$key}それを配列にします。

編集:更新については、次のようにすると、必要なものが得られると思います:

@{$HoA{$key}} = split(/ /, $list);

またはあなたができる

push(@{$HoA{$key}}, split(/ /, $list);

例えば:

my $list = "fred joe brown sam";
my %HoA = ();
my $key = "jacob";
@{$HoA{$key} = split(/ /, $list);
foreach my $item (@{$HoA{$key}})
{
    print "Test item: $nextItem\n";
}

You will get:
Test item: fred
Test item: joe
Test item: brown
Test item: sam

use strict;編集:プログラムの先頭に追加します。基本的に、ハッシュが定義されている場合、HoA を配列として使用しようとしています。ハッシュの内容を不適切に参照しています。適切に行うには、との$間にが必要です。Perl は型がなく、そうしなければ殺人を免れることができます。orailly からの参照の抜粋は、いくつかのことを明らかにするかもしれません。@HoAuse strict;

my @testarray配列
my %hashです ハッシュ
$hash{$el1} = \@arrayです 配列への参照の値を持つ
@{$hash{$el1}} = @arrayハッシュ要素です 配列を含むハッシュ要素です

于 2012-09-21T17:37:52.503 に答える
11

ハッシュの各エントリは、配列への参照です。例えば:

$my_hash{$key}

配列ではなく、配列への参照です。$my_hash{$key}その配列が存在するメモリ内の領域を指しているだけです。逆参照するには、配列シンボルを前に置きます。

@{ my_hash{$key} }

要素について話し始めると、少し複雑になります。

${ my_hash{$key} }[0]

その配列の最初の要素です。その配列が他の配列へのハッシュで構成されている場合、構文が非常にわかりにくくなる可能性があることを想像できます。幸いなことに、Perl にはそれをきれいに処理する方法があります。

$my_hash{$key}->[0];

これは上記とまったく同じですが、構文を理解しやすくなっています。場合によっては、間接参照なしで参照できるようにするために、中間変数を使用する方が簡単な場合があります。

my %hash_of_array_refs;

foreach my $key (sort keys %hash_of_array_refs) {
    my @array = @{ $hash_of_array_refs{$key} };    #Dereference
    foreach my $element (@array) {                 #Much easier to read and understand
        say "First element is $array[0]";
        say "last element is $array[$#array]";
        say "This element: $element";
    }
}

逆参照しないと、次のようになります。

my %hash_of_array_refs;

foreach my $key (sort keys %hash_of_array_refs) {
    foreach my $element (@{ $hash_of_array_refs{$key} } ) {                 #Much easier to read and understand
        say "First element is " . $hash_of_array_refs->[0];
        say "last element is " . $hash_of_array_refs->[$#{ $hash_of_array_refs{key} } ]";
        say "This element: $element";
    }
}
于 2012-09-21T20:25:40.283 に答える
3
@array

配列を取得する方法なので、

@{ $array_ref }

配列参照と同等です。

$HoA{$key}

は配列への参照なので、

@{ $HoA{$key} }

その配列です。

for my $nextItem (@{ $HoA{$key} }) 
于 2012-09-21T17:40:40.323 に答える
1

「配列の最初の値だけを貼り付けているのはなぜですか?」

バックスラッシュを前に付けて、配列への参照をハッシュに入れる必要があります。

$HoA{$key} = \@testarray;

次に、逆参照するハッシュから取得すると、次のようになります。

@testarray = @{ $HoA{$key} };
于 2012-09-22T16:29:38.407 に答える