I want to get the union/intersect/difference from two arrays of hashes for example:
array1 = [{:name =>'Guy1', :age => 45},{:name =>'Guy2', :age => 45}]
array2 = [{:name =>'Guy1', :age => 45},{:name =>'Guy3', :age => 45}]
...
p array1 - array2
=> [{:name=>"Guy2", :age=>45}]
p array2 - array1
=> [{:name=>"Guy3", :age=>45}]
p array1 | array2
=> [{:name=>"Guy1", :age=>45}, {:name=>"Guy2", :age=>45}, {:name=>"Guy3", :age=>45}]
however when I want to only compare based on the names and ignore the ages without needing to remove them from the hashes for example:
array1 = [{:name =>'Guy1', :age => 45},{:name =>'Guy2', :age => 45}]
array2 = [{:name =>'Guy1', :age => 46},{:name =>'Guy3', :age => 45}]
In this case i'm not getting the results that I want b/c the ages are different.
array1 - array2
=> [{:name=>"Guy1", :age=>45}, {:name=>"Guy2", :age=>45}]
array2 - array1
=> [{:name=>"Guy1", :age=>46}, {:name=>"Guy3", :age=>45}]
array1 | array2
=> [{:name=>"Guy1", :age=>45}, {:name=>"Guy2", :age=>45}, {:name=>"Guy1", :age=>46}, {:name=>"Guy3", :age=>45}]
Is there a way to get the union/intersect/difference and ignore the age key?
edit: for a better example:
array1 = [{:name =>'Guy1', :age => 45},{:name =>'Guy2', :age => 45}]
array2 = [{:name =>'Guy1'},{:name =>'Guy3'}]
p array1 - array2
p array2 - array1
p array1 | array2
p array1 & array2
Thanks in advance for the help!
Here's a quick and dirty way of getting the union:
(array1 + array2).uniq{|a| a[:name]}
However, I would recommend creating your own subclass of Hash
so you can safely override eql?
as Cary Swoveland points out is what the set-like operators rely on. Note that you also need to limit the hash
method to only provide the hashing function on the name field.
class Guy < Hash
def eql?(other_hash)
self[:name] == other_hash[:name]
end
def hash
self[:name].hash
end
end
Then these Guy
objects will work in all of the set operations:
array1 = [ Guy[name:'Guy1', age: 45], Guy[name:'Guy2', age: 45] ]
array2 = [ Guy[name:'Guy1', age: 46], Guy[name:'Guy3', age: 45] ]
array1 - array2
#=> [{:name=>"Guy2", :age=>45}]
array2 - array1
#=> [{:name=>"Guy3", :age=>45}]
array1 | array2
#=> [{:name=>"Guy1", :age=>45}, {:name=>"Guy2", :age=>45}, {:name=>"Guy3", :age=>
45}]
array1 & array2
#=> [{:name=>"Guy1", :age=>45}]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With