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

发布于 2024-12-15 04:27:57 字数 151 浏览 3 评论 0原文

有没有一种简单的方法(即使用 spaceship 运算符)来定义 Ruby 中基于两个不同属性的比较?即,如果我有一个包含两个属性(attr1 和 attr2)的类,是否有一种 Rubyesque 方法可以在 attr1 上比较该类的两个实例,如果它们相等,则在 attr2 上比较它们?

Is there an easy way (i.e. using the spaceship operator) to define comparison in Ruby based on two different attributes? I.e. If I have a class that contains two attributes, attr1 and attr2, is there a Rubyesque way of comparing two instances of this class on attr1, and if they're equal then compare them on attr2?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

多情癖 2024-12-22 04:27:57

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

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

This is an easily extendible (to more attributes) way:

def <=>(other)
  [self.attr1, self.attr2] <=> [other.attr1, other.attr2]
end
故事灯 2024-12-22 04:27:57

可比较 mixin 的全部目的是为宇宙飞船(比较)运算符提供定义。因此,如果您想对两个属性进行比较,那就这样做吧。这是一个过于冗长的示例:

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

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

显然,上面假设 attr1attr2 都有太空船运算符的定义。此外,您还需要确定什么构成大于和小于,这对于两个属性来说可能有点困难。这表明可比较的代码可能不适合您的场景。


A more succinct and idiomatic way of writing this would be:

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

The whole point of the comparable mixin is to provide a definition for the spaceship (comparison) operator. So if you want to do a comparison across two attributes, then do it. Here's an overly verbose example:

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

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

Obviously the above assumes attr1, and attr2 both have definitions for the spaceship operator. As well you'll need to determine what constitutes greater than, and less than, which is likely a bit difficult across two attributes. Which suggests that comparable may not be the proper code for your scenario.


A more succinct and idiomatic way of writing this would be:

def <=>(obj)
  self.attr1 <=> obj.attr1 == 0 ? self.attr2 <=> obj.attr2 : self.attr1 <=> obj.attr1
end
南七夏 2024-12-22 04:27:57

太空飞船具有“不可比较”

太空飞船要求:

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

Spaceship with 'not comparable'

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's solution wasn't giving me the nil when 'not comparable'.

Impementation

Added extra line for coping with 'not comparable':

def <=> other
  return nil unless other.is_a?(self.class)
  [self.attr1, self.attr2] <=> [other.attr1, other.attr2]
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文