小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

Perlでの多次元配列アクセス

Perlでは、言語仕様的には、多次元配列は、ありません。
しかし、配列のリファレンスを配列の要素にすることで、あたかも多次元配列を実現することが出来るのです。
多次元配列は結構難解で、言葉で説明すると余計に混乱するので、以下のサンプルをヒントにしてみてください。


基本的には、リファレンスはスカラー値で、変数名の前に『\』添えて表記します。
そのリファレンスから元の値にアクセスすることをデリファレンスいいます。
元がスカラーのリファレンスのデリファレンスは、変数名に『$』を添えて表記します。
また、配列の最大インデックスは、変数名に『$#』を添えて表記します。

my @aaa = ('aaa', 'bbb', 'ccc', 'ddd'); # 1次元配列変数
my @bbb = (\@aaa, 'eee', 'fff');        # 2次元配列変数(ただし、一番目の要素のみ2次元)
my @ccc = (\@bbb, 'ggg');               # 3次元配列変数(ただし、一番目の要素のみ3次元)
my $ddd = \@ccc;   # 3次元配列変数のリファレンスが入っているスカラー変数

# 1次元配列変数@aaaへのアクセス
print $#aaa; # @aaaの最大インデックス
print "\n";
for (my $i = 0; $i <= $#aaa; $i++) {
        print $aaa[$i], "\n";
}

# 2次元配列変数から@aaaへのアクセス
print $#{$bbb[0]}; # 2次元配列変数からの@aaaの最大インデックス
print "\n";
for (my $i = 0; $i <= $#{$bbb[0]}; $i++) {
     print ${$bbb[0]}[$i], "\n"; # 左は、$bbb[0]->[$i]や$bbb[0][$i]と等価
}

# 3次元配列変数から@aaaへのアクセス
print $#{${$ccc[0]}[0]}; # 3次元配列変数からの@aaaの最大インデックス
print "\n";
for (my $i = 0; $i <= $#{${$ccc[0]}[0]}; $i++) {
     print ${$ccc[0]}[0][$i], "\n"; # 左は、$ccc[0]->[0]->[$i]や$ccc[0][0][$i] と等価
}

# 3次元配列変数リファレンスから@aaaへのアクセス
print $#{$$ddd[0][0]}; # 3次元配列変数リファレンスからの@aaaの最大インデックス
print "\n";
for (my $i = 0; $i <= $#{$$ddd[0][0]}; $i++) {
     print ${$ddd}[0][0][$i], "\n"; # 左は、$ddd->[0]->[0]->[$i] や $$ddd[0][0][$i]と等価
}

結果的には、多次元配列の表記は、以下の通りです。

  • 1次元配列の表記は、$aaa[0]のような感じで。
  • 2次元配列の表記は、$bbb[0][0]のような感じで。
  • 3次元配列の表記は、$ccc[0][0][0]のような感じで。

実に単純で、よかったよかった。


結果的には、多次元配列の最大インデックス表記は、以下の通りです。

  • 1次元配列の最大インデックス表記は、$#aaaのような感じで。
  • 2次元配列の最大インデックス表記は、$#{$bbb[0]}のような感じで。
  • 3次元配列の最大インデックス表記は、$#{${$ccc[0]}[0]}のような感じで。

実に難解なので、すこし解説です。

  • @aaaの最大インデックスは、$#aaaです。
  • $bbb[0]の中身は、@aaaのリファレンスです。したがって、$#{$bbb[0]}と$#aaaは等価です。
  • $ccc[0]の中身は、@bbbのリファレンスです。したがって、$#{${$ccc[0]}[0]}と$#{$bbb[0]}は、等価です。