忘備録 Rubyで多次元配列のコピー
RubyのArrayには clone や dup があるわけですが多次元配列のコピーを取っておこう、となったときに役に立たない
irb(main):022:0> a = [1, 2, [3, 4]] => [1, 2, [3, 4]] irb(main):023:0> b = a.dup => [1, 2, [3, 4]] irb(main):024:0> a[2][0] = 5 => 5 irb(main):025:0> a => [1, 2, [5, 4]] irb(main):026:0> b => [1, 2, [5, 4]]
aの内容だけ書き換えたはずがbの内容まで変わってしまっています。
cloneやdupは浅いコピーなのでこういうことが起こってしまいます。
そこで深くコピーする方法は以下のとおり
irb(main):030:0> a = [1, 2, [3, 4]] => [1, 2, [3, 4]] irb(main):031:0> b = Marshal.load(Marshal.dump(a)) => [1, 2, [3, 4]] irb(main):032:0> a[2][0] = 5 => 5 irb(main):033:0> a => [1, 2, [5, 4]] irb(main):034:0> b => [1, 2, [3, 4]]
再利用したいなら Marshal.load(Marshal.dump(a)) の部分をObjectクラスを再オープンしてメソッドとして定義すればよいでしょう。
再帰的にメソッドを定義しようかと思いましたがこんなカッコいい方法があるんですね。