Ruby - devolver uma matriz em ordem aleatória
Pergunta
Qual é a maneira mais fácil de devolver uma matriz em ordem aleatória em Ruby? Qualquer coisa que seja agradável e curta que possa ser usada em uma sessão de IRB como
[1,2,3,4,5].random()
# or
random_sort([1,2,3,4,5])
Solução
Se você não tem [] .Shuffle, [] .sort_by {rand} funciona como apontado por sepp2k. .sort_by substitui temporariamente cada elemento por algo com o objetivo de classificar, neste caso, um número aleatório.
] .Sort {RAND-0.5} No entanto, não vai embaralhar corretamente. Alguns idiomas (por exemplo, algumas implementações de JavaScript) não embaralham devidamente as matrizes se você fizer um tipo aleatório na matriz, com consequências às vezes bastante públicas.
Análise JS (com gráficos!): http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html
Ruby não é diferente! Tem o mesmo problema. :)
#sort a bunch of small arrays by rand-0.5
a=[]
100000.times{a << [0,1,2,3,4].sort{rand-0.5}}
#count how many times each number occurs in each position
b=[]
a.each do |x|
x.each_index do |i|
b[i] ||=[]
b[i][x[i]] ||= 0
b[i][x[i]] += 1
end
end
p b
=>
[[22336, 18872, 14814, 21645, 22333],
[17827, 25005, 20418, 18932, 17818],
[19665, 15726, 29575, 15522, 19512],
[18075, 18785, 20283, 24931, 17926],
[22097, 21612, 14910, 18970, 22411]]
Cada elemento deve ocorrer em cada posição cerca de 20000 vezes. [] .Sort_By (Rand) fornece resultados muito melhores.
#sort with elements first mapped to random numbers
a=[]
100000.times{a << [0,1,2,3,4].sort_by{rand}}
#count how many times each number occurs in each position
...
=>
[[19913, 20074, 20148, 19974, 19891],
[19975, 19918, 20024, 20030, 20053],
[20028, 20061, 19914, 20088, 19909],
[20099, 19882, 19871, 19965, 20183],
[19985, 20065, 20043, 19943, 19964]]
Da mesma forma para [] .Shuffle (que provavelmente é mais rápido)
[[20011, 19881, 20222, 19961, 19925],
[19966, 20199, 20015, 19880, 19940],
[20062, 19894, 20065, 19965, 20014],
[19970, 20064, 19851, 20043, 20072],
[19991, 19962, 19847, 20151, 20049]]
Outras dicas
array.shuffle
Que tal isso?
Métodos auxiliares para enumerável, matriz, hash e string que permitem escolher um item aleatório ou embaralhar a ordem dos itens.