我有一个源对象
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
答案 0 :(得分:5)
另一种选择是使用#uniq
方法。但是,对于裸#uniq
,同样的警告适用于#|
方法:#hash
和#eql?
按顺序用于测试相同的元素。
但是,uniq
can take a block,所以
(sources + external_sources).uniq &:url
即使一个人懒得为相关课程定义#hash
和#eql?
方法,也可以应用。
答案 1 :(得分:3)
我不确定“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?
是每个班级应具备的基本设施。添加这些后,#|
和#&
方法将开始在Source
个实例的数组上运行。