From: Robert Klemme Date: 2011-07-16T21:25:44+09:00 Subject: Fwd: Comparing hashes based on their keys 1st send attempt died in spamassassin... ---------- Forwarded message ---------- From: Robert Klemme Date: Sat, Jul 16, 2011 at 12:21 AM Subject: Re: Comparing hashes based on their keys To: ruby-talk@ruby-lang.org On Fri, Jul 15, 2011 at 9:47 PM, Rob Biedenharn wrote: > On Jul 15, 2011, at 3:01 PM, Stefano Mioli wrote: > >> On 7/15/11 7:18 PM, Rob Biedenharn wrote: >> >> class Hash >>  def same_key_structure?(other) >>   return false unless other.is_a?(Hash) >>   return false unless self.keys == other.keys && >> self.keys.all?{|_|_.is_a?(Symbol)} >>   self.keys.all? {|_|self[_].is_a?(Hash) ? >> self[_].same_key_structure?(other[_]) : !other[_].is_a?(Hash)} >>  end >> end >> >> >> Now that I think about it, that >> >>        self.keys == other.keys >> >> might cause problems, because I didn't specify (sorry, my bad) that I >> don't care about which order the keys appear in. >> >> In other words, I consider these two hashes to be equal: >> >>        h1 = {:x => nil, :y => nil} >>        h2 = {:y => nil, :x => nil} >> >> but h1.keys == h2.keys would return false in this context. > >  then sort them: > >  return false unless self.keys.sort == other.keys.sort There is one reason to not sort: Hash keys are not required to implement <=>.  Now, we "know" that keys will be only Symbols but what if not?  You might see an exception from #sort.  Comparing via Set would be more robust here since we know that keys fulfill the requirements for a Set element.  So that would be return false unless keys.to_set == other.keys.to_set Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/