Kirschstein
Kirschstein

Reputation: 14868

Comparing items based on their index in an array in Ruby

I have a Card class and I want to overload the > operator to compare against another card (Ace is higher than king, king higher than queen, etc). I've forgotten what little I ever knew about Ruby and don't have a clue where to start.

class Card
  @@RANKS = ['A', 'K', 'Q', 'J', 'T', '9', '8','7','6','5','4','3','2']
  attr_reader :rank

  def initialize(str)
    @rank = str[0,1]
  end

  def > (other)
    #?????
  end
end

Upvotes: 0

Views: 645

Answers (3)

Evolve
Evolve

Reputation: 9193

I would agree with darrint.

All you need do is include Comparable and define <=> and then you will be able to do all the other comparisons for free! Giving you a lot more flexibility than just defining '>' on it's own.

In the words of the pickaxe book: "The Comparable mixin can be used to add the comparison operators (<, <=, ==, >=, and >), as well as the method between?, to a class. For this to work, Comparable assumes that any class that uses it defines the operator <=>. So, as a class writer, you define the one method, <=>, include Comparable, and get six comparison functions for free."

A full example is available in the (free online) pickaxe book: http://ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html#S2 (scroll down a couple of paragraphs to 'Mixins give you a wonderfully controlled way..')

Upvotes: 2

darrint
darrint

Reputation: 418

You might be happier if you define the spaceship operator instead of greater than. (<=>)

Sorting, for instance, depends on it being defined.

http://ruby-doc.org/ruby-1.9/classes/Enumerable.html

Upvotes: 5

Brian McKenna
Brian McKenna

Reputation: 46218

You can use the array.index method. The following code checks the index of both cards and returns true if the other card appears after the current card.

class Card
  @@RANKS = ['A', 'K', 'Q', 'J', 'T', '9', '8','7','6','5','4','3','2']
  attr_reader :rank

  def initialize(str)
    @rank = str[0,1]
  end

  def > (other)
    @@RANKS.index(other.rank) > @@RANKS.index(@rank)
  end
end

ace = Card.new 'A'
king = Card.new 'K'
nine = Card.new '9'

puts ace > king
puts ace > nine
puts nine > king

Upvotes: 1

Related Questions