Forum: Ruby Randomizing an Array?

Posted by jwcooper (Guest)
on 2006-12-22 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 2006-12-29 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 2006-12-29 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 2006-12-30 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 2007-01-02 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 2007-01-02 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 2007-01-09 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 2007-01-09 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 2007-01-09 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 2007-01-09 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 2008-05-15 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 2008-05-16 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
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.