Bagaimana cara memilih secara acak dari array?

559

Saya ingin tahu apakah ada cara yang jauh lebih bersih untuk melakukan ini. Pada dasarnya, saya ingin memilih elemen acak dari array dengan panjang variabel. Biasanya, saya akan melakukannya seperti ini:

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

Apakah ada sesuatu yang lebih mudah dibaca / sederhana untuk menggantikan baris kedua? Atau apakah itu cara terbaik untuk melakukannya. Saya kira Anda bisa melakukannya myArray.shuffle.first, tetapi saya hanya melihat #shufflebeberapa menit yang lalu pada SO, saya belum benar-benar menggunakannya.

Paul Hoffer
sumber
13
Jawaban yang bagus di bawah ini tetapi poin umum tentang shuffle. Saya akan membayangkan suffling array penuh akan jauh lebih intensif daripada hanya mendapatkan nomor acak sehingga itu bukan arah yang baik untuk pergi.
Derek Organ

Jawaban:

1127

Cukup gunakan Array#sample:

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

Ini tersedia di Ruby 1.9.1+. Agar dapat menggunakannya dengan versi Ruby yang lebih lama, Anda dapat melakukannya require "backports/1.9.1/array/sample".

Perhatikan bahwa dalam Ruby 1.8.7 ada di bawah nama yang disayangkan choice; diganti namanya di versi yang lebih baru sehingga Anda tidak harus menggunakannya.

Meskipun tidak berguna dalam kasus ini, samplemenerima argumen nomor jika Anda ingin sejumlah sampel berbeda.

Marc-André Lafortune
sumber
1
Saya seharusnya tahu bahwa Anda akan memiliki jawaban yang sempurna untuk saya (karena sebagian besar pertanyaan Ruby yang saya jelajahi di sini memiliki masukan Anda di suatu tempat). Saya senang Anda menunjukkan versi; Saya menggunakan 1.9.2. apidock (komentar mladen) tidak memiliki sampel; ruby-doc juga tidak. Menurut Anda, apa referensi terbaik untuk Ruby, yang diperbarui ke 1.9?
Paul Hoffer
Di samping catatan, apakah pantas untuk mengubah "jawaban yang benar" setelah saya pertama kali memilih jawaban lain?
Paul Hoffer
1
Terima kasih :-) Dan ya, dianjurkan (lihat meta.stackexchange.com/questions/19448/… )
Marc-André Lafortune
Saya perhatikan suntingan Anda menghapus menyebutkan 1.8.8. Apakah masih tersedia dalam 1,8-kepala, dan Anda hanya mengedit pertanyaan karena 1.8.8 tidak akan terjadi?
Andrew Grimm
3
@Andrew: Ya, saya mengedit jawaban saya karena 1.8.8 tidak akan terjadi. Seharusnya masih dalam 1,8-kepala, tapi cabang itu sudah mati :-(
Marc-André Lafortune
84

myArray.sample(x) juga dapat membantu Anda mendapatkan x elemen acak dari array.

beesasoh
sumber
6
Perlu dicatat bahwa my_array.sample (1)! = My_array.sample
Redithion
5
@Redithion Juga patut dicatat, bahwa perbedaan antara: my_array.sample (1) == [sample] dan my_array.sample == sampel untuk memberikan secara eksplisit apa yang Anda maksud
Ekkstein
14
myArray.sample

akan mengembalikan 1 nilai acak.

myArray.shuffle.first

juga akan mengembalikan 1 nilai acak.

JJ21
sumber
26
Shuffle itu berlebihan.
superluminary
1
Secara teknis, metode acak ini benar juga stackoverflow.com/a/84747/2047418
Filip Bartuzi
12

Jumlah Acak Item Acak dari Array

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

Contoh hasil yang mungkin:

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

=> ["two", "three"]
=> ["one", "three", "two"]
=> ["two"]
Mike Rapadas
sumber
@fwilson mengoleksi objek secara acak dalam urutan apa pun. Juga baik untuk menguji berbagai kombinasi atau menghasilkan data rintisan
Mike Rapadas
mengapa tidak memperpanjang kelas Array? [] .total_random akan lebih keren. datang ruby ​​nya. tujuannya!
Tim Kretschmer
Ini tidak akan pernah mengembalikan array kosong. Anda harus menempatkan 1 +di tempat yang berbeda.
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)]

Ini akan mengembalikan elemen acak dari array.

Jika Anda akan menggunakan baris yang disebutkan di bawah ini

arr[1+rand(arr.count)]

maka dalam beberapa kasus akan mengembalikan nilai 0 atau nil.

Garis yang disebutkan di bawah ini

rand(number)

selalu mengembalikan nilai dari 0 ke angka-1.

Jika kita gunakan

1+rand(number)

maka ia dapat mengembalikan angka dan arr [angka] tidak mengandung elemen.

Muhammad Aamir
sumber
-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
Charon IV
sumber