2011-12-22 6 views
1

"配列の配列"に関する次の例を読んでいます。 AOAは、二次元アレイ配列の配列へのアクセスについて

次のコードセグメントは、インデックスと全部を印刷するために主張されている参考文献

for $aref (@AoA) { 
    print "\t [ @$aref ],\n"; 
} 

、次のコードセグメントに全部を印刷するために主張されている

for $i (0 .. $#AoA) { 
    print "\t [ @{$AoA[$i]} ],\n"; 
} 

ここには$ arefスタンドがありますか? @$aref@{$AoA[$i]}の定義を理解するにはどうすればよいですか?ありがとう。

+4

[perldoc perldata](http://perldoc.perl.org/perldata.html)と[perldoc perlref](http://perldoc.perl.org/perlref.html)を参照してください。 – Ether

答えて

5

$arefは、「アレイ参照」、すなわちアレイの参照を表す。

my $my_aref = \@somearray; 

次の構文を持つ配列参照から配列を作ることができます。

@{$my_aref} 

@{$my_aref}@somearrayです。

第2の例では、$AoA[$i]は配列参照であり、同じ構文で逆参照します(@{$AoA[$i]})。これは、コピーではありません。実際には同じ配列です。

さらに詳しい説明と例については、perlreftutを参照してください。

1

"配列の配列"は実際には配列の配列ではありません。これは配列参照の配列です。ベース配列の各要素は別の配列への参照です。したがって、ベース配列の要素を順番に調べたいときは、配列参照を返すことになります。これらは最初のループで$arefに割り当てられます。これらのシンボルは、@シンボルのプリファンドによって参照解除されるため、@$aref$aref配列参照で参照される配列です。

同じようなことが2番目のループで機能します。 $AoA[$i]は、配列参照の@AoA配列の$i番目の要素です。 @シンボルであらかじめ保留して参照を解除してください(明確にするために{}を追加します)。@{$AoA[$i]}$AoA[$i]配列参照によって参照される配列です。

1

Perlには多次元配列がありません。 1つは、同じ結果を得るために配列を他の配列に配置します。

まあ、ほとんど。配列(およびハッシュ)値はスカラーなので、配列を別の配列に配置することはできません。代わりに参照を配列に代入する代わりに、何をしますか。

つまり、「配列の配列」は、「配列への参照配列」の略です。 @AoAの各値は、2次元配列の「錯覚」を考慮すると、別の配列への参照です。


参照は、[ ]または同等のものから使用されます。 [ ]は匿名配列を作成し、その配列への参照を作成してから参照を返します。それが参照の由来です。AoAの構築の

一般的な方法:

my @AoA = (
    [ 'a', 'b', 'c' ], 
    [ 'd', 'e', 'f' ], 
); 

my @AoA; 
push @AoA, [ 'a', 'b', 'c' ]; 
push @AoA, [ 'd', 'e', 'f' ]; 

my @AoA; 
$AoA[$y][$x] = $n; 

$AoA[$y][$x] = $n; 

$AoA[$y]->[$x] = $n; 

の略であり、それはautovivificationに以下のおかげと同等だということを覚えておいてください

($AoA[$y] //= [])->[$x] = $n; 
1

perlで多次元構造を持つ謎は、扱う変数が3種類しかないことに気がついたら理解しやすいです。スカラ、配列、ハッシュ

  • スカラは単一の値である、それはちょうど約何でも、しかし だけ一度に含めることができます。
  • 配列には、数字のインデックス が固定されている、いくつかのスカラー値が含まれています。
  • ハッシュには、文字列で構成されたキーでインデックスされたスカラー値が含まれています。

およびすべてアレイ、ハッシュまたはスカラーがこのように作用する。多次元配列は単一次元と変わらない。

これもperldataで非常に簡潔に表現される:

をPerlですべてのデータは、スカラー、スカラーの配列、又は スカラーのハッシュです。スカラーには、数値、文字列、または参照の3種類のうちのいずれか1つの単一の値が含まれます。一般に、 のフォームから別のフォームへの変換は透過的です。スカラー は複数の値を直接保持することはできませんが、 という配列への参照や複数の値を含むハッシュを含むことがあります。例えば

ここ
my @array = (1, 2, 3); 

$array[0]は、あなたが期待するだけのようになど、$array[1]は2が含まれ、1が含まれています。

my @aoa = ([ 1, 2, 3 ], [ 'a', 'b', 'c' ]); 

ここで、$array[0]には配列参照が含まれています。それを印刷すると、ARRAY(0x398a84)のようになります。心配しないでください!それはまだスカラー値です。これをどうやって知るのですか?配列にはスカラ値のみが含まれるためです。

我々は

for $aref (@AoA) { 
    print $aref; # prints ARRAY(0x398a84) or similar 
} 

ような何かを行うときに

for $number (@array) { 
    print $number; 
} 

$aref$numberを行うと何ら変わりませんが、スカラー値です。ここまでは順調ですね。ちょっと時間をかけてこの知識をロックしてください。配列にはスカラー値しか含めることができません。今


、次の部分は、単に参照に対処する方法を知っています。これはperlrefperlreftutに記載されています。

リファレンスはスカラー値です。これはメモリ内の場所へのアドレスです。この場所にはデータが含まれています。実際のデータにアクセスするには、リファレンスを間接参照する必要があります。簡単な例として

:参照の前にシギルを追加

my @data = (1, 2, 3); 
my $aref = \@data; # The backslash in front of the sigil creates a reference 
print $aref;   # print something like ARRAY(0xa4b6a4) 
print @$aref;  # prints 123 

はシギルが表すデータの種類にスカラー値間接参照にPerlを伝えます。この場合、配列です。上記、我々は特定の、名前の場所への参照を持っている例では

Not a HASH reference 

:あなたが参照のタイプのための間違った印章を選択した場合は、perlのは、次のようなエラーが発生します。 @$aref@dataは同じ値にアクセスします。 1つの値を変更すると、メモリ位置へのアドレスが同一であるため、両方が影響を受けます。のは、それを試してみましょう:

my @data = (1, 2, 3); 
my $aref = \@data; 
$$aref[1] = 'a';   # dereference to a scalar value by $ sigil 
# $aref->[1] = 'a'  # does the same thing, a different way 
print @data;    # prints 1a3 
print @$aref;   # prints 1a3 

我々はまた、匿名のデータを持つことができます。我々は配列の配列を構築する上で唯一興味を持っていたならば、我々は@dataには関心を持っていないだろうし、これを行うことによって、それをスキップすることができます:

my $aref = [ 1, 2, 3 ]; 

番号のリストの周りの括弧は無名配列を作成します。 $arefには、同じタイプのデータが含まれています。しかしこの場合、$arefは、メモリ位置に含まれるデータにアクセスする唯一の方法です。

my $aref1 = [ 1, 2, 3 ]; 
my $aref2 = [ 'a', 'b', 'c' ]; 
my $aref3 = [ 'x', 'y', 'z' ]; 

ここで、匿名配列への参照を含む3つのスカラー変数があります。これらを配列に入れるとどうなりますか? @{ ... }:我々は$aref1にアクセスしたいと思います場合

my @aoa = ($aref1, $aref2, $aref3); 

は、我々は print @$aref1を行うことができますが、我々はこの場合も
print @{$aoa[0]}; 

を行うことができ、我々は、逆参照の拡張形式を使用する必要があります。 perlはあいまいさを好まないので、 @{$aoa[0]}$aoa[0]の参照を配列として参照する)と @{$aoa}[0](参照を $aoaに入れ、配列を逆参照してその配列の最初の値をとる)を区別する必要があります。

上記は@{$aref}です。これは@$arefと同じです。

したがって、配列の配列だけを作成することに興味がある場合は、$aref1スカラーのいずれにも関心がありません。ですので、プロセスから切り離しましょう:

my @aoa = ([ 1, 2, 3 ], [ 'a', 'b', 'c' ], [ 'x', 'y', 'z' ]); 

タダ!それは配列の配列です。

今、バックトラックすることができます。この配列内の値にアクセスするには、

for my $scalar (@aoa) { 
    print @$scalar; # prints 123abcxyz 
} 

今回は、別の変数名を使用してポイントを作成しました。このループは@aoaからの各値をとります。これはまだスカラ値だけですが、配列として逆参照して出力します。

それともそのインデックス

for my $i (0 .. $#aoa) { 
    print @{$aoa[$i]}; 
} 

経由@aoaにアクセスすることができ、それはこれだけです!

関連する問題