[#44310] プログラムに対して意図したとおりの文字列を渡す方法 — "Information Kanasansoft" <kanasansoft@...>

kanasanです。

9 messages 2007/12/05

[#44332] クラス:相互参照系の作成方法について質問です — "Saburoh Sakai" <sabroh@...>

はじめまして、さかいと申します。

12 messages 2007/12/11

[#44366] Rake改善プロジェクト — "Hajime Hoshi" <hajimehoshi@...>

東京大学修士 1 年の星一と申します。

14 messages 2007/12/19

[ruby-list:44354] Re: 配列のシャッフル

From: rubikitch@...
Date: 2007-12-18 01:41:22 UTC
List: ruby-list #44354
From: Maehara Masahide (前原正英) <maehrm@miyazaki-c.ed.jp>
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/

In This Thread