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

-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!

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

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

and swapping

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