Reputation: 2807
I'm trying to compare and find the difference between two nested hashes with multiple hash arrays within arrays.
What is the best way to go about this comparison? It appears there are no libraries or functions that can help with this..
For example, I want the below two examples of hash a and hash b to be considered equal.
pry(main)> a
#⇒ {"197315"=>{:qty=>1,
# :modifiers=>[{"197323-197319"=>{:qty=>1}},
# {"197322-197321"=>{:qty=>1}}]}}
pry(main)> b
#⇒ {"197315"=>{:qty=>1,
# :modifiers=>[{"197322-197321"=>{:qty=>1}},
# {"197323-197319"=>{:qty=>1}}]}}
pry(main)> a == b
#⇒ false
pry(main)> a
#⇒ {"197315"=>{:qty=>1,
# :modifiers=>[{"197322-197321"=>{
# :qty=>1,
# :modifiers=>['2222'=>'33333', '4444'=>'55555']}},
# {"197323-197319"=>{:qty=>1}}]}}
pry(main)> b
#⇒ {"197315"=>{:qty=>1,
# :modifiers=>[{"197322-197321"=>{
# :qty=>1,
# :modifiers=>['4444'=>'55555', '2222'=>'33333']}},
# {"197323-197319"=>{:qty=>1}}]}}
pry(main)> a == b
#⇒ false
Upvotes: 1
Views: 56
Reputation: 110675
This recursive solution should work with any number of levels of nested arrays and hashes.
Code
require 'set'
def arr_to_set(o)
case o
when Hash
o.each_with_object({}) { |(k,v),g| g[k] = arr_to_set(v) }
when Array
o.map { |e| arr_to_set(e) }.to_set
else
o
end
end
Examples
Example 1
a = {"197315"=>{:qty=>1, :modifiers=>[
{"197323-197319"=>{:qty=>1}},
{"197322-197321"=>{:qty=>1}}
]
}
}
b = {"197315"=>{:qty=>1, :modifiers=>[
{"197322-197321"=>{:qty=>1}},
{"197323-197319"=>{:qty=>1}}
]
}
}
arr_to_set(a) == arr_to_set(b)
#=> true
Example 2
c = {"197315"=>{:qty=>1,
:modifiers=>[
{"197322-197321"=>{ :qty=>1,
:modifiers=>['2222'=>'33333', '4444'=>'55555']
}
},
{"197323-197319"=>{:qty=>1}
}
]
}
}
d = {"197315"=>{:qty=>1,
:modifiers=>[
{"197322-197321"=>{:qty=>1,
:modifiers=>['4444'=>'55555', '2222'=>'33333']
}
},
{"197323-197319"=>{:qty=>1}
}
]
}
}
arr_to_set(c) == arr_to_set(d)
#=> true
Upvotes: 2