Code Snippet: Array.shuffle

Ask a Question related to Ruby, Design and Development.

  1. #1

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

  2. Similar Questions and Discussions

    1. Email Site-Wide Error message (with code snippet)
      I would like to create a Site-Wide error message that is emailed to the administrator. I have a lot of the information I want to put in but I can...
    2. A code snippet: Controlled retry
      I sometimes find myself retrying operations when in a networked situation (e.g., maybe server isn't up, just try again). I just wrote this little...
    3. #25247 [Fbk->NoF]: Shuffle() method doesn't work properly
      ID: 25247 Updated by: sniper@php.net Reported By: jeroen at kesh dot nl -Status: Feedback +Status: ...
    4. #25247 [NEW]: Shuffle() method doesn't work properly
      From: jeroen at kesh dot nl Operating system: Windows 2000 Server PHP version: 4.3.3 PHP Bug Type: Arrays related Bug...
    5. Ruby Code Snippet: Array.count
      On Sat 05 Jul 2003 at 08:01:38 +0900, Stefan Arentz wrote: This is already available with Enumerable#find_all: a = (1..10).to_a puts...
  3. #2

    Default Re: Code Snippet: Array.shuffle

    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
    Jason Creighton Guest

  4. #3

    Default Re: Code Snippet: Array.shuffle


    "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


    Joe Gwozdecki Guest

  5. #4

    Default Re: Code Snippet: Array.shuffle

    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.

    Brian Candler Guest

  6. #5

    Default Re: Code Snippet: Array.shuffle


    "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


    Joe Gwozdecki Guest

  7. #6

    Default Re: Code Snippet: Array.shuffle

    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)

    Brian Candler Guest

  8. #7

    Default Re: Code Snippet: Array.shuffle


    "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


    Joe Gwozdecki Guest

  9. #8

    Default Re: Code Snippet: Array.shuffle

    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 Guest

  10. #9

    Default Re: Code Snippet: Array.shuffle

    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'
    It's not Array.[], but Kernel#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

    Mauricio Fernández Guest

  11. #10

    Default Re: Code Snippet: Array.shuffle

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

  12. #11

    Default Re: Code Snippet: Array.shuffle

    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 [](*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.

    Brian Candler Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139