¿Cómo elijo al azar de una matriz?


559

Quiero saber si hay una forma mucho más limpia de hacer esto. Básicamente, quiero elegir un elemento aleatorio de una matriz de longitud variable. Normalmente, lo haría así:

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

¿Hay algo que sea más legible / más simple para reemplazar la segunda línea? ¿O es esa la mejor manera de hacerlo? Supongo que podrías hacerlo myArray.shuffle.first, pero solo lo vi #shufflehace unos minutos en SO, en realidad aún no lo he usado.


13
Buena respuesta a continuación, pero un punto general sobre barajar. Me imagino que sufrir la matriz completa sería mucho más intenso que simplemente obtener un número aleatorio, por lo que no sería una buena dirección.
Derek Organ

Respuestas:


1127

Solo usa Array#sample:

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

Está disponible en Ruby 1.9.1+. Para poder usarlo con una versión anterior de Ruby, podría hacerlo require "backports/1.9.1/array/sample".

Tenga en cuenta que en Ruby 1.8.7 existe bajo el nombre desafortunado choice; fue renombrado en una versión posterior, por lo que no debe usar eso.

Aunque no es útil en este caso, sampleacepta un argumento numérico en caso de que desee varias muestras distintas.


1
Debería haber sabido que tendrías una respuesta perfecta para mí (ya que la mayoría de las preguntas de Ruby que busco aquí tienen tu opinión en alguna parte). Me alegra que hayas señalado el versionado; Estoy usando 1.9.2. apidock (comentario de mladen) no tiene muestra; tampoco lo hace ruby-doc. En su opinión, ¿cuál es la mejor referencia para Ruby, actualizada a 1.9?
Paul Hoffer

En una nota al margen, ¿es correcto cambiar la "respuesta correcta" después de haber seleccionado otra respuesta?
Paul Hoffer

1
Gracias :-) Y sí, se recomienda (ver meta.stackexchange.com/questions/19448/… )
Marc-André Lafortune

Noté que su edición eliminaba la mención de 1.8.8. ¿Todavía está disponible en 1.8-head, y solo está editando la pregunta porque 1.8.8 no sucederá?
Andrew Grimm

3
@ Andrew: Sí, edité mi respuesta porque 1.8.8 no sucederá. Todavía debería estar en 1.8 cabezas, pero esa rama está muerta :-(
Marc-André Lafortune

84

myArray.sample(x) También puede ayudarlo a obtener x elementos aleatorios de la matriz.


66
Vale la pena señalar que my_array.sample (1)! =
My_array.sample

55
@Redithion También vale la pena señalar, que la diferencia entre: my_array.sample (1) == [sample] y my_array.sample == sample para proporcionar explícitamente lo que quieres decir
Ekkstein


12

Número aleatorio de elementos aleatorios de una matriz

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

Ejemplos de posibles resultados:

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

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

@fwilson colecciones aleatorias de objetos en cualquier orden. También es bueno para probar diferentes combinaciones o generar datos de código auxiliar
Mike Rapadas

¿Por qué no extender la clase Array? [] .total_random sería mucho más genial. comeon su rubí. su objetivo!
Tim Kretschmer

Esto nunca devolvería una matriz vacía. Necesita colocar 1 +en un lugar diferente.
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)]

Esto devolverá un elemento aleatorio de la matriz.

Si va a utilizar la línea mencionada a continuación

arr[1+rand(arr.count)]

entonces en algunos casos devolverá 0 o valor nulo.

La línea mencionada abajo

rand(number)

siempre devuelve el valor de 0 a número-1.

Si usamos

1+rand(number)

entonces puede devolver un número y arr [número] no contiene ningún elemento.


-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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.