Pseudo-randomize an array in a consistent order

Here’s my final version in case anyone’s interested:

class Array

def randomize!(seed=nil)
srand(seed) if seed
i = length - 1
while (i > 0)
#have to specify Kernel::rand to avoid method name clash
j = Kernel::rand(i)
# Swap self[i] and self[j]
tmp = self[i]
self[i] = self[j]
self[j] = tmp
i -= 1
end
#reset srand
srand if seed
self
end

def randomize(seed=nil)
self.dup.randomize!(seed)
end

end

I encountered a puzzling gotcha with rand - it turns out that Rails
monkey-patches Array with ‘rand’ (no arguments) which pulls out a random
element. So, calling

j = rand(i)

was giving me a ‘too many arguments’ error, as it thought i was wanting
Array::rand. So, i just specify that i want Kernel::rand and it’s fine.

thanks again
max

On Fri, 4 Jul 2008, Max W. wrote:

  # Swap self[i] and self[j]

def randomize(seed=nil)
self.dup.randomize!(seed)
end

end

I don’t think it randomizes very well.

1000.times { puts “yes!” if [1,2].randomize == [1,2] }
=> 1000

I encountered a puzzling gotcha with rand - it turns out that Rails
monkey-patches Array with ‘rand’ (no arguments) which pulls out a random
element.

I’d describe that as a gotcha with Rails :slight_smile:

David

David A. Black wrote:

I don’t think it randomizes very well.

1000.times { puts “yes!” if [1,2].randomize == [1,2] }
=> 1000
David

Well spotted - this is the offending line:

j = Kernel::rand(i)

It means (effectively) that a number can never stay in the same place,
which breaks the randomness a bit (and totally breaks it for two-element
arrays). Changing it to this

j = Kernel::rand(i+1)

seems to fix it.

thanks!
max

It means (effectively) that a number can never stay in the same place,

Err by ‘number’ i mean ‘element’ of course (elements just happen to be
numbers in the example).

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs