How to merge two lists and remove duplicates in ruby ​​/ rails?

I have a source object where

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

and I have the following:

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

I would like to combine the two lists and start pulling items from external_sources if they already exist in the list of sources. I'm not sure how to do it eloquently?

I also tried:

 sources | external_sources 

but does this give a result without removing duplicates because my == comparison wants to compare the 'url' attribute inside? For instance:

 [src1] == [src2] # true list = [src1] | [src2] list.size # 2 
+4
source share
2 answers

I'm not sure what you mean by "merge" (there is no #merge method on arrays, only on hashes), but you can simplify your code as follows:

 merged = sources | external_sources 

To make it work with your class, you need two more methods: #hash (the hash of the instance used to pre-screen equality) and #eql? used to confirm equality:

 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 and #eql? are one of the fixed assets that every class should have. After adding them, methods #| and #& will start behaving on arrays of Source instances.

+3
source

Another option is to use the #uniq method. However, for bare #uniq , the same caveat applies as for the #| : #hash and #eql? used to verify identical elements.

However, uniq can take a block , so

 (sources + external_sources).uniq &:url 

can be applied even if lazy to define #hash and #eql? for the class in question.

+5
source

Source: https://habr.com/ru/post/1483991/


All Articles