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/