5

ここで参照に関して非常に初心者っぽい質問がありますが、少なくとも私にはまだ混乱しています...
以下のコード例では、配列のハッシュを作成しようとしています:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use Data::Dumper;

$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Terse = 1;
$Data::Dumper::Quotekeys = 0;

my @a1 = ( 'a1', 1, 1, 1 );
my @a2 = ( 'a2', 2, 2, 2 );

my $a1_ref = \@a1;
my $a2_ref = \@a2;

my @a = ( $a1_ref, $a2_ref );

my %h = ();

for my $i ( 1 .. 2 ) {
        $h{"$i"} = \@a;
}

say Dumper \%h;

ダンパー出力は

{
          '1' => [
                   [
                     'a1',
                     1,
                     1,
                     1
                   ],
                   [
                     'a2',
                     2,
                     2,
                     2
                   ]
                 ],
          '2' => $VAR1->{'1'}
        }

ここでの問題は
、なぜ $h{'2'} が $h{'1'} への参照なのかということです。@a array-of-arrays で作成された同一のキー値を持つハッシュ %h を作成しようとしています。ハッシュの各キー値に @a に基づく独自の AoA を持たせたいのですが、代わりに $h{'1'} への参照を取得しています。私は何を間違っていますか??
私が達成しようとしているダンパーの出力は次のとおりです。

{
          '1' => [
                   [   
                     'a1',
                     1,  
                     1,  
                     1   
                   ],  
                   [   
                     'a2',
                     2,  
                     2,  
                     2   
                   ]   
                 ],  
          '2' => [
                   [   
                     'a1',
                     1,  
                     1,  
                     1   
                   ],  
                   [   
                     'a2',
                     2,  
                     2,  
                     2   
                   ]   
                 ]   
        }   

どんな助けでも感謝します。前もって感謝します!

4

4 に答える 4

4

$h{'2'}への参照ではなく$h{'1'}、両方が同じ配列、つまり への参照@aです。おそらくあなたが望むのは:

for my $i ( 1 .. 2 ) {
    $h{"$i"} = $a[$i - 1];
}

これはこれと同等です:

$h{'1'} = $a[0];   # i.e., $a1_ref
$h{'2'} = $a[1];   # i.e., $a2_ref

$h{'1'}への参照と への参照を@a1行います。$h{'2'}@a2

ちなみに、表記法を使用し、匿名配列とハッシュへの参照を (それぞれ) 作成すると役立つ場合[ ... ]あります{ ... }。andを介してandを除いて決して使用しないため、後者を直接作成することもできます。@a1@a2$a1_ref$a2_ref

my $a1_ref = [ 'a1', 1, 1, 1 ];   # reference to a new array (no name needed)
my $a2_ref = [ 'a2', 2, 2, 2 ];   # ditto

更新された質問のために編集:配列をコピーするには、次のように記述できます。

my @orig = (1, 2, 3);
my @new = @orig;

また:

my $orig_ref = [1, 2, 3];
my $new_ref = [@$orig_ref]; # arrayref -> array -> list -> array -> arrayref

あなたの場合、私があなたを正しく理解していれば、少し「深い」コピーを実行する必要があります。同じ要素を持つ2つの配列が必要なだけでなく、要素が同じ要素を持つ異なる配列への参照である2つの配列が必要です。これを行う組み込みの Perl の方法はありませんが、ループを作成するか、次のmap関数を使用できます。

my @orig = ([1, 2, 3], [4, 5, 6]);
my @new = map [@$_], @orig;

そう:

for my $i ( 1 .. 2 ) {
    $h{"$i"} = [map [@$_], @a];
}
于 2013-05-04T19:41:16.773 に答える