Ruby - 使用Comparable mixin比较两个不同属性上的对象

时间:2011-11-14 15:14:03

标签: ruby comparable

是否有一种简单的方法(即使用宇宙飞船运营商)根据两个不同的属性在Ruby中定义比较?即如果我有一个包含两个属性的类,attr1和attr2,是否有一种Rubyesque方法在attr1上比较这个类的两个实例,如果它们相等则在attr2上比较它们?

3 个答案:

答案 0 :(得分:13)

这是一种易于扩展(更多属性)的方式:

def <=>(other)
  [self.attr1, self.attr2] <=> [other.attr1, other.attr2]
end

答案 1 :(得分:7)

可比混合的重点是为宇宙飞船(比较)操作员提供定义。因此,如果您想跨两个属性进行比较,那就去做吧。这是一个过于冗长的例子:

def <=>(obj)
  comparison = self.attr1 <=> obj.attr1

  if comparison == 0
    return self.attr2 <=> obj.attr2
  else
    return comparison
  end
end

显然上面假设attr1attr2都有太空船运营商的定义。同样,你需要确定什么构成大于,小于两个属性可能有点困难。这表明可比较可能不适合您的方案。

<小时/> 一种更为简洁和惯用的写作方式是:

def <=>(obj)
  self.attr1 <=> obj.attr1 == 0 ? self.attr2 <=> obj.attr2 : self.attr1 <=> obj.attr1
end

答案 2 :(得分:2)

太空船与'不具有可比性'

Spaceship requires:

a <=> b :=
  if a < b then return -1
  if a = b then return  0
  if a > b then return  1
  if a and b are not comparable then return nil  <= I wanted this

当'不具有可比性'时,Steenslag的解决方案并没有给我零。

Impementation

增加额外的行以应对'不具有可比性':

def <=> other
  return nil unless other.is_a?(self.class)
  [self.attr1, self.attr2] <=> [other.attr1, other.attr2]
end