Randomizing Position in an Array

I’m trying to randomize an array, and this is what I have:

arr_set_unordered = randomizer(arr_set)

def randomizer(arr)
result = arr.collect { arr.slice!(rand arr.length) }
end

It does randomize it, but it only returns 3 values instead of the
necessary 5 that are in the arr_set array. Any ideas why?

Thank you!

Please try:
http://www.google.com/search?rls=en&q=array+shuffle+ruby

-Rob

On Dec 22, 2006, at 4:51 AM, jwcooper wrote:

It does randomize it, but it only returns 3 values instead of the
necessary 5 that are in the arr_set array. Any ideas why?

Thank you!

Rob B. http://agileconsultingllc.com
[email protected]

Just to save you a little time:

myarr = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
myarr.sort_by { rand }
=> [5, 3, 2, 4, 1]

–Jeremy

On 12/22/06, jwcooper [email protected] wrote:

It does randomize it, but it only returns 3 values instead of the
necessary 5 that are in the arr_set array. Any ideas why?

Thank you!


My free Ruby e-book:
http://www.humblelittlerubybook.com/book/

My blogs:

http://www.rubyinpractice.com/

Jeremy McAnally wrote:

Just to save you a little time:

myarr = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]

myarr.sort_by { rand }
=> [5, 3, 2, 4, 1]

–Jeremy

This doesn’t seem to belong in a rails discussion, but I was curious and
looked at performance. It seems the elegant ways are not the best. See
ruby code below.

Stephan

Timing different way to shuffle an array in ruby

class Array

The ruby way of swapping two variable values

def swap!(a,b)
self[a], self[b] = self[b], self[a]
end

the “assembler” way of swapping two variable values

def swap_with_int_var!(a,b)
c = self[a]
self[a] = self[b]
self[b] = c
end

Shuffling arrays is usually done by iterating through the indices,

and swapping

each value with a value at a random position

shuffling based on push/delete

def shuffle!
size.downto(1) { |n| push delete_at(rand(n)) }
self
end

shuffling with the ruby way of swapping

def shuffle_II
(size-1).downto(1) { |n| swap!(n, rand(size)) }
self
end

shuffling with the “assembler” way of swapping

def shuffle_III
(size-1).downto(1) { |n| swap_with_int_var!(n, rand(size)) }
self
end

def shuffle_IV
sort_by { rand }
end

end

def time_shuffle_method(size)
a = (0…size).to_a

start_time = Time.new
3000.times { yield a }
end_time = Time.new

return end_time - start_time
end

To inspect shuffling methods, invoke with argument “test” and

optionally, size
if (ARGV[0] == ‘test’)
size = ARGV[1] ? ARGV[1].to_i : 5
puts (0…size).to_a.shuffle!
puts ‘–’
puts (0…size).to_a.shuffle_II
puts ‘–’
puts (0…size).to_a.shuffle_III
puts ‘–’
puts (0…size).to_a.shuffle_IV

exit
end

shuffle_time = time_shuffle_method(500) { |a| a.shuffle! }
puts “Time elapsed for shuffle! : #{shuffle_time}”

shuffle_time_II = time_shuffle_method(500) { |a| a.shuffle_II }
puts “Time elapsed for shuffle_II : #{shuffle_time_II}”

shuffle_time_III = time_shuffle_method(500) { |a| a.shuffle_III }
puts “Time elapsed for shuffle_III : #{shuffle_time_III}”

shuffle_time_IV = time_shuffle_method(500) { |a| a.shuffle_IV }
puts “Time elapsed for shuffle_IV : #{shuffle_time_IV}”

=begin

Here are results from running on my machine

Conclusion: fancy ruby manipulations take their time
Stick with the “ordinary” shuffle implementation ( shuffle_III )

stephan@[/tmp]: ruby shuffle_timer
Time elapsed for shuffle! : 4.319548
Time elapsed for shuffle_II : 5.956232
Time elapsed for shuffle_III : 3.011474
Time elapsed for shuffle_IV : 3.672521
stephan@[/tmp]: ruby shuffle_timer
Time elapsed for shuffle! : 4.30994
Time elapsed for shuffle_II : 5.902858
Time elapsed for shuffle_III : 3.139915
Time elapsed for shuffle_IV : 3.692018

Stephan W.
January 2007

=end

Very cool, and very useful information. I appreciate everyones help in
this!

I did a lot of searching on google, but came up empty, so I am thankful
for this help.

My situation isn’t extremely time sensitive, but I’m glad to know a
simple solution such as the 3rd, or 4th option will work well.