Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

comparing two hashes

by Cody Pendant (Prior)
on Feb 24, 2002 at 06:06 UTC ( [id://147150]=perlquestion: print w/replies, xml ) Need Help??

Cody Pendant has asked for the wisdom of the Perl Monks concerning the following question:

I've got a situation where there are a hundred items, either true or false.

I've got the old list of which ones are true or false, and I've edited it using a web form, probably removing some from the "true" list and adding others to it.

Having submitted the form, what's the best way to reset the list correctly?

I did it like this:

I made a hash of 100 entries all set to zero, then did a foreach on the list of old items, and set the right values to 1.

Then I made a hash of 100 entries all set to zero and did a foreach loop on the list of new items, setting the right values to 1.

Then I went through the hash keys like this:

foreach $entry(@a){ if ($oldhash{$entry}==1 && $newhash{$entry}==0){ # push it into an array of deletions to be made } elsif($newhash{$entry}==1 && $oldhash{$entry}==0){ # ditto array of additions to be made } }

I've been staring at this code for a while and I can't figure out if that's a dumb way to do it or not, but it feels kind of dumb.

Is there a smarter way?
--

Edit: chipmunk 2002-02-24

Replies are listed 'Best First'.
Re: comparing two hashes
by chipmunk (Parson) on Feb 24, 2002 at 06:24 UTC
    What you're really trying to do is subtract one set from another set. Hashes are the right tool, but this can be done with slices instead of loops.
    # find old values that are not in new values my %deletions; @deletions{@oldvalues} = (); delete @deletions{@newvalues}; my @deletions = keys %deletions; # find new values that are not in old values my %additions @additions{@newvalues} = (); delete @additions{@oldvalues}; my @additions = keys %additions;

    Update: fixed hash names.

      chipmunk is right that hashes are the right tool to use here. However, there are some instances when hashes are not usable:

      • When you need to preserve the order of the data
      • If you have duplicate keys.

      I have had quite a lot of success with Algorithm::Diff. See also Re: Comparing Elements of Two Arrays.


      That looks very much smarter and I'm sure it works, but can you (or anyone) please explain it a little more?

      What is

      @deletions{@oldvalues} = ();
      doing? I didn't know you could create hashes that way!

      Also, what's "%tmp"? --

        Thats something called a hash slice.This is used to refer to (and/or operate on) multiple hash elements at the same time.
        hth
Re: comparing two hashes
by Cody Pendant (Prior) on Feb 25, 2002 at 00:13 UTC
    Is it bad form to come back and answer my question? I looked at "comparing two arrays" in categorised Q and A, and dumbed it down a little to this:
    # List pair which has one old item to be deleted, # and one new item to be added: @oldlist = ( 1,3,5,7,9 ); @newlist = ( 3,5,7,9,11 ); foreach $item(@oldlist){ $old{$item}=1; } foreach $item(@newlist){ $new{$item}=1; } # Find the stuff that's on both lists: my @bothlists = grep {defined $new{$_}} @oldlist; print "Stuff on both lists: @bothlists\n"; # Find the stuff that's on the old but not the new list: my @deletions = grep {!defined $new{$_}} @oldlist; print "Stuff on old but not on new (needs deleting): @deletions\n"; # Find the stuff that's on the new but not the old list: my @additions = grep {!defined $old{$_}} @newlist; print "Stuff on new but not on old (needs adding) @additions\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://147150]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (6)
As of 2024-04-18 03:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found