简体   繁体   中英

Compare Hash Arrays in Ruby

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM