Ruby_Array_54

この記事は、以下のドキュメントを改変(自分なりに整理)して利用しています。

class Array (Ruby 3.1 リファレンスマニュアル)

インスタンスメソッド

shuffle -> Array
shuffle(random: Random) -> Array
  • 配列の要素をランダムシャッフルし、その結果を配列として返す
  • 引数にRandomオブジェクトを渡すことでそのオブジェクトが生成する擬似乱数列を用いることができる
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):002:0> arr.shuffle
=> ["c", "a", "e", "b", "d"]

irb(main):003:0> arr.shuffle
=> ["d", "e", "b", "a", "c"]
irb(main):001:1* class Foo
irb(main):002:2*   def self.rand(arg)
irb(main):003:2*     0.1
irb(main):004:1*   end
irb(main):005:0> end
=> :rand

irb(main):006:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):007:0> arr.shuffle(random: Foo)
=> ["b", "c", "d", "e", "a"]

irb(main):008:0> arr.shuffle(random: Foo)
=> ["b", "c", "d", "e", "a"]

irb(main):009:0> arr.shuffle(random: Foo)
=> ["b", "c", "d", "e", "a"]
shuffle! -> self
shuffle!(random: Random) -> self
  • 配列を破壊的にランダムシャッフルする
  • randomには乱数生成器(主にRandomオブジェクト)を指定する
    • 選択する要素のインデックスを返す rand メソッドに応答するオブジェクトであれば指定することが可能
    • randメソッドの引数にはRandom#rand(max) のように選択可能なインデックスの最大値が指定される
    • Kernel.#rand、Random を使用しないオブジェクトを指定した場合、Kernel.#srandの指定に影響されない
    • Ruby_Array_52 - にっちとだじゃれ に書いたsampleメソッド時の挙動と違う?バグ?
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):002:0> arr.shuffle!
=> ["a", "b", "e", "c", "d"]

irb(main):003:0> arr
=> ["a", "b", "e", "c", "d"]
irb(main):011:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):012:0> arr.shuffle!(random: Foo)
=> ["b", "c", "d", "e", "a"]

irb(main):013:0> arr.shuffle!(random: Bar)
<internal:array>:13:in `shuffle!': random number too big 2 (RangeError)
        from (irb):13:in `<main>'                                               
        from /Users/mfham/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
        from /Users/mfham/.rbenv/versions/3.1.0/bin/irb:25:in `load'            
        from /Users/mfham/.rbenv/versions/3.1.0/bin/irb:25:in `<main>' 

# ちなみにrandomメソッドに対して同クラスを指定すると次のようにエラーは起きない
# randomに関するドキュメントの説明文は同じなのに何で・・・?
# 「選択する要素のインデックスを返す rand メソッドに応答するオブジェクトであれば」をrandメソッドがインデックスを返せば(整数)良いと理解したけど・・・

irb(main):014:0> arr.sample(random: Foo)
=> "b"

irb(main):015:0> arr.sample(random: Bar)
=> "e"