Hatena::Grouprubyist

trotrの日記

 | 

2008-01-23

rubyの配列値が共有されてしまう. 00:09

何か良い方法はないのかな?

module Enumerable
  def accumulate_n(init)
    (0..self.first.length-1).inject([]) do |re, i|
      xs = self.map{ |e| e[i]}
      re << xs.inject(init){ |re,e| yield(re,e)}
    end
  end
end
a = (0..4).map{ |e| e * 3}.map{ |e| [e,e+1,e+2]}
a # => [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14]]
a.accumulate_n(0){ |re,e| re + e} # => [30, 35, 40]

#このbのような結果をもらいたい。
b = (0..a.first.length-1).map{ |i| a.map{ |e| e[i]}}
b # => [[0, 3, 6, 9, 12], [1, 4, 7, 10, 13], [2, 5, 8, 11, 14]]

#これでできそうな気がするけど、配列の値が共有されてしまう。
c = a.accumulate_n([]){ |re,e| p e; re << e} 
c # => [[0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14], [0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14], [0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14]]

# >> 0
# >> 3
# >> 6
# >> 9
# >> 12
# >> 1
# >> 4
# >> 7
# >> 10
# >> 13
# >> 2
# >> 5
# >> 8
# >> 11
# >> 14

rubikitchrubikitch 2008/01/24 13:17 「Array#<<」は破壊的メソッドなのでコピーしましょう。
c = a.accumulate_n([]){ |re,e| p e; re.dup << e} # => [[0, 3, 6, 9, 12], [1, 4, 7, 10, 13], [2, 5, 8, 11, 14]]

trotrtrotr 2008/01/25 19:08 ありがとうございます。そうか、コピーすればいいのかー。

ゲスト



トラックバック - http://rubyist.g.hatena.ne.jp/trotr/20080123
 |