Code Snippet: Array.shuffle

Here is another small Ruby code snippet that extends the Array class. Use
this to randomize the order of all entries in an Array.

class Array
def shuffle
self.each_index { |i| r = rand(self.length - 1);
self[i],self[r] = self[r],self[i] }
end
end

Works like this:

a = Array[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a.shuffle
==> [7, 10, 9, 6, 4, 8, 5, 3, 1, 2]

S.

Stefan Arentz wrote:

Here is another small Ruby code snippet that extends the Array class. Use
this to randomize the order of all entries in an Array.

class Array
def shuffle
self.each_index { |i| r = rand(self.length - 1);
self[i],self[r] = self[r],self[i] }
end
end

Works like this:

a = Array[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a.shuffle
==> [7, 10, 9, 6, 4, 8, 5, 3, 1, 2]

S.

This seems like a relevant discussion:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/19125

Chad

Here is another small Ruby code snippet that extends the Array class. Use
this to randomize the order of all entries in an Array.

class Array
def shuffle
self.each_index { |i| r = rand(self.length - 1);
self[i],self[r] = self[r],self[i] }
end
end

Works like this:

a = Array[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a.shuffle
==> [7, 10, 9, 6, 4, 8, 5, 3, 1, 2]

ary = (0…10).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ary.sort { rand(3)-1 }
=> [4, 6, 5, 0, 2, 3, 9, 7, 8, 1, 10]

…of course, this probably won’t produce as random as result, but it’s easier to implement.

Jason Creighton

···

On 08 Jul 2003 03:01:30 +0200 Stefan Arentz stefan.arentz@soze.com wrote:

rand(x) gives a number between 0 and x-1, so I think you should use
rand(self.length) not rand(self.length-1). In particular this will work
properly for arrays containing 1 element.

You could also replace self.each_index and self.length with
each_index and length, respectively. And you don’t need the semicolon.

Regards,

Brian.

···

On Tue, Jul 08, 2003 at 10:21:42AM +0900, Stefan Arentz wrote:

Here is another small Ruby code snippet that extends the Array class. Use
this to randomize the order of all entries in an Array.

class Array
def shuffle
self.each_index { |i| r = rand(self.length - 1);
self[i],self[r] = self[r],self[i] }
end
end

“Brian Candler” B.Candler@pobox.com wrote in message
news:20030708063637.GA74975@uk.tiscali.com

Here is another small Ruby code snippet that extends the
Array class. Use
this to randomize the order of all entries in an Array.

class Array
def shuffle
self.each_index { |i| r = rand(self.length - 1);
self[i],self[r] = self[r],self[i] }
end
end

rand(x) gives a number between 0 and x-1, so I think you
should use
rand(self.length) not rand(self.length-1). In particular
this will work
properly for arrays containing 1 element.

You could also replace self.each_index and self.length
with
each_index and length, respectively. And you don’t need
the semicolon.

Regards,

Brian.

How come when I try out this code snippet in IRB, including
entering the array, it does nothing? Am I missing
something?

Joe Gwozdecki
Houston, Texas

···

On Tue, Jul 08, 2003 at 10:21:42AM +0900, Stefan Arentz wrote:

I don’t know. Here’s an irb session log:

$ irb
irb(main):001:0> class Array
irb(main):002:1> def shuffle
irb(main):003:2> each_index { |i| r = rand(length)
irb(main):004:3> self[i],self[r] = self[r],self[i] }
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> a = [1,2,3,4,5,6,7,8,9,10]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):008:0> a.shuffle
=> [8, 7, 1, 4, 9, 10, 3, 2, 6, 5]
irb(main):009:0> a.shuffle
=> [7, 10, 5, 9, 8, 1, 6, 3, 4, 2]
irb(main):010:0>

What did you do differently? Note that if you miss a bracket or an ‘end’
then irb may think you are in a continuation line; if the prompt ends with
an asterisk this is a pretty strong clue.

irb(main):012:0> [
irb(main):013:1* 1,2,3
irb(main):014:1> ]
=> [1, 2, 3]

Regards,

Brian.

···

On Wed, Jul 09, 2003 at 06:05:28AM +0900, Joe Gwozdecki wrote:

How come when I try out this code snippet in IRB, including
entering the array, it does nothing? Am I missing
something?

“Brian Candler” B.Candler@pobox.com wrote in message
news:20030708224157.GA75351@uk.tiscali.com

How come when I try out this code snippet in IRB,
including
entering the array, it does nothing? Am I missing
something?

I don’t know. Here’s an irb session log:

$ irb
irb(main):001:0> class Array
irb(main):002:1> def shuffle
irb(main):003:2> each_index { |i| r = rand(length)
irb(main):004:3> self[i],self[r] = self[r],self[i] }
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> a = [1,2,3,4,5,6,7,8,9,10]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):008:0> a.shuffle
=> [8, 7, 1, 4, 9, 10, 3, 2, 6, 5]
irb(main):009:0> a.shuffle
=> [7, 10, 5, 9, 8, 1, 6, 3, 4, 2]
irb(main):010:0>

What did you do differently? Note that if you miss a
bracket or an ‘end’
then irb may think you are in a continuation line; if the
prompt ends with
an asterisk this is a pretty strong clue.

irb(main):012:0> [
irb(main):013:1* 1,2,3
irb(main):014:1> ]
=> [1, 2, 3]

Regards,

Brian.

Your coding works fine in IRB. The original poster wrote a
= Array[1,2,3,4,5,6,7,8,9,10] which did not work. Get rid
of “Array” and it works.

Joe Gwozdecki
Houston, Texas

···

On Wed, Jul 09, 2003 at 06:05:28AM +0900, Joe Gwozdecki wrote:

It looks OK to me:

irb(main):001:0> a = Array[1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):002:0>

(this is 1.6.8)

···

On Wed, Jul 09, 2003 at 08:46:38AM +0900, Joe Gwozdecki wrote:

Your coding works fine in IRB. The original poster wrote a
= Array[1,2,3,4,5,6,7,8,9,10] which did not work. Get rid
of “Array” and it works.

“Brian Candler” B.Candler@pobox.com wrote in message
news:20030709073944.GA75875@uk.tiscali.com

Your coding works fine in IRB. The original poster
wrote a
= Array[1,2,3,4,5,6,7,8,9,10] which did not work. Get
rid
of “Array” and it works.

It looks OK to me:

irb(main):001:0> a = Array[1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):002:0>

(this is 1.6.8)

I got the error from – a = array[1,2,3,4,5]
IRB will give a consistent error.
You are right. a = Array[1,2,3,4,5] does
work just fine. Also a = [1,2,3,4,5] does too
and is probably cleaner.

Joe Gwozdecki
Houston, Texas

···

On Wed, Jul 09, 2003 at 08:46:38AM +0900, Joe Gwozdecki wrote:

Certainly. Ruby is case-sensitive. You need to call method of ‘Array’,
not ‘array’

Cheers,

Brian.

···

On Wed, Jul 09, 2003 at 08:50:59PM +0900, Joe Gwozdecki wrote:

It looks OK to me:

irb(main):001:0> a = Array[1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):002:0>

(this is 1.6.8)

I got the error from – a = array[1,2,3,4,5]
IRB will give a consistent error.

It’s not Array., but Kernel#Array.

···

On Wed, Jul 09, 2003 at 09:35:22PM +0900, Brian Candler wrote:

On Wed, Jul 09, 2003 at 08:50:59PM +0900, Joe Gwozdecki wrote:

It looks OK to me:

irb(main):001:0> a = Array[1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):002:0>

(this is 1.6.8)

I got the error from – a = array[1,2,3,4,5]
IRB will give a consistent error.

Certainly. Ruby is case-sensitive. You need to call method of ‘Array’,
not ‘array’


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Software is like sex; it’s better when it’s free.
– Linus Torvalds

You sure? This is Kernel#Array:

 Array(5)   #>>  [5]

 Array(5,6) #>>  ArgumentError: wrong # of arguments(2 for 1)

I believe that foo[bar] is a shortcut for

foo.send(:[], bar)

And therefore Array[1,2,3,4,5] is

Array.send(:[], 1, 2, 3, 4, 5)
#=> [1, 2, 3, 4, 5]

or equivalently

Array.[] (1,2,3,4,5)
#=> [1, 2, 3, 4, 5]

i.e. this is a class (singleton) method of Array

Regards,

Brian.

···

On Wed, Jul 09, 2003 at 09:45:33PM +0900, Mauricio Fernández wrote:

I got the error from – a = array[1,2,3,4,5]
IRB will give a consistent error.

Certainly. Ruby is case-sensitive. You need to call method of ‘Array’,
not ‘array’

It’s not Array., but Kernel#Array.

I got the error from – a = array[1,2,3,4,5]
IRB will give a consistent error.

Certainly. Ruby is case-sensitive. You need to call method of ‘Array’,
not ‘array’

It’s not Array., but Kernel#Array.

You sure? This is Kernel#Array:

Shouldn’t have asserted this so strongly as it turns out… I was wrong :stuck_out_tongue:

Anyway, this is yet another case of significant spaces in Ruby:

class << Array
alias_method :old, :;
?> def
puts “Array.
old(*a)
end
end
=> nil
Array[1,2,3]
Array.
=> [1, 2, 3]
Array [1,2,3]
=> [1, 2, 3]

BTW, irb needs the ‘;’ at the end of the second line:

class << Array
alias_method :old, :
?> def
puts “Array.
old(*a)
end
SyntaxError: compile error
(irb):6: syntax error
from (irb):6

bug?

···

On Wed, Jul 09, 2003 at 10:02:40PM +0900, Brian Candler wrote:

On Wed, Jul 09, 2003 at 09:45:33PM +0900, Mauricio Fernández wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

‘Ooohh… “FreeBSD is faster over loopback, when compared to Linux
over the wire”. Film at 11.’
– Linus Torvalds

Ah, I see: foo[bar] => foo. (bar)
foo [bar] => foo( [bar] )

Yuk. This exists in 1.6.8. I guess it mirrors Matz’s change introduced for
1.8:
foo(a+b).c => ( foo(a+b) ).c
foo (a+b).c => foo( (a+b).c )

As for the semicolon, it seems that irb does not play nicely with unusual
symbols:

$ irb
irb(main):001:0> :ok
=> :ok
irb(main):002:0> :
irb(main):003:0* puts “oops”
oops
=> nil
irb(main):004:0>

Cheers,

Brian.

···

On Thu, Jul 10, 2003 at 12:16:59AM +0900, Mauricio Fernández wrote:

Anyway, this is yet another case of significant spaces in Ruby:

class << Array
alias_method :old, :;
?> def
puts “Array.
old(*a)
end
end
=> nil
Array[1,2,3]
Array.
=> [1, 2, 3]
Array [1,2,3]
=> [1, 2, 3]