想象一个包含类似这样的类:
class Element
include Comparable
attr_accessor :name, :pos_x, :pos_y
def initialize(name, pos_x, pos_y)
@name = name
@pos_x = pos_x
@pos_y = pos_y
end
def <=>(other)
if (@pos_x == other.pos_x) and (@pos_y == other.pos_y)
return 0
else
return @name <=> other.name
end
end
def eql?(other)
self == other
end
end
在这种情况下,您将如何实现 hash
函数使得 a.hash == b.hash
?一般来说,我会这样做:
def hash
@name.hash
end
但这不包括pos_x
和pos_y
。
最佳答案
不幸的是,在这种情况下,在数学上不可能定义有效的哈希函数。
设a,b为两个位置相等、名称不同的元素。根据 eql?
的定义,这意味着 h(a) == h(b)
。由于这对于任何名称值都是正确的,因此哈希函数将独立于名称属性,但这与第二个检查相矛盾。因此,这个 eql?
定义没有散列函数。对不起。 :(
更新:
如 toro2k 所述 - 您的相等性定义不可传递。一般来说,如果 a == b 且 b == c,则要求 a == c。根据您的 eql?
函数:
{pos_x: 1, pos_y: 1, name: 'a'} == {pos_x: 1, pos_y: 1, name: 'b'}
{pos_x: 1, pos_y: 1, name: 'b'} == {pos_x: 2, pos_y: 2, name: 'b'}
但是
{pos_x: 1, pos_y: 1, name: 'a'} != {pos_x: 2, pos_y: 2, name: 'b'}
这就是问题的根源。
关于ruby - 如何为包含可比较的类定义哈希函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22276046/