Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > hash differences

Reply
Thread Tools

hash differences

 
 
int
Guest
Posts: n/a
 
      09-15-2005
i have 2 hashes, %newer and %older. %newer is an update of the
data in %older. i would like to know:
1) which key, value pairs are in %newer but not %older
2) which key, value pairs are in %older but not %newer
3) which keys have different values in %older and %newer
4) which values have different keys in %older and %newer

wrote some code, it is messy, it is over 30 lines long lots
of foreach, if, else, blocks and it seems to have a problem
with case 4). looking for a perl idiomatic solution.

any suggestions appreciated.

 
Reply With Quote
 
 
 
 
William James
Guest
Posts: n/a
 
      09-15-2005
int wrote:
> i have 2 hashes, %newer and %older. %newer is an update of the
> data in %older. i would like to know:
> 1) which key, value pairs are in %newer but not %older
> 2) which key, value pairs are in %older but not %newer
> 3) which keys have different values in %older and %newer
> 4) which values have different keys in %older and %newer
>
> wrote some code, it is messy, it is over 30 lines long lots
> of foreach, if, else, blocks and it seems to have a problem
> with case 4). looking for a perl idiomatic solution.
>
> any suggestions appreciated.


I suggest using Ruby:

older = {
'aa', 11,
'bb', 22,
'cc', 33,
'dd', 44,
'ee', 55,
'ff', 66 }

newer = older.dup
newer['bb'] = 55 ; newer['ee'] = 22 ; newer['gg'] = 77

p ( newer.to_a - older.to_a ).sort
p ( older.to_a - newer.to_a ).sort
p (older.keys & newer.keys).reject{ |x| newer[x]==older[x] }.sort
p (older.values & newer.values).reject{ |x|
newer.index(x)==older.index(x)}.sort

-----------------------------------------------------------------

Output:

[["bb", 55], ["ee", 22], ["gg", 77]]
[["bb", 22], ["ee", 55]]
["bb", "ee"]
[22, 55]

 
Reply With Quote
 
 
 
 
Anno Siegel
Guest
Posts: n/a
 
      09-15-2005
int <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> i have 2 hashes, %newer and %older. %newer is an update of the
> data in %older. i would like to know:
> 1) which key, value pairs are in %newer but not %older
> 2) which key, value pairs are in %older but not %newer
> 3) which keys have different values in %older and %newer
> 4) which values have different keys in %older and %newer
>
> wrote some code, it is messy, it is over 30 lines long lots
> of foreach, if, else, blocks and it seems to have a problem
> with case 4). looking for a perl idiomatic solution.
>
> any suggestions appreciated.


Study the faq "How do I compute the difference of two arrays? ..."
(perldoc -q difference). It demonstrates the standard method of
doing this in Perl.

Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
Reply With Quote
 
Darren Dunham
Guest
Posts: n/a
 
      09-15-2005
int <(E-Mail Removed)> wrote:
> i have 2 hashes, %newer and %older. %newer is an update of the
> data in %older. i would like to know:
> 1) which key, value pairs are in %newer but not %older
> 2) which key, value pairs are in %older but not %newer
> 3) which keys have different values in %older and %newer
> 4) which values have different keys in %older and %newer


> wrote some code, it is messy, it is over 30 lines long lots
> of foreach, if, else, blocks and it seems to have a problem
> with case 4). looking for a perl idiomatic solution.


Well, case 4 is very different. The easiest way to do that is to build
a reverse hash, where each value is put into another hash as its key,
and the original key is the value. When you get to the second hash, you
know if it was in the first and what the key was. In addition, the
question is very difficult to answer if the values are not unique within
each of the original hashes.

I don't know if it's idiomatic or not, but here's how I'd do the first
3.

foreach $key (keys %hash1)
if exists $hash2{$key}
[ check case 3 and see if values are same or different ]
delete $hash2{$key}
else
[ record $key as existing only in hash1 ]

[all remaining keys in hash2 are unique to hash2]

