Як вибрати довільно з масиву?


559

Я хочу знати, чи існує набагато чистіший спосіб зробити це. В основному, я хочу вибрати випадковий елемент з масиву змінної довжини. Зазвичай я б це робив так:

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

Чи є щось, що читає / простіше замінити другий рядок? Або це найкращий спосіб зробити це. Я припускаю, що ти міг би це зробити myArray.shuffle.first, але я бачив #shuffleлише кілька хвилин тому на SO, я його ще не використовував.


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
Я мав би знати, що ви отримаєте ідеальну відповідь для мене (оскільки більшість запитань про Рубі, які я переглядаю тут, десь є вашими відомостями). Я радий, що ви вказали на версію; Я використовую 1.9.2. apidock (коментар mladen) не має вибірки; ні рубін-док. На вашу думку, яка найкраща посилання на Ruby, оновлену до 1.9?
Пол Гоффер

Зі сторони, чи правильно змінювати "правильну відповідь" після того, як я вперше обрав іншу відповідь?
Пол Гоффер

1
Дякую :-) І так, рекомендується (див. Meta.stackexchange.com/questions/19448/… )
Марк-Андре Лафортун

Я помітив вашу редакцію про видалення згадки 1.8.8. Це все ще доступно в 1,8-головному, і ви просто редагуєте питання, оскільки 1.8.8 не відбудеться?
Ендрю Грімм

3
@Andrew: Так, я змінив свою відповідь, оскільки 1.8.8 не відбудеться. Це все ще повинно бути в 1,8 голови, але ця гілка мертва :-(
Марк-Андре Лафортун

84

myArray.sample(x) також може допомогти вам отримати x випадкових елементів з масиву.


6
Варто зазначити, що my_array.sample (1)! = My_array.sample
Redithion

5
@Redithion Також варто зазначити, що різниця між: my_array.sample (1) == [зразок] та my_array.sample == зразок, щоб чітко вказати, що ви маєте на увазі
Екштейн


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 випадкові колекції об'єктів у будь-якому порядку. Також добре підходить для тестування різних комбінацій або отримання даних про заглушки
Майк Рападас

чому б не розширити клас масиву? [] .total_random буде набагато крутішим. Комон її рубін. її мета!
Тім Кречмер

Це ніколи не поверне порожній масив. Потрібно розмістити 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 або нульове значення.

Рядок, згаданий нижче

rand(number)

завжди повертайте значення від 0 до числа-1.

Якщо ми використовуємо

1+rand(number)

тоді він може повернути число, а arr [число] не містить елемента.


-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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.