Как Set в ruby ​​сравнивает элементы? - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь поместить пользовательские объекты в набор.Я попробовал это:

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 идентифицирует дваодни и те же объекты?

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Из документов :

Set использует Hash в качестве хранилища, поэтому вы должны отметить следующие моменты:

  • Равенствоэлементов определяется согласно Object#eql? и Object#hash.[...]

Тем не менее, если вы хотите, чтобы два человека были равны, если у них одинаковое имя, вы должны соответственно ввести hash:

def hash
  @name.hash
end
0 голосов
/ 20 ноября 2018

Встроенный в Ruby Set хранит элементы в Hash.Таким образом, чтобы Set обрабатывал ваши объекты как "одинаковые", вам также необходимо определить собственный метод hash.Примерно так будет работать:

def hash
  @name.hash
end

Используйте gem which set.rb, чтобы увидеть, где хранится исходный код Set, и попробуйте прочитать его.Это ясно и хорошо написано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...