如何在ruby / rails中合并两个列表并删除重复项?

我有一个源对象在哪里

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 

我不确定“merge”是什么#merge (数组上没有#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? 是每个class级应该具备的基本设施。 添加这些后, #|#&方法将开始在Source实例的数组上运行。

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

但是, uniq 可以占用一块 ,所以

 (sources + external_sources).uniq &:url 

即使懒惰定义#hash#eql?也可以应用#eql? 有关课程的方法。