From: rubikitch@... Date: 2007-12-18T10:41:22+09:00 Subject: [ruby-list:44354] Re: 配列のシャッフル From: Maehara Masahide (前原正英) Subject: [ruby-list:44352] 配列のシャッフル Date: Tue, 18 Dec 2007 09:30:02 +0900 るびきちです。 > 現在,『The Ruby Way』を読んでいるのですが,その中で以下のような配列の > シャッフルについての記述があります。 翻訳はまだですが、The Ruby Wayはすでに2nd editionが出ています。 そこでは sort_by { rand } で乱数でsortすることでシャッフルしています。 class Array def randomize self.sort_by { rand } end def randomize! self.replace(self.randomize) end end a = [1, 2, 3, 4, 5] a.randomize! # => [2, 3, 4, 5, 1] > def randomize! > result = collect { slice!(rand(length)) } > replace result > end (snip) > def shuffle > arr = dup > collect{ arr.slice!(rand(arr.length)) } > end (snip) > 何故,『The Ruby Way』の方法では,配列の全要素をシャッフルできないので > しょうか?アドバイスを頂ければ幸いです。 元のrandomize!で使われているslice!は名前の通り破壊的メソッドです。 だからcollectの中で元の配列の内容が書き変わってしまいます。 一方、shuffleの方はdupでオリジナルをコピーしているのでコピーを書き換えても 元の配列には何も影響が出ません。 ちなみに速度を比べてみると、sort_byによるrandomizeの方が速いですね。 require 'benchmark' a = Array.new(100000){rand} Benchmark.realtime{ a.shuffle} # => 4.83160209655762 Benchmark.realtime{ a.randomize} # => 0.643673896789551 -- rubikitch Blog: http://d.hatena.ne.jp/rubikitch/ Site: http://www.rubyist.net/~rubikitch/