Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > having trouble with hash of arrays...

Reply
Thread Tools

having trouble with hash of arrays...

 
 
bjobrien62@gmail.com
Guest
Posts: n/a
 
      07-03-2013
This is confusing me...
I have a patient id and that patient id can have a list of patient names (each with different spelling, but the same person)

my %hash = ();
my $pid = "Patient ID";
my $pname = "Patient Name";

I check to see if there is an entry in the hash for patient ID.
If there is then I want the array of Patient Names for the Patient ID.
Then I want to see if this spelling is found in the Array.
If it is do nothing, if it isn't then I add the new spelling to the array then set that array as the value for the hash pid.


if (exists($hash{$pid})) {

$pnames = $hash{$pid};
@found = grep(/$pname/, @pnames);
$size = @found;

if ($size == 0) {
push(@$names, $pname);
$hash{$pid} = [ @foo ];
}
} else {
$hash{$pid} = [ $pname ];
}

Then I want to print out the list...

my $patid = "";

foreach my $patid (keys %hash) {
print "The spellings for $patid are\n";
foreach (@{$hash{$patid}}) {
print "\t$_\n";
}
}

 
Reply With Quote
 
 
 
 
Ivan Shmakov
Guest
Posts: n/a
 
      07-03-2013
>>>>> bjobrien62 <(E-Mail Removed)> writes:

> This is confusing me...


What specifically?

[...]

> if (exists($hash{$pid})) {
> $pnames = $hash{$pid};
> @found = grep(/$pname/, @pnames);


The problem with grep () is that it will scan through /all/ the
list, instead of stopping on the first match.

> $size = @found;
> if ($size == 0) {
> push(@$names, $pname);
> $hash{$pid} = [ @foo ];
> }
> } else {
> $hash{$pid} = [ $pname ];
> }


... Overall, I'd just use a (second) hash instead, as in:

$hash{$pid}->{$pname} = 1
unless (exists ($hash{$pid})
&& exists ($hash{$pid}->{$pname}));

> Then I want to print out the list...


> my $patid = "";


What is the above statement for?

> foreach my $patid (keys %hash) {
> print "The spellings for $patid are\n";
> foreach (@{$hash{$patid}}) {
> print "\t$_\n";
> }
> }


The inner foreach () loop seems a bit superfluous here.
Consider, e. g.:

foreach my $patid (keys %hash) {
print "The spellings for $patid are\n";
local ($,, $\)
= ("\t", "\n");
print ("", keys (%{$hash{$patid}}));
}

Naturally, join () may be used instead of setting $,, like:

print ("The spellings for ", $patid, " are\n",
"\t", join ("\t", keys (%{$hash{$_}})), "\n");
foreach (keys (%hash));

Consider also applying sort () to the keys () of the hashes.

--
FSF associate member #7257
 
Reply With Quote
 
 
 
 
Charles DeRykus
Guest
Posts: n/a
 
      07-03-2013
On 7/2/2013 5:11 PM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> This is confusing me...
> I have a patient id and that patient id can have a list of patient names (each with different spelling, but the same person)
>
> my %hash = ();
> my $pid = "Patient ID";
> my $pname = "Patient Name";
>
> I check to see if there is an entry in the hash for patient ID.
> If there is then I want the array of Patient Names for the Patient ID.
> Then I want to see if this spelling is found in the Array.
> If it is do nothing, if it isn't then I add the new spelling to the array then set that array as the value for the hash pid.
>
>
> if (exists($hash{$pid})) {
>
> $pnames = $hash{$pid};
> @found = grep(/$pname/, @pnames);

^^^^^^^
@{$pnames}
> $size = @found;
>
> if ($size == 0) {
> push(@$names, $pname);
> $hash{$pid} = [ @foo ];
> }
> } else {
> $hash{$pid} = [ $pname ];
> }


@$names and @foo look wrong... old code fragments perhaps?


Since you only want to add new spellings, you could shorten it all down
to a line or two, eg,

