Question

Je suis en train de remplacer l'opérateur de Ruby <=> (vaisseau spatial) pour les pommes et les oranges tri afin que les pommes viennent d'abord triés en poids, et les oranges seconde, triées par douceur. Comme ceci:

module Fruity
  attr_accessor :weight, :sweetness

  def <=>(other)
    # use Array#<=> to compare the attributes
    [self.weight, self.sweetness] <=> [other.weight, other.sweetness]
  end
  include Comparable
end

class Apple
include Fruity

def initialize(w)
  self.weight = w
end

end

class Orange
include Fruity

def initialize(s)
  self.sweetness = s
end

end

fruits = [Apple.new(2),Orange.new(4),Apple.new(6),Orange.new(9),Apple.new(1),Orange.new(22)]

p fruits

#should work?
p fruits.sort

Mais cela ne fonctionne pas, quelqu'un peut-il dire ce que je fais mal ici, ou une meilleure façon de le faire?

Était-ce utile?

La solution

Votre problème est que vous n'initialise l'une des propriétés de chaque côté, l'autre sera toujours nil. nil n'a pas été traité dans le procédé de Array#<=>, qui finit par tuer le tri.

Il y a quelques façons de traiter d'abord le problème serait quelque chose comme ceci

[self.weight.to_i, self.sweetness.to_i] <=> [other.weight.to_i, other.sweetness.to_i]

nil.to_i vous donne 0, qui laissera ce travail.

Autres conseils

Probablement fin, quand même ...

ajouter le suivant monkey-patch

class Array
  def to_i(default=Float::INFINITY)
    self.map do |element|
      element.nil? ? default : element.to_i
    end
  end
end

Et changer le corps de Fruity::<=> to

[self.weight, self.sweetness].to_i <=> [other.weight, other.sweetness].to_i
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top