Como eu escolho aleatoriamente uma matriz?

559

Quero saber se existe uma maneira muito mais limpa de fazer isso. Basicamente, quero escolher um elemento aleatório de uma matriz de comprimento variável. Normalmente, eu faria assim:

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

Existe algo mais legível / mais simples para substituir a segunda linha? Ou essa é a melhor maneira de fazê-lo. Suponho que você poderia myArray.shuffle.first, mas vi apenas #shufflealguns minutos atrás no SO, ainda não o usei.

Paul Hoffer
fonte
13
Boa resposta abaixo, mas um ponto geral sobre a reprodução aleatória. Eu imaginaria que o preenchimento de toda a matriz seria muito mais intenso do que apenas obter um número aleatório, para que não fosse uma boa direção a seguir.
Derek Órgão

Respostas:

1127

Basta usar Array#sample:

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

Está disponível no Ruby 1.9.1+. Para poder usá-lo também com uma versão anterior do Ruby, você poderia require "backports/1.9.1/array/sample".

Observe que no Ruby 1.8.7 ele existe sob o nome infeliz choice; foi renomeado na versão posterior, portanto você não deve usá-lo.

Embora não seja útil nesse caso, sampleaceita um argumento numérico caso você queira um número de amostras distintas.

Marc-André Lafortune
fonte
1
Eu deveria saber que você teria uma resposta perfeita para mim (já que a maioria das perguntas sobre Ruby que navego aqui tem sua opinião em algum lugar). Fico feliz que você apontou o versionamento; Estou usando o 1.9.2. apidock (comentário de mladen) não possui amostra; nem ruby-doc. Na sua opinião, qual é a melhor referência para Ruby, atualizada para 1,9?
Paul Hoffer
Em uma nota lateral, é adequado alterar a "resposta correta" depois que eu tiver selecionado outra resposta pela primeira vez?
Paul Hoffer
1
Thanks :-) E sim, ele é encorajado (veja meta.stackexchange.com/questions/19448/... )
Marc-André Lafortune
Notei sua edição removendo a menção de 1.8.8. Ele ainda está disponível no 1.8-head e você está apenas editando a pergunta porque o 1.8.8 não acontece?
Andrew Grimm
3
@ Andrew: Sim, editei minha resposta porque a 1.8.8 não acontecerá. Ele ainda deve estar em 1,8-cabeça, mas esse ramo está morto :-(
Marc-André Lafortune
84

myArray.sample(x) também pode ajudá-lo a obter x elementos aleatórios da matriz.

beesasoh
fonte
6
Ele worths observando que my_array.sample (1) = my_array.sample!
Redithion
5
@Redithion É importante notar também, que a diferença entre: my_array.sample (1) == [amostra] e my_array.sample == amostra para fornecer explicitamente o que quer dizer
Ekkstein
14
myArray.sample

retornará 1 valor aleatório.

myArray.shuffle.first

também retornará 1 valor aleatório.

JJ21
fonte
26
O shuffle é supérfluo.
superluminary
1
Tecnicamente este método aleatório é correta muito stackoverflow.com/a/84747/2047418
Filip Bartuzi
12

Número aleatório de itens aleatórios de uma matriz

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

Exemplos de resultados possíveis:

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

=> ["two", "three"]
=> ["one", "three", "two"]
=> ["two"]
Mike Rapadas
fonte
@fwilson coleções aleatórias de objetos em qualquer ordem. Também é bom para testar combinações diferentes ou gerar dados stub
Mike Rapadas
por que não estender a classe Array? [] .total_random seria muito mais legal. Venha seu rubi. seu objetivo!
Tim Kretschmer
Isso nunca retornaria uma matriz vazia. Você precisa colocar 1 +em um 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)]

Isso retornará um elemento aleatório da matriz.

Se você usar a linha mencionada abaixo

arr[1+rand(arr.count)]

em alguns casos, ele retornará 0 ou valor nulo.

A linha mencionada abaixo

rand(number)

sempre retorne o valor de 0 ao número 1.

Se usarmos

1+rand(number)

então ele pode retornar number e arr [number] não contém nenhum elemento.

Muhammad Aamir
fonte
-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
Caronte IV
fonte