Perlの多次元配列の初期化を1行で書いてみたけど、やめたほうがいい
いきなり結論
3次元配列を0初期化する場合。
@multi_array=map{[map{[map{0}(0..2)]}(0..4)]}(0..7); #multi_array[8][5][3]
でも、普通にこっちのほうがいいよ
my @array; for my $i(0..7){ for my $j(0..4){ for my $k(0..2){ $array[$i][$j][$k]=0; } } }
やめたほうがいい理由
読みにくい、書きにくい
1行にmapが3回も出てきます。中括弧と角かっこのネストも多く、間違いやすいです。
要素数がわかりにくい
作りたい配列の要素数は[8][5][3]ですが、コードは添え字の数字が逆の順に出てきます。コメントなど、何らかの追加情報がないと誤解を招きます。
これを書いた本人も、末尾コメントがなければ理解できる自信がないです。
ゼロ初期化以外が書きにくい(拡張性がない)
中に複雑な初期値を書くことができません、少なくともif文を追加するのは向きません。 一から書いた、初版のプログラムでは、全ての要素は初期値ゼロでいいかもしれません。しかし、プログラムに機能を追加・拡張していくと、「偶数行だけ別の値にしたい」「規則的な値を入れたい」となることは時々あります。この初期化の後にfor文で追加の初期化を書けばよいかもしれませんが、(結果論では)最初からfor文で書いておいたほうがシンプルです。
よく考えると利用機会が限られる
3次元配列って必要でしょうか。多数のデータ、複雑な構造を持つデータなら、オブジェクトの配列や、あるいはデータベースで表したほうが有利なことはないか、考える余地はあります。これはプログラムの文法というより、構成や設計寄りの検討になります。
数学の3次元行列そのものを扱うときには必要なので、要は適材適所、です。
最後に
短く書くことはプログラマの美徳なこともありますが「短く『簡潔』」であることも重要だと思います。また、あまり省略しすぎると追記(拡張)に耐えられないこともあります。
短くて難しい記述は長くて読みやすい記述とトレードオフとも言えるので、凝った記述に凝りすぎないようにしましょう。なにごともほどほどに。
付録:いちおう解説
普通に書いた場合(再掲)。
my @array; for my $i(0..7){ for my $j(0..4){ for my $k(0..2){ $array[$i][$j][$k]=0; } } }
ところで、for
とmap
について、次の2つの式は同じ結果になります。
for my $i (0..9){$array[$i]=0;} @array=map{0](0..9); #same
それを使い、一番内側のfor
をmap
にします。
for my $i(0..7){ for my $j(0..4){ $array[$i][$j]=map{0}(0..2); #(0,0,0)のリスト } }
同じように2次元目も。2次元配列=リファレンスの配列なので、mapの結果に角括弧をつけ、配列のリファレンスとして返します。
for my $i(0..7){ $array[$i]=map{[map{0}(0..2)]}(0..4); #[0,0,0]のリファレンス×5。 }
あと一息。
@array=map{[map{[map{0}(0..2)]}(0..4)]}(0..7);
おしまい。