Ruby Forum Ruby > Randomizing an Array?

Posted by jwcooper (Guest)
on 22.12.2006 20:42
(Received via mailing list)
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 5
values that I'm expecting.  Any ideas why?

Thank you!
Posted by Daniel Waite (rabbitcreative)
on 29.12.2006 21:15
jwcooper wrote:
> I'm trying to randomize an array...

Try this.

class Array

  def randomize
    duplicated_original, new_array = self.dup, self.class.new
    new_array << 
duplicated_original.slice!(rand(duplicated_original.size)) until 
new_array.size.eql?(self.size)
    new_array
  end

  def randomize!
    self.replace(randomize)
  end

end

Enjoy!
Posted by Daniel Waite (rabbitcreative)
on 29.12.2006 21:17
Sorry, I guess a use-case would be helpful.

Call #randomize or #randomize! on any array to mix up its elements.

[ 5, 10, 15, 20, 25 ].randomize # [25, 15, 5, 20, 10]
Posted by Dan Stevens (IAmAI) (Guest)
on 30.12.2006 16:34
(Received via mailing list)
I found a library called 'rand.rb':
http://raa.ruby-lang.org/project/rand/. It allows you to select an
element at random from an array and 'scramble' (randomize the order)
of them as well.

Description:

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

Examples with Array:

[1,2,3,4].pick
# => 2 (pick random element)

[1,2,3,4].shuffle
# => [2, 4, 1, 3] (return random-sorted version)

a = [1,2,3,4]
a.pick!
# => 3
a
# => [1,2,4] (remove the picked element)
Posted by Ilan Berci (iberci)
on 02.01.2007 17:36
jwcooper wrote:
> 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 5
> values that I'm expecting.  Any ideas why?
> 
> Thank you!

ilans-Mac:~ ilan$ irb
irb(main):001:0> (1..10).to_a.sort {rand}
=> [10, 6, 1, 7, 3, 8, 5, 9, 4, 2]
irb(main):002:0>
Posted by Florian Frank (Guest)
on 02.01.2007 22:04
(Received via mailing list)
Ilan Berci wrote:
> jwcooper wrote:
>   
>> I'm trying to randomize an array, and this is what I have:
>>     
[...]
> ilans-Mac:~ ilan$ irb
> irb(main):001:0> (1..10).to_a.sort {rand}
> => [10, 6, 1, 7, 3, 8, 5, 9, 4, 2]
> irb(main):002:0>
>   
Don't do this, better use (1..10).sort_by { rand }. Your version is
equivalent to (1..10).sort { 1 } and *always* creates the same
permutation for this array.
Posted by Daniel Waite (rabbitcreative)
on 09.01.2007 20:30
Florian Frank wrote:
>> irb(main):001:0> (1..10).to_a.sort {rand}
>> => [10, 6, 1, 7, 3, 8, 5, 9, 4, 2]

Wow. That is squeaky clean, and a lot faster than my method. Thanks for 
sharing. :)
Posted by Daniel Waite (rabbitcreative)
on 09.01.2007 20:34
Florian Frank wrote:
> Don't do this, better use (1..10).sort_by { rand }. Your version is
> equivalent to (1..10).sort { 1 } and *always* creates the same
> permutation for this array.

It's random for me. Both work.
Posted by Ilan Berci (iberci)
on 09.01.2007 22:00
Daniel Waite wrote:
> Florian Frank wrote:
>> Don't do this, better use (1..10).sort_by { rand }. Your version is
>> equivalent to (1..10).sort { 1 } and *always* creates the same
>> permutation for this array.
> 
> It's random for me. Both work.

Actually Frank is correct, my mistake, it should definetely be sort_by 
and not sort..  I should have reviewed it more thoroughly before 
responding..

ilan

Posted by Florian Frank (Guest)
on 09.01.2007 23:09
(Received via mailing list)
Daniel Waite wrote:
> Florian Frank wrote:
>> Don't do this, better use (1..10).sort_by { rand }. Your version is
>> equivalent to (1..10).sort { 1 } and *always* creates the same
>> permutation for this array.
> 
> It's random for me. Both work.

No, really, it isn't. It may "look random", but try sorting (1..10) many
times and ponder the coincidence.
Posted by Joao Silva (rubyforum)
on 15.05.2008 22:52
Florian Frank wrote:
> Daniel Waite wrote:
>> Florian Frank wrote:
>>> Don't do this, better use (1..10).sort_by { rand }. Your version is
>>> equivalent to (1..10).sort { 1 } and *always* creates the same
>>> permutation for this array.
>> 
>> It's random for me. Both work.
> 
> No, really, it isn't. It may "look random", but try sorting (1..10) many
> times and ponder the coincidence.

That's because sort{ foo } expects foo to be in -1,0,1.

rand() is always [0, 1).

rand(2)-1 is (-1,1) however and thus will work just fine. :)

One could do sort{rand <=> rand}, but that's ~9x slower by my testing.

irb(main):163:0> (1..10).to_a.sort{rand }
=> [10, 6, 1, 7, 3, 8, 5, 9, 4, 2]
irb(main):164:0> (1..10).to_a.sort{rand }
=> [10, 6, 1, 7, 3, 8, 5, 9, 4, 2]
irb(main):165:0> (1..11).to_a.sort{rand }
=> [11, 6, 1, 7, 3, 8, 5, 9, 4, 10, 2]
irb(main):166:0> (1..12).to_a.sort{rand }
=> [12, 7, 1, 8, 3, 9, 5, 10, 2, 11, 6, 4]

vs

irb(main):186:0> (1..12).to_a.sort{rand(2) -1}
=> [1, 2, 6, 11, 9, 4, 8, 7, 5, 10, 3, 12]
irb(main):187:0> (1..12).to_a.sort{rand(2) -1}
=> [1, 9, 8, 3, 5, 6, 11, 4, 2, 10, 7, 12]


 - Sai http://saizai.com, who is too lazy to remember his actual account 
pass right now
Posted by Robert Klemme (Guest)
on 16.05.2008 10:48
(Received via mailing list)
2008/5/15 Joao Silva <rubyforum@thisisnotmyrealemail.com>:
>> times and ponder the coincidence.
>
> That's because sort{ foo } expects foo to be in -1,0,1.

I don't think so - the sign is important:

irb(main):001:0> (1..10).sort { -1 }
=> [1, 2, 3, 7, 4, 9, 5, 8, 6, 10]
irb(main):002:0> (1..10).sort { 1 }
=> [10, 6, 1, 7, 3, 8, 5, 9, 4, 2]
irb(main):003:0> (1..10).sort { 10 }
=> [10, 6, 1, 7, 3, 8, 5, 9, 4, 2]
irb(main):004:0> (1..10).sort { -10 }
=> [1, 2, 3, 7, 4, 9, 5, 8, 6, 10]

> rand() is always [0, 1).

Did you mean [0,1[?

> rand(2)-1 is (-1,1) however and thus will work just fine. :)

rand(2)-1 is (-1,0). I would rather do rand(3)-1 or rand(2) - 0.5  -
But all this is worse than sort_by { rand } IMHO.

Kind regards

robert