配列からランダムに選択するにはどうすればよいですか?


559

これを行うよりクリーンな方法があるかどうかを知りたいです。基本的に、可変長の配列からランダムな要素を選択します。通常、私は次のようにします。

myArray = ["stuff", "widget", "ruby", "goodies", "java", "emerald", "etc" ]
item = myArray[rand(myarray.length)]

2行目を置き換えるのにもっと読みやすい/簡単なものはありますか?またはそれを行うための最良の方法です。できると思いますがmyArray.shuffle.first#shuffleSOで数分前に見ただけで、まだ実際に使用していません。


13
以下は良い回答ですが、シャッフルに関する一般的なポイントです。完全な配列を詰め込むことは、単に乱数を取得することよりもはるかに集中的になるので、それは良い方向ではないでしょう。
デレクオルガン

回答:


1127

ただ使用するArray#sample

[:foo, :bar].sample # => :foo, or :bar :-)

Ruby 1.9.1以降で使用できます。Rubyの以前のバージョンでも使用できるようにするには、次の方法があり require "backports/1.9.1/array/sample"ます。

Ruby 1.8.7では、残念な名前で存在していることに注意してくださいchoice。後のバージョンで名前が変更されたので、使用しないでください。

この場合は有用でsampleはありませんが、多数の異なるサンプルが必要な場合に備えて、数値引数を受け入れます。


1
私があなたに完璧な答えを持っていることを知っていたはずです(私がここで閲覧するほとんどのRubyの質問はどこかにあなたの意見があるからです)。バージョン管理を指摘していただき、ありがとうございます。1.9.2を使用しています。apidock(mladenのコメント)にはサンプルがありません。ruby-docも同様です。あなたの意見では、1.9に更新されたRubyの最良のリファレンスは何ですか?
Paul Hoffer、

余談ですが、最初に別の回答を選択した後で「正解」を変更することは適切ですか?
Paul Hoffer、2010

1
おかげで:-)そして、はい、それは(参照奨励されmeta.stackexchange.com/questions/19448/...を
マルク=アンドレ・Lafortune

1.8.8の言及が削除されていることに気づきました。1.8ヘッドでも使用できますか?1.8.8が発生しないため、質問を編集していますか?
Andrew Grimm、

3
@Andrew:はい、私は1.8.8が起こらないので私の回答を編集しました。それはまだ1.8ヘッドにする必要がありますが、その枝が死んで:-(
マルク=アンドレ・Lafortune

84

myArray.sample(x) また、配列からx個のランダムな要素を取得するのにも役立ちます。


6
my_array.sample(1)!= my_array.sample
Redithion

5
@Redithionまた、注目に値します。my_array.sample(1)== [sample]とmy_array.sample == sampleの違いは、意味を明確に示しています
Ekkstein


12

配列からのランダムなアイテムのランダムな数

def random_items(array)
  array.sample(1 + rand(array.count))
end

考えられる結果の例:

my_array = ["one", "two", "three"]
my_array.sample(1 + rand(my_array.count))

=> ["two", "three"]
=> ["one", "three", "two"]
=> ["two"]

@fwilsonオブジェクトのランダムなコレクションを任意の順序で。さまざまな組み合わせのテストやスタブデータの生成にも適しています
Mike Rapadas 2014

クラスArrayを拡張しないのはなぜですか?[] .total_randomの方がずっと涼しいでしょう。ルビーが登場。その目的!
Tim Kretschmer

これは決して空の配列を返しません。1 +別の場所に配置する必要があります。
sawa

0
arr = [1,9,5,2,4,9,5,8,7,9,0,8,2,7,5,8,0,2,9]
arr[rand(arr.count)]

これは配列からランダムな要素を返します。

以下の行を使用する場合

arr[1+rand(arr.count)]

その後、場合によっては0またはnil値を返します。

下記の行

rand(number)

常に0からnumber-1までの値を返します。

使うなら

1+rand(number)

その場合、numberが返され、arr [number]に要素が含まれません。


-2
class String

  def black
    return "\e[30m#{self}\e[0m"
  end

  def red
    return "\e[31m#{self}\e[0m"
  end

  def light_green
    return "\e[32m#{self}\e[0m"
  end

  def purple
    return "\e[35m#{self}\e[0m"
  end

  def blue_dark
    return "\e[34m#{self}\e[0m"
  end

  def blue_light
    return "\e[36m#{self}\e[0m"
  end

  def white
    return "\e[37m#{self}\e[0m"
  end


  def randColor
    array_color = [
      "\e[30m#{self}\e[0m",
      "\e[31m#{self}\e[0m",
      "\e[32m#{self}\e[0m",
      "\e[35m#{self}\e[0m",
      "\e[34m#{self}\e[0m",
      "\e[36m#{self}\e[0m",
      "\e[37m#{self}\e[0m" ]

      return array_color[rand(0..array_color.size)]
  end


end
puts "black".black
puts "red".red
puts "light_green".light_green
puts "purple".purple
puts "dark blue".blue_dark
puts "light blue".blue_light
puts "white".white
puts "random color".randColor
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.