Shuffling an Array

Problem

You want to put the elements of an array in random order.

Solution

The simplest way to shuffle an array (in Ruby 1.8 and above) is to sort it randomly:

	[1,2,3].sort_by { rand } # => [1, 3, 2]

This is not the fastest way, though.

Discussion

It's hard to beat a random sort for brevity of code, but it does a lot of extra work. Like any general sort, a random sort will do about n log n variable swaps. But to shuffle a list, it suffices to put a randomly selected element in each position of the list. This can be done with only n variable swaps.

	class Array
	 def shuffle! 
	 each_index do |i| 
	 j = rand(length-i) + i
	 self[j], self[i] = self[i], self[j] 
	 end
	 end

	 def shuffle 
	 dup.shuffle! 
	 end
	end

If you're shuffling a very large list, either Array#shuffle or Array#shuffle! will be significantly faster than a random sort. Here's a real-world example of shuffling using Array#shuffle:

	class Card
	 def initialize(suit, rank)
	 @suit = suit 
	 @rank = rank 
	 end

	 def to_s
	 "#{@suit} of #{@rank}"
	 end
	end

	class Deck < Array
	 attr_reader :cards 
	 @@suits = %w{Spades Hearts Clubs Diamonds}
	 @@ranks = %w{Ace 2 3 4 5 6 7 8 9 10 Jack Queen King} 

	 def initialize
	 @@suits.each { |suit| @@ranks.each { |rank| self << Card.new(rank, suit) } }
	 end
	end

	deck = Deck.new
	deck.collect { |card| card.to_s }
	# => ["Ace of Spades", "2 of Spades", "3 of Spades", "4 of Spades",…]
	deck.shuffle! 
	deck.collect { |card| card.to_s }
	# => ["6 of Clubs", "8 of Diamonds", "2 of Hearts", "5 of Clubs",…]

 

See Also

  • Recipe 2.5, "Generating Random Numbers"
  • The Facets Core library provides implementations of Array#shuffle and Array#shuffle!


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net