Jak wybrać losowo z tablicy?


559

Chcę wiedzieć, czy istnieje o wiele czystszy sposób na zrobienie tego. Zasadniczo chcę wybrać losowy element z tablicy o zmiennej długości. Normalnie zrobiłbym to w ten sposób:

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

Czy jest coś bardziej czytelnego / prostszego do zastąpienia drugiej linii? Czy jest to najlepszy sposób na zrobienie tego. Przypuszczam, że mógłbyś to zrobić myArray.shuffle.first, ale widziałem #shufflekilka minut temu na SO, jeszcze go nie użyłem.


13
Dobra odpowiedź poniżej, ale ogólna uwaga na temat losowania. Wyobrażam sobie, że wyczerpanie pełnej tablicy byłoby znacznie bardziej intensywne niż uzyskanie losowej liczby, więc nie byłby to dobry kierunek.
Derek Organ

Odpowiedzi:


1127

Po prostu użyj Array#sample:

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

Jest dostępny w Ruby 1.9.1+. Aby móc go używać z wcześniejszą wersją Ruby, możesz require "backports/1.9.1/array/sample".

Zauważ, że w Ruby 1.8.7 istnieje pod niefortunną nazwą choice; zmieniono jego nazwę w późniejszej wersji, więc nie należy jej używać.

Chociaż nie jest to przydatne w tym przypadku, sampleakceptuje argument liczbowy, jeśli chcesz uzyskać wiele różnych próbek.


1
Powinienem był wiedzieć, że masz dla mnie idealną odpowiedź (ponieważ większość pytań Ruby, które tu przeglądam, ma gdzieś swój wkład). Cieszę się, że wskazałeś wersję; Używam 1.9.2. apidock (komentarz mladen) nie ma próbki; ruby-doc też nie. Twoim zdaniem, jakie jest najlepsze odniesienie do Ruby, zaktualizowanego do wersji 1.9?
Paul Hoffer

Na marginesie, czy należy zmienić „poprawną odpowiedź” po tym, jak pierwszy raz wybrałem inną odpowiedź?
Paul Hoffer

1
Dzięki :-) I tak, zachęca się (patrz meta.stackexchange.com/questions/19448/... )
Marc-André Lafortune

Zauważyłem twoją edycję usuwającą wzmiankę o 1.8.8. Czy nadal jest dostępny w wersji 1.8-head, a ty po prostu edytujesz pytanie, ponieważ 1.8.8 się nie wydarzy?
Andrew Grimm

3
@Andrew: Tak, zredagowałem swoją odpowiedź, ponieważ 1.8.8 się nie wydarzy. Wciąż powinno być 1,8 głowy, ale ta gałąź jest martwa :-(
Marc-André Lafortune

84

myArray.sample(x) może również pomóc ci uzyskać x losowych elementów z tablicy.


6
Warto zauważyć, że my_array.sample (1)! = My_array.sample
Redithion

5
@Redithion Warto również zauważyć, że różnica między: my_array.sample (1) == [sample] i my_array.sample == sample, aby podać wyraźnie, co masz na myśli
Ekkstein


12

Losowa liczba losowych przedmiotów z tablicy

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

Przykłady możliwych wyników:

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

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

@fwilson losowe kolekcje obiektów w dowolnej kolejności. Również dobry do testowania różnych kombinacji lub generowania danych pośredniczących
Mike Rapadas

dlaczego nie rozszerzyć klasy Array? [] .total_random byłby o wiele fajniejszy. chodź rubin. jego cel!
Tim Kretschmer,

To nigdy nie zwróci pustej tablicy. Musisz umieścić 1 +w innym miejscu.
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)]

Zwróci losowy element z tablicy.

Jeśli skorzystasz z linii wymienionej poniżej

arr[1+rand(arr.count)]

w niektórych przypadkach zwróci wartość 0 lub zero.

Linia wymieniona poniżej

rand(number)

zawsze zwracaj wartość od 0 do liczby-1.

Jeśli użyjemy

1+rand(number)

wtedy może zwrócić liczbę, a arr [liczba] nie zawiera elementu.


-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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.