4

我有一个源对象

class Source

def ==(other)
  return false if self.url == nil || other == nil
  self.url == other.url
end

我有以下内容:

def self.merge_internal_and_external_sources(sources=[], external_sources=[])
    (sources + external_sources).uniq
end

我想合并这两个列表,如果它们已经存在于源列表中,则开始从 external_sources 中踢出项目。我不确定如何雄辩地做到这一点?

我也试过:

sources | external_sources

但这会产生一个结果而不会因为我的 == 比较而删除重复项想要在内部比较 'url' 属性?例如:

[src1] == [src2] # true
list = [src1] | [src2] 
list.size # 2
4

2 回答 2

5

另一种选择是使用#uniq方法。但是,对于 bare #uniq,同样的警告适用于#|method:#hash并按#eql?顺序用于测试相同的元素。

但是,uniq 可以占用一个 block,所以

(sources + external_sources).uniq &:url

即使一个人懒于为相关类定义#hash#eql?方法,也可以应用。

于 2013-06-02T00:52:13.860 回答
3

我不确定“合并”是什么意思(#merge数组上没有方法,只有哈希值),但是您可以像这样简化代码:

merged = sources | external_sources

要使其与您的类一起使用,您还需要两个方法:(#hash实例哈希值,用于初步相等性筛选)和#eql?,用于确认相等性:

class Source
  def hash
    url.hash + 1
  end
  # Or delegate it to the url:
  # require 'active_support/core_ext/module/delegation'
  # delegate :hash, to: :url

  def eql? other
    return false if url.nil? || other.url.nil?
    url == other.url
  end
end

#hash并且#eql?是每个班级都应该拥有的基本设施之一。添加这些之后,#|方法将开始在实例#&数组上运行。Source

于 2013-06-02T00:37:51.733 回答