我正在尝试将自定义对象放入集合中。我尝试过:
require 'set'
class Person
include Comparable
def initialize(name, age)
@name = name
@age = age
end
attr_accessor :name, :age
def ==(other)
@name == other.name
end
alias eql? ==
end
a = Person.new("a", 18)
b = Person.new("a", 18)
people = Set[]
people << a
people << b
puts a == b # true
似乎Set
不能使用Object#eql?
或==
方法标识相同的对象:
puts people # #<Set: {#<Person:0x00007f9e09843df8 @name="a", @age=18>, #<Person:0x00007f9e09843da8 @name="a", @age=18>}>
Set
如何识别两个相同的对象?
答案 0 :(得分:5)
来自docs:
Set
使用Hash
作为存储,因此必须注意以下几点:
- 元素的相等性是根据
Object#eql?
和Object#hash
确定的。 [...]
那是说:如果您希望两个人在同名时是平等的,那么您必须相应地实现hash
:
def hash
@name.hash
end
答案 1 :(得分:3)
Ruby的内置Set
将项目存储在Hash
中。因此,对于Set
将对象视为“相同”的对象,还需要定义一个自定义hash
方法。这样的事情会起作用:
def hash
@name.hash
end
使用gem which set.rb
查看Set
的源代码的存储位置,然后尝试通读它。它很清楚而且写得很好。