Остановить добавление дубликатов в массив объектов Ruby - PullRequest
2 голосов
/ 10 мая 2010

как я могу удалить дубликаты элементов из массива объектов ruby, используя атрибут объекта для соответствия идентичным объектам.

с массивом базовых типов, я могу использовать набор ..

например.

array_list = [1, 3, 4 5, 6, 6]
array_list.to_set 
=> [1, 2, 3, 4, 5, 6]

можно ли адаптировать эту технику для работы с атрибутами объекта?

спасибо

Ответы [ 5 ]

3 голосов
/ 10 мая 2010

Я думаю, ты ставишь телегу перед лошадью. Вы спрашиваете себя: «Как я могу заставить uniq удалить объекты, которые не равны?» Но то, что вы должны задать себе: «Почему эти два объекта не равны, несмотря на то, что я считаю их такими?»

Другими словами: кажется, что вы пытаетесь обойти тот факт, что ваши объекты имеют нарушенную семантику равенства, когда то, что вы действительно должны сделать, это просто исправление этой нарушенной семантики равенства .

Вот пример для Product, где два продукта считаются равными, если они имеют одинаковый номер типа:

class Product
  def initialize(type_number)
    self.type_number = type_number
  end

  def ==(other)
    type_number == other.type_number
  end

  def eql?(other)
    other.is_a?(self.class) && type_number.eql?(other.type_number)
  end

  def hash
    type_number.hash
  end

  protected

  attr_reader :type_number

  private

  attr_writer :type_number
end

require 'test/unit'
class TestHashEquality < Test::Unit::TestCase
  def test_that_products_with_equal_type_numbers_are_considered_equal
    assert_equal 2, [Product.new(1), Product.new(2), Product.new(1)].uniq.size
  end
end
2 голосов
/ 10 мая 2010

Если вы можете записать его в свои объекты для использования eql?, тогда вы можете использовать uniq.

0 голосов
/ 11 мая 2010

Если вы используете Array или вместо него Set?Если порядок не важен, то последний сделает более эффективным поиск дубликатов.

0 голосов
/ 10 мая 2010

спасибо за ваши ответы .. Uniq работает, как только я добавил следующее в мою объектную модель

def ==(other)
    other.class == self.class &&
    other.id  == self.id
end
alias :eql? :==
0 голосов
/ 10 мая 2010

как насчет uniq

   a = [ "a", "a", "b", "b", "c" ]
   a.uniq   #=> ["a", "b", "c"]

Вы можете использовать его и на объекте!

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