From: Daniel Harple Date: 2006-03-09T01:15:48+09:00 Subject: Re: Newbie: sorting an array of custom objects On Mar 8, 2006, at 3:48 PM, Einar H�st wrote: > That solution requires some_field to be 'naturally' ordered, > though, doesn't it? (I'm very new to Ruby...) What if some_field > contains a string, and I want 'Oranges' to be sorted before > 'Apples'? Actually, I'm writing a card game, so I want 'Spades' < > 'Hearts' < 'Clubs' < 'Diamonds'. > > - Einar As mentioned, you should use the Comparable mix-in. class Card include Comparable SUITES = %w{Spade Heart Club Diamond} VALUES = %w{Ace King Queen Jack} + ("1".."10").to_a.reverse def initialize(suite, value) @suite, @value = suite, value end attr_reader :suite, :value def <=>(card) if @suite == card.suite VALUES.index(@value) <=> VALUES.index(card.value) else SUITES.index(@suite) <=> SUITES.index(card.suite) end end end and full example of a Card game skeleton: require 'pp' module CardGame class Deck def initialize @cards = [] Card::SUITES.each do |suite| Card::VALUES.each { |v| @cards << Card.new(suite, v) } end # shuffle the deck @cards = @cards.sort_by { rand } end def draw_card @cards.pop end end class Card include Comparable SUITES = %w{Spade Heart Club Diamond} VALUES = %w{Ace King Queen Jack} + ("1".."10").to_a.reverse def initialize(suite, value) @suite, @value = suite, value end attr_reader :suite, :value def <=>(card) if @suite == card.suite VALUES.index(@value) <=> VALUES.index(card.value) else SUITES.index(@suite) <=> SUITES.index(card.suite) end end end class Hand def initialize @cards = [] end def <<(card) @cards << card @cards.sort! @cards end end end deck = CardGame::Deck.new hand1 = CardGame::Hand.new hand2 = CardGame::Hand.new # Draw some cards 3.times do hand1 << deck.draw_card hand2 << deck.draw_card end pp hand1, hand2 __END__ -- Daniel