On Fri, Jul 15, 2011 at 5:38 PM, Stefano Mioli <stefano.mioli / gmail.com> wrote: > Hi list, > ¨Âåô§ó óá÷å ÷áîô ôï ÷òéôíåôèïä ôèáô ãïíðáòåó ô÷èáóèåó æïåñõáìéôù > based on their keys. > > Each key is a symbol, and the corrisponding value can either be a string or > another hash with this same properties. > > Two hashes, let's call them h1 and h2, are to be considered equal if: > > * they have the same keys > > * h1[:x] and h2[:x] are both hashes, and they are equal according to the > very same rules you are reading ;) > > * they are both nil It seems your spec is not very precise because your bullet list mixes AND and OR. I assume you meant Two objects o1 and o2 are considered equal for this relation if and only if ( o1 is nil AND o2 is nil ) OR ( o1 is a Hash AND o2 is a Hash AND o1.keys == o2.keys AND for each key k ( o1[k] is not a Hash OR o2[k] is not a Hash OR o1[k] equals o2[k] according to this relation ) ) > In short, we only care about the values when they are hashes. > If they are strings, we don't care whether they are equal or not. > > To make an example, when fed these two hashes the method should return true: > > h1 = { > one => "one", > two => "two", > three => { > alpha => "alpha", > bravo => "bravo", > charlie => "charlie" > ¨Â > } > > h2 = { > one => "whatever", > two => "hey", > three => { > alpha => "zulu", > bravo => "oscar", > charlie => "brown" > ¨Â > } > > When fed these other two arrays, the method should return false: > > h3 = h1 > > h4 = { > one => "one", > two => "two", > three => { > alpha => "alpha", > bravo => "bravo", > ¨Â > } > > The difference is that Ole :charlie is missing in h2. > The values don't change to make it clear that we don't care about them. > > I came up with the following implementation that seems to work (at least > according to the specs I wrote), but what I would like to ask is if it could > be any simpler/more idiomatic/more elegant. > > Corner cases that one might spot are also good to know about. > > def compare(hash1, hash2) I would rename arguments because these need not be Hashes. > ¨ÂòçÛèáóè±èáóè²Ý > > ¨Âåôõòôòõå éæ áòçó®áììûüèü è®îéì¿> ¨Âåôõòæáìóéæ áòçó®ïîåûüèü è®îéì¿> > ¨Âáóè±®åáãèßëåäï üë> ¨ÂáìõåÛèáóè±Ûëݬ èáóè²ÛëÝ> > ¨Âöáìõåó®áììûüèü è®éóßῨÈáóè©ý > ¨Âåôõòãïíðáò娪öáìõåó© > ¨Âìó> ¨Âåôõòæáìóéæ öáìõåó®ïîåûüöáìõåü öáìõå®îéì¿ > ¨Âîä > ¨Âîä > > ¨Âòõ> end Hm, I'd probably remove #all?, #any? and the like and code conditions directly - especially since you are always dealing with two items because it's likely faster. Your code creates a lot of temporary Arrays along the way. Btw, I believe your implementation misses the case where hash2's key set is a superset of hash1's, i.e. contains additional keys. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/