在Ruby中制作对象哈希的最佳方法?

时间:2014-11-02 00:28:35

标签: ruby

所以我有一个类,其中我需要覆盖相等运算符。这不是那么难。但是除非my_obj.hash对于要比较的两个对象相同,否则不会使用自定义相等运算符。所以我们需要覆盖hash()

我有点坚持这样做的最好方法。我的对象嵌入了其他三个对象实例。我通过示例看到,对于简单的实例变量,您可以自己获取变量的哈希值:

[var1, var2, var3].hash

更具体地说,我的班级有三个嵌入对象的实例变量,让我们调用它们:

一个 B1 B2

如果

,我的对象的两个实例是相等的
object1.B1 == object2.B1 && object1.B2 == object2.B2 || 
      object1.B1 == object2.B2 && object1.B2 == object2.B1

换句话说,B1和B2的集合中包含相同的两个对象,无论它们被分配给哪个特定的变量。

B1和B2也有自定义的相等机制。

我不清楚在这里覆盖hash()的最佳策略。

如果示例是抽象的,我很抱歉,我试图避免发布大量代码。

3 个答案:

答案 0 :(得分:2)

尝试使用Set而不是数组,因此顺序并不重要。你必须把这一行放在最上面:

require 'set'

然后创建一个包含两个对象的Set,并使用它来帮助实现相等运算符和哈希方法。我假设Set #hap行为正确,您可以在哈希方法中使用它。 Set#==可用于简化相等运算符。

http://www.ruby-doc.org/stdlib-2.1.4/libdoc/set/rdoc/Set.html

答案 1 :(得分:1)

您的B1B2对象是否可以排序?如果是这样,您可以轻松实现hash方法:

class MyClass
  def hash
    return [self.B1, self.B2].sort.hash
  end
end

如果它们目前无法排序,按任何固有价值排序是没有意义的,您可以随时按object_id排序:

class BClass
  include Comparable

  def <=> (other)
    case other
    when BClass then return (self.object_id <=> other.object_id)
    else return nil
    end
  end
end

这使您的B1B2对象可以相互排序,同时抛出&#34; ArgumentError:X与Y的比较失败&#34; 与任何其他类的实例。

如果您正在使用object_id的路线,那么使用该方法开始实施hash方法可能更容易:

class MyClass
  def hash
    return [self.B1.object_id, self.B2.object_id].sort.hash
  end
end

但这意味着只有自相同的对象才会正确地显示为相同,而不仅仅是那些&#34;看起来&#34;一样。要理解我的意思,请比较以下内容:

# Comparison of look-alike objects
"a".object_id == "a".object_id  # => false

# Comparison of self-same objects
a = "a"
a.object_id == a.object_id      # => true

答案 2 :(得分:-1)

我假设哈希值可以是任何对象,只要它在您的案例中的每个对象中都是唯一的。如果该假设是正确的,那么如何定义对象hash()方法如何作为数组返回?

我并不是100%清楚你想要实现的目标。但我已经解释了self.B1self.B2的顺序并不重要。那么这是一种可能性:

def hash
  [self.B1.hash, self.B2.hash].sort
end

然后您可以将两个对象的hash()

进行比较
(my_obj1.hash == my_obj2.hash)