是否有一种简单的方法(即使用 spaceship 运算符)在 Ruby 中基于两个不同的属性定义比较?即,如果我有一个包含两个属性 attr1 和 attr2 的类,是否有一种 Rubyesque 方法可以在 attr1 上比较此类的两个实例,如果它们相等,则在 attr2 上比较它们?
问问题
3653 次
3 回答
15
这是一种易于扩展(更多属性)的方式:
def <=>(other)
[self.attr1, self.attr2] <=> [other.attr1, other.attr2]
end
于 2013-01-15T20:26:48.220 回答
7
可比较 mixin 的全部意义在于为 spaceship(比较)运算符提供定义。因此,如果您想对两个属性进行比较,那就去做吧。这是一个过于冗长的示例:
def <=>(obj)
comparison = self.attr1 <=> obj.attr1
if comparison == 0
return self.attr2 <=> obj.attr2
else
return comparison
end
end
显然,以上假设attr1
,并且attr2
两者都具有宇宙飞船运算符的定义。您还需要确定什么构成大于和小于,这在两个属性中可能有点困难。这表明可比较的代码可能不适合您的场景。
一种更简洁和惯用的写法是:
def <=>(obj)
self.attr1 <=> obj.attr1 == 0 ? self.attr2 <=> obj.attr2 : self.attr1 <=> obj.attr1
end
于 2011-11-14T15:24:33.880 回答
2
具有“不可比性”的宇宙飞船
宇宙飞船需要:
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 的解决方案并没有给我零。
实施
为处理“不可比较”添加了额外的行:
def <=> other
return nil unless other.is_a?(self.class)
[self.attr1, self.attr2] <=> [other.attr1, other.attr2]
end
于 2014-08-14T17:28:21.600 回答