unless ( grep( /^$pname$/, @$pnames ) {
push( @{ $hash{$pid} }, $pname );
}



>
> Then I want to print out the list...
>
> my $patid = "";

^^^^^^^^^^^^^^^
unneeded

>
> foreach my $patid (keys %hash) {
> print "The spellings for $patid are\n";
> foreach (@{$hash{$patid}}) {
> print "\t$_\n";
> }
> }
>


Other than the unneeded line, this looks ok though.

--
Charles DeRykus


 
Reply With Quote
 
Dr.Ruud
Guest
Posts: n/a
 
      07-03-2013
On 03/07/2013 08:44, Charles DeRykus wrote:

> unless ( grep( /^$pname$/, @$pnames ) {
> push( @{ $hash{$pid} }, $pname );
> }


Names can contain regexp-metacharacters.

grep { $_ eq $pname } @$pnames

--
Ruud

 
Reply With Quote
 
Rainer Weikusat
Guest
Posts: n/a
 
      07-03-2013
(E-Mail Removed) writes:
> if (exists($hash{$pid})) {
>
> $pnames = $hash{$pid};
> @found = grep(/$pname/, @pnames);


@pnames is not the same as the anonymous array $pnames refers to. That
would be @$pnames.

/$pname/ is a regex match which will return true if one of the input
elements matches the regex $pname somewhere. Eg, if $pname was 'Henry
I.', that would match 'John Henry Ibsen'. This should be something
like

/^\Q$pname\E$/

This anchors the match at the beginning and end of the string, eg,
'Henry' will match 'Henry' and not 'John Henry' and quotes any
regex-metacharacters in $pname.

> $size = @found;


You can as well use $size = grep(...) as grep returns the number of
elements it found in scalar context.


> if ($size == 0) {
> push(@$names, $pname);


@$names is not the same as @$pnames. The strict module/ pragma is very
helpful for catching these kind of mistakes.
 
Reply With Quote
 
George Mpouras
Guest
Posts: n/a
 
      07-04-2013
# this is what you want


use strict;
use warnings;
my %hash;

while (<DATA>)
{
my ($pid, $pname) = $_ =~/^(.*?),(.*?)\s*$/;

if (exists $hash{$pid})
{
unless ( $pname ~~ @{$hash{$pid}->{'names'}} )
{
push @{$hash{$pid}->{'names'}} , $pname
}
}
else
{
$hash{$pid}->{'value'} = $pname;
$hash{$pid}->{'names'} = [ $pname ]
}
}


use Data:umper; print Dumper \%hash;

__DATA__
foo,foo name
foo,fooname
foo,fo oname
foo,fooname
goo,gooname
goo,goo name
goo,gooname
 
Reply With Quote
 
Dr.Ruud
Guest
Posts: n/a
 
      07-05-2013
On 04/07/2013 20:45, George Mpouras wrote:

> while (<DATA>) {
> my ($pid, $pname) = /^(.*?),(.*?)\s*$/;


Be aware that the '(.*?)\s*$' at the end just means '(.*)'.




What meaning where you looking for?

Maybe this: '(.*\S)\s*$'.
(but then the last field can't be empty).

--
Ruud

 
Reply With Quote
 
Dr.Ruud
Guest
Posts: n/a
 
      07-05-2013

Ignore this, I sent it by accident.

On 05/07/2013 10:03, Dr.Ruud wrote:
> On 04/07/2013 20:45, George Mpouras wrote:
>
>> while (<DATA>) {
>> my ($pid, $pname) = /^(.*?),(.*?)\s*$/;

>
> Be aware that the '(.*?)\s*$' at the end just means '(.*)'.
>
>
>
>
> What meaning where you looking for?
>
> Maybe this: '(.*\S)\s*$'.
> (but then the last field can't be empty).
>


I was testing and found out I was wrong, and need more coffee:

perl -wle '
$_ = "x,y \n";
my ($pid, $pname) = /^(.*?),(.*?)\s*$/;
print "<$pid>,<$pname>";
'
<x>,<y>

--
Ruud

 
Reply With Quote
 
gravitalsun@gmail.com
Guest
Posts: n/a
 
      07-05-2013
On Friday, July 5, 2013 11:03:30 AM UTC+3, Dr.Ruud wrote:
> On 04/07/2013 20:45, George Mpouras wrote:
>
>
>
> > while (<DATA>) {

>
> > my ($pid, $pname) = /^(.*?),(.*?)\s*$/;

>
>
>
> Be aware that the '(.*?)\s*$' at the end just means '(.*)'.
>
>
>
>
>
>
>
>
>
> What meaning where you looking for?
>
>
>
> Maybe this: '(.*\S)\s*$'.
>
> (but then the last field can't be empty).
>
>
>
> --
>
> Ruud




you are not correct, the (.*?)\s*$/ is not equal to '(.*)'.
It is not greedy and you do not catch any \n \r \v at $2
So this way you can avoid the function
chomp $_;
The .* you mention is catching also the new lines.
 
Reply With Quote
 
gravitalsun@gmail.com
Guest
Posts: n/a
 
      07-05-2013
hey , sorry , I did not see your previous message.
 
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
Help with printing a bit pattern with printf and %x matt.jaffe@gmail.com C Programming 9 04-19-2013 12:14 PM
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
Multidimensional arrays and arrays of arrays Philipp Java 21 01-20-2009 08:33 AM
hash of arrays - appending to one of the arrays Adam Akhtar Ruby 5 03-25-2008 11:53 PM
Having Trouble Accessing Hash with Two "keys" R^3 Perl Misc 5 11-23-2005 03:22 AM



Advertisments