in reply to Need advice on hashes and methods

One way (perhaps a little brute-force) is to step through one of the hashes, and deleting entries from both hashes that match. When the dust settles, you'll have all the people in each hash that are not in the other hash. Try something like this (untested) snippet:

foreach (keys %firsthash) { if (exists($secondhash{$_})) { delete($firsthash{$_}; delete($secondhash{$_}; } }

No good deed goes unpunished. -- (attributed to) Oscar Wilde

Replies are listed 'Best First'.
Re^2: Need advice on hashes and methods
by tom2112 (Novice) on Aug 15, 2006 at 13:55 UTC
    Thanks guys! Since these are membership lists, and I need to know who cancelled their membership (would be on first list, but not on second list), and who are the new members (would be on second list, but not on first). So, I would probably want something like this:
    foreach (keys %firsthash) { if (exists($secondhash{$_})) { delete($firsthash{$_}; } } foreach (keys %secondhash) { if (exists($firsthash{$_})) { delete($secondhash{$_}; } }
    The result would be that I would have cancelled members in the firsthash and new members in the second hash. Right?

      Yeah, I suppose that would work, too. The code sample I gave you would work (and is a little more efficient for large lists, since you're only iterating through the list of keys once, instead of twice.) Essentially you want to eliminate the intersection of the two hashes, I think -- and either way will work.

      Update: As you pointed out below, the first foreach removes elements from the first hash, so the second foreach fails to detect matches. Better stick with the single-pass solution. Thanks for pointing that out! :)

        Ooops. My idea wouldn't work, since the first loop is destructive of the first hash, by the time it got to the second hash, it would think that they were all new members. Your single loop should do it correctly, now that I really think about it!