I am trying to compare an array of externally defined Objects. I was hoping I would be able to do a simple .difference
, a function that was introduced in Ruby 2.6.0 but after looking at it: https://ruby-doc.org/core-2.6/Array.html#method-i-difference I'm not sure I can specify a custom comparison.
Okay assuming we have a simple Object Num
# Pretend we don't have access to this, just for reference
class Num
def initialize(val)
@val = val
end
def val
@val
end
end
And I have two arrays, one is a subset of the other. I want to find what the subset is missing. In this following example I want the difference to be the Object with value 3, since it doesn't exist in the subset.
all = [Num.new(1), Num.new(2), Num.new(3)]
subset = [Num.new(1), Num.new(2)]
The default .difference
function compares using .eql?
between the two objects so the difference does not give the expected result:
all.difference(subset)
=> [#<Num:0x00007fcae19e9540 @val=1>, #<Num:0x00007fcae19e9518 @val=2>, #<Num:0x00007fcae19e94f0 @val=3>]
I was able to create my own custom hacky solution to properly give me the values I want:
def custom_difference(all, subset)
diff = all.reject { |all_curr|
subset.find{ |subset_curr|
subset_curr.val == all_curr.val
} != nil
}
end
custom_difference(all, subset)
=> [#<Num:0x00007fcae19e94f0 @val=3>]
But I want to know if there's anyway to utilize the existing .difference
function, I was trying to use like this as well in order to override the way the two objects are compared:
all.difference(subset) { |a, b|
a.val <=> b.val
}
=> [#<Num:0x00007fcae19e9540 @val=1>, #<Num:0x00007fcae19e9518 @val=2>, #<Num:0x00007fcae19e94f0 @val=3>]
But this doesn't do anything to adjust the way the comparison occurs (AFAIK) Am I doing something wrong? Is this just not possible? :'(