[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Code Snippet: Array.shuffle

Stefan Arentz

7/8/2003 1:02:00 AM


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.

9 Answers

Jason Creighton

7/8/2003 1:52:00 AM

0

On 08 Jul 2003 03:01:30 +0200
Stefan Arentz <stefan.arentz@soze.com> 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]

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

Joe Gwozdecki

7/8/2003 8:49:00 PM

0


"Brian Candler" <B.Candler@pobox.com> wrote in message
news:20030708063637.GA74975@uk.tiscali.com...
> 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
>
> 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


Brian Candler

7/8/2003 10:39:00 PM

0

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?

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.

Joe Gwozdecki

7/8/2003 11:45:00 PM

0


"Brian Candler" <B.Candler@pobox.com> wrote in message
news:20030708224157.GA75351@uk.tiscali.com...
> 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?
>
> 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


Brian Candler

7/9/2003 7:37:00 AM

0

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.

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)

Joe Gwozdecki

7/9/2003 11:46:00 AM

0


"Brian Candler" <B.Candler@pobox.com> wrote in message
news:20030709073944.GA75875@uk.tiscali.com...
> 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.
>
> 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


Brian Candler

7/9/2003 12:35:00 PM

0

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

Cheers,

Brian.

Brian Candler

7/9/2003 1:03:00 PM

0

On Wed, Jul 09, 2003 at 09:45:33PM +0900, Mauricio Fern&#225;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.

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.

Brian Candler

7/9/2003 3:33:00 PM

0

On Thu, Jul 10, 2003 at 12:16:59AM +0900, Mauricio Fern&#225;ndez wrote:
> Anyway, this is yet another case of significant spaces in Ruby:
>
> >> class << Array
> >> alias_method :_old_, :[];
> ?> def [](*a)
> >> puts "Array.[]"
> >> _old_(*a)
> >> end
> >> end
> => nil
> >> Array[1,2,3]
> Array.[]
> => [1, 2, 3]
> >> Array [1,2,3]
> => [1, 2, 3]

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.