BuddyJoe
BuddyJoe

Reputation: 71111

Ruby - return an array in random order

What is the easiest way to return an array in random order in Ruby? Anything that is nice and short that can be used in an IRB session like

[1,2,3,4,5].random()
# or 
random_sort([1,2,3,4,5])

Upvotes: 5

Views: 7708

Answers (3)

Brian Hempel
Brian Hempel

Reputation: 9094

If you don't have [].shuffle, [].sort_by{rand} works as pointed out by sepp2k. .sort_by temporarily replaces each element by something for the purpose of sorting, in this case, a random number.

[].sort{rand-0.5} however, won't properly shuffle. Some languages (e.g. some Javascript implementations) don't properly shuffle arrays if you do a random sort on the array, with sometimes rather public consequences.

JS Analysis (with graphs!): http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html

Ruby is no different! It has the same problem. :)

#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]]

Each element should occur in each position about 20000 times. [].sort_by(rand) gives much better results.

#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]]

Similarly for [].shuffle (which is probably fastest)

[[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]]

Upvotes: 5

dierre
dierre

Reputation: 7218

What about this?

Helper methods for Enumerable, Array, Hash, and String that let you pick a random item or shuffle the order of items.

http://raa.ruby-lang.org/project/rand/

Upvotes: 1

christian
christian

Reputation: 401

array.shuffle

Upvotes: 19

Related Questions