Ruby 配列の初期化と多重配列

環境もそろってきたので、記述のメモなど残していきます。

配列に関すること

宣言

arr = Array.new()
arr = Array.new # 等価
arr = [] # 等価
p arr # []

初期化

hoge_0 = [1,2,3]
p hoge_0 # => [1, 2, 3]
hoge_1 = [[1,2,3],[4,5,6]]
p hoge_1 # => [[1, 2, 3], [4, 5, 6]]

rubyなら出来そうで出来ない初期化、以前のversionではOK?

hoge_2[] = "hoge" # => エラー
hoge_3[0] = "hoge" # => エラー

new での初期化

arr = Array.new()
p arr # => []

arr = Array.new(3)
p arr # => [nil,nil,nil]

arr = Array.new(3, 1)
p arr # => [1,1,1]
arr[1] = 2
p arr # => [1, 2, 1]

ランダム値の初期化を考える

arr = Array.new(3, rand(1..9))
p arr # => [x,x,x] 要素が同じ値に(上記l.8参照)なってしまうので、ブロックを用いる

arr = Array.new(3){ rand(1..9) }
p arr # => [x,y,z] 要素3こが1~9のランダムな値

多次元配列の宣言の前に注意点!
このように書いてしまうとおかしなことになる

arr = Array.new(3,Array.new(3))
arr[1][1] = 2
p arr # => [[nil, 2, nil], [nil, 2, nil], [nil, 2, nil]]

上は、a[1][1]の要素を変更したのに、その他の配列(object)も変更されています。
参考 Rubyで二次元配列の初期化 – simanmanのブログ

オブジェクトのIDを確認すると、同じ値となっています。

p arr.map(&:object_id) # => [17525590, 17525590, 17525590]

多次元配列はブロックを使用して宣言する。
ランダム値の初期化の時と同様に、ここでもブロックを使います。

arr = Array.new(3){ Array.new(3) }
arr = Array.new(3).map{ Array.new(3) } # 同意 mapメソッドは、要素の数だけ繰り返しブロックを実行
p arr # => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
arr[1][1] = 2
p arr # => [[nil, nil, nil], [nil, 2, nil], [nil, nil, nil]]

上のように宣言することで、arr[1][1]の値のみ変更されます。
また、オブジェクトIDを確認すると、それぞれのオブジェクトとなっています。

p arr.map(&:object_id) # => [17918240, 17918230, 17918220]

多次元配列を初期化する
ランダム値の初期化の時と同様に、ここでもブロックを使います。

arr = Array.new(3){ Array.new(3, 1) }
p arr # => [[1, 1, 1], [1, 1, 1], [1, 1, 1]]

arr = Array.new(3){ |i| Array.new(3){ |j| i+j } }
p arr # => [[0, 1, 2], [1, 2, 3], [2, 3, 4]]

Rubyで二次元配列の初期化 – simanmanのブログ