はじめに
Array.newで作った2次元配列で少しハマったので、
その時に調べた内容をメモとして残します。
何が起こったか
現在、研修でGoogle Tech Dev Guideのマインスイーパーを作る課題を解いており、
マスを表現するために2次元配列を使ったところ、事件が起きました。。
今回は10✖10のマスを作りたかったので、下記のようにマスを作りました。
irb(main):001:0> a = Array.new(10,Array.new(10,"-"))
irb(main):002:0> pp a
[["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]
なんとなく上手く作れたように見えます。
次に左上のマスに「9」を格納してみます。
irb(main):003:0> a[0][0] = 9
irb(main):004:0> pp a
[[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"]]
ん?なぜか他の箇所まで「9」になっています。
この時点でお気づきの方もいるかと思うのですが、
Array.new(10,Array.new(10,"-"))で2次元配列を作成すると、
2次元目の配列は1次元目の配列を参照してしまうみたいです。。
それを確認するために、オブジェクトIDを見てみます。
(オブジェクトIDが分からない方はこちらを参照してください)
irb(main):005:0> puts a[0][0].object_id
19
irb(main):006:0> puts a[1][0].object_id
19
やはり、同じオブジェクトIDになっていますね。
どうするかいろいろ考えた結果、下記のような形になりました。
irb(main):007:0> b = Array.new(10).map{Array.new(10,"-")}
Array#mapはブロックの実行結果を新しい配列にして返してくれます。
この状態で、再度オブジェクトIDを確認してみます。
irb(main):008:0> puts b[0][0].object_id
46928456320740
irb(main):009:0> puts b[1][0].object_id
46928456320660
異なるオブジェクトIDになりましたね。
次に値を入れてみます。
irb(main):010:0> b[0][0] = 9
irb(main):011:0> pp b
[[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]
左上だけ値が変わりましたー!
まとめ
Array#mapすごく便利!!!