Hash

P

Pradeep Patra

Hi all,
I have a questions of comparing two hashes.

%hash1={a=>2,b=>3,c=>4,d=>5}
%hash2={a=>7,b=>8,c=>9,d=>0)

I have to ensure that from %hash2 the value is increased by 5(2->7 and
3->8) for "a","b". I dont want to compare the all the values of
hash2(for exp-d=0).I want to push this to a library(preferably a
single method) so that I can reuse it. Is there a better way to do
this?.

Can anybody help me in this regard? Any source code will be of great
help.


Regards
Pradeep
 
R

Rainer Weikusat

[...]
I think you want to make sure that the values of hash2 for
keys 'a' and 'b' are 5 more than the corresponding values in hash1.
Here's some code that does that, but it's trivial, so I think there
must be more to it than that!

#!/usr/bin/perl
use strict;
use warnings;

my %hash1 = (a=>2,b=>3,c=>4,d=>5);
my %hash2 = (a=>7,b=>5,c=>9,d=>0);

for ( qw(a b) ) {
print "$_: Not increased by 5\n" unless $hash2{$_} == $hash1{$_}+5;
}

In case of exactly two comparisons known at compile time, using a
logical operator usually makes more sense. Also, your variable names
are by far not verbose enough. I suggest

my %first_hash_table_using_modified_bernstein_hash;
my %second_hash_table_also_using_modified_bernstein_hash;

Remember, the more words (or letters) you need to express
trivialities, the less likely it will be that your audience notices
that (before falling asleep, that is ...)
 
P

Pradeep Patra

Are you trying to be funny?  You certainly don't seem to be trying to be
helpful to the OP.

Thanks Henry for you kind help. Sorry for the confusion.To be more
clear:

I have a %hash1 = { 'total' => '15',
'success' => '15',
'error' => '0',
'percent' => '10%'
};

After some operations performed the %hash1 has values populated with
new values for some of the keys(for exp: total,success,percent) and
that result to %hash2.

Lets say modified %hash2 is as follows.

%hash2 = { 'total' => '20',
'success' => '20',
'error' => '0',
'percent' => '15%'
};


Note: hash2 has modified values for (success,total and percent) was
increased by 5.I want to ensure that the 'error' still 0(between hash1
and hash2).

I want to write a function for example:

hash_compare(hash1,hash2)
{
if hash2's success counter is increased by 5 for
total,success,percent return success;
if hash2's error counter > 0 return fail;


}

It can be done 2 ways we need 2 foreach loops to loop through the
"keys of hash1" and then "keys of hash2" and then match keys to
retrieve values from hash1 and hash2 and then see that it increased by
5. Is there a better way to do this? Code snippet to perform this will
be useful.


Regards
Pradeep
 
R

Rainer Weikusat

Henry Law said:
Are you trying to be funny? You certainly don't seem to be trying to
be helpful to the OP.

In the sense that the code you posted was technically capable of
solving the problem, this would be much better expressed as

my %h0 = (a=>2,b=>3,c=>4,d=>5);
my %h1 = (a=>6,b=>5,c=>9,d=>0);

print "$_: Not increased by 5\n" if
($_ = 'a', $h0{a} + 5 != $h1{a})
|| ($_ = 'b', $h0{b} + 5 != $h1{b});

instead of using a loop with a fixed number of iterations. Otherwise,
this should be put into a subroutine which could work with any two
hashes, instead of only hashes named %hash1 and %hash2 which happen to
have keys named 'a' and 'b', but the problem specification of the OP
is too incomplete for that (what should happen in case of non-isomorph
hashes?).

Also %hash1 is a singularly bad choice for a variable name in Perl
since the fact that this is a hash is already communicated by the
sigil and 'hash' doesn't communicate anything of interest about this
hash and the only difference to simply naming it %h1 is that this lack
of useful information is 'encoded' in a more verbose way.

Coming to think of that, and even more efficient way to ensure thay
any poor soul who might have to work with your code (not the fictional
'maintenance programmer' who deserves to be tortured with any
conceivable contortion but a *real* person) will curse your name till
the end of times would be to use factually incorrect/ misleading
verbose noise as variable names, ie,

my %array1 = (a,2,b,3,c,4,d,5); # You can't catch me!

BTW, this is a literary device which is known as 'parody' and it is
supposed to draw attention to some shortcoming of something by
exaggerating that into absurdity (a hyberbole). This even includes the
Chuck Berry allusion.
 
R

Rainer Weikusat

Pradeep Patra said:
I want to write a function for example:

hash_compare(hash1,hash2)
{
if hash2's success counter is increased by 5 for
total,success,percent return success;
if hash2's error counter > 0 return fail;


}

A working example of a possible interpretation of this description:

--------------------
my %h0 = (
total => 15,
success => 15,
error => 0,
percent => 10);

my %h1 = (
total => 20,
success => 20,
error => 0,
percent => 15);

sub verify_changes(\%\%$)
{
my ($h0, $h1, $pred) = @_;

!exists($h1->{$_}) || $pred->($h0->{$_}, $h1->{$_}) || return
for grep { $_ ne 'error'; } keys(%$h0);
return 1;
}

printf("verified %s\n",
!$h1{error} && verify_changes(%h0, %h1, sub { return $_[1] - $_[0] == 5; }) ?
'ok' : 'not ok');
---------------------

NB: The verify_changes subroutine takes three arguments, the 'source
hash', the 'product hash' and a reference to a 'predicate' subroutine
which is supposed to compare two values 'in some way', the
example in the printf statement does your 'larger by 5' check. Testing
$h1{error} is done separately before calling the verification routine.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,736
Latest member
zacharyharris

Latest Threads

Top