--
Darren Dunham http://www.velocityreviews.com/forums/(E-Mail Removed)
Senior Technical Consultant TAOS http://www.taos.com/
Got some Dr Pepper? San Francisco, CA bay area
< This line left intentionally blank to confuse you. >
 
Reply With Quote
 
int
Guest
Posts: n/a
 
      09-15-2005
thanks for the suggestions. i agree, it's a difficult question
and it's not addressed in the faq. there is no guarantee
of uniqueness between hashes.

for example if

$older{aa}="alpha";
$older{bb}="beta";
$older{cc}="gamma";

then newer could be

1)
$newer{aa}="alpha";
$newer{bb}="beta";
$newer{cc}="gamma";
$newer{dd}="delta";

2)
$newer{aa}="alpha";
$newer{bb}="beta";

3)
$newer{aa}="alpha";
$newer{bb}="beta";
$newer{cc}="omega";

4)
$newer{aa}="alpha";
$newer{bb}="beta";
$newer{dd}="gamma";

5) some combination like
$newer{aa}="alpha";
$newer{cc}="omega";
$newer{dd}="gamma";
$newer{tt}="theta";

the ruby solution is ideal but unfortunately I'm trapped in
perl for this. here is pseudo code for my solution. it has
problems and it's too long. there has to be a better "perl"
way.

foreach my $k (keys %newer) {
if (! exists $older{$k}) {
# this is a new key
if (! map (/$newer{$k}/, keys reverse %older) ) {
# value is new too
print "new pair: $k, $newer{$k}\n";
}
else {
# new value for a pre-existing key
print "new key: $k, for value $older{$k}\n";
}
}
}
foreach my $k (keys %older) {
if (! exists $newer{$k}) {
# the key is gone
if (! map (/$older{$k}/, keys reverse %newer) ) {
# both key and value are gone
print "key, value pair removed: $k, $older{$k}\n";
}
else {
# new value for a pre-existing key should be here
# but alas, it isn't. why isn't it symmetric?
# need yet another foreach loop here
}
}
}



int

 
Reply With Quote
 
Mark Clements
Guest
Posts: n/a
 
      09-15-2005
int wrote:
> i have 2 hashes, %newer and %older. %newer is an update of the
> data in %older. i would like to know:
> 1) which key, value pairs are in %newer but not %older
> 2) which key, value pairs are in %older but not %newer
> 3) which keys have different values in %older and %newer
> 4) which values have different keys in %older and %newer


<snip and jump to later post>

> thanks for the suggestions. i agree, it's a difficult question
> and it's not addressed in the faq. there is no guarantee
> of uniqueness between hashes.


<snip>

>
> the ruby solution is ideal but unfortunately I'm trapped in
> perl for this. here is pseudo code for my solution. it has
> problems and it's too long. there has to be a better "perl"
> way.


Have you considered checking out Set::Hash and Set::Array? Requirements
1 and 2 are simple using Set::Hash (OK - they are fairly simple using
other methods), and you should be able to work something out for 3 and 4
using the provided set operations and building a reverse mapping as
suggested by Darren.

Mark
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
DEVELOP THE WINNING EDGE, SMALL DIFFERENCES IN YOUR PERFORMANCE CANLEAD TO LARGE DIFFERENCES IN YOUR RESULTS Home_Job_opportunity C Programming 0 01-14-2009 03:51 PM
DEVELOP THE WINNING EDGE, SMALL DIFFERENCES IN YOUR PERFORMANCE CANLEAD TO LARGE DIFFERENCES IN YOUR RESULTS Home_Job_opportunity C Programming 0 01-08-2009 04:31 PM
Hash#select returns an array but Hash#reject returns a hash... Srijayanth Sridhar Ruby 19 07-02-2008 12:49 PM
In 'HashMap.put', "if (e.hash == hash && eq(k, e.key))" ? Red Orchid Java 3 01-30-2006 07:04 PM



Advertisments