Как выбрать случайным образом из массива?

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
Я должен был знать, что у вас был бы идеальный ответ для меня (так как большинство вопросов по Ruby, которые я просматриваю здесь, где-то содержат ваши данные). Я рад, что вы указали версию; Я использую 1.9.2. apidock (комментарий Младена) не имеет образца; как и ruby-doc. На ваш взгляд, что является лучшим справочником для Ruby, обновленным до 1.9?
Пол Хоффер
Следует отметить, что правильно ли менять «правильный ответ» после того, как я впервые выбрал другой ответ?
Пол Хоффер
1
Спасибо :-) И да, это поощряется (см. Meta.stackexchange.com/questions/19448/… )
Марк-Андре Лафортун
Я заметил, что ваша правка удаляет упоминание о 1.8.8. Это все еще доступно в 1.8-head, и вы просто редактируете вопрос, потому что 1.8.8 не произойдет?
Эндрю Гримм
3
@ Андрей: Да, я отредактировал свой ответ, потому что 1.8.8 не произойдет. Это все еще должно быть в 1,8-головке, но эта ветка мертва :-(
Марк-Андре Лафортун
84

myArray.sample(x) также может помочь вам получить х случайных элементов из массива.

beesasoh
источник
6
Стоит отметить, что my_array.sample (1)! = My_array.sample
Redithion
5
@Redithion Стоит также отметить, что разница между: my_array.sample (1) == [sample] и my_array.sample == sample позволяет явно
указать,
14
myArray.sample

вернет 1 случайное значение.

myArray.shuffle.first

также вернет 1 случайное значение.

JJ21
источник
26
Перестановка лишняя.
Сверхсветовой
1
Технически этот случайный метод тоже корректен stackoverflow.com/a/84747/2047418
Филипп Бартузи
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 случайные коллекции объектов в любом порядке. Также подходит для тестирования различных комбинаций или создания данных окурка
Майк Рападас
почему бы не расширить класс Array? [] .total_random был бы намного круче. пойдем рубин. его цель!
Тим Кречмер
Это никогда не вернет пустой массив. Вам нужно разместить 1 +в другом месте.
Пила
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
Харон IV
источник