in reply to Re^2: Putting Hash values into an array
in thread Putting Hash values into an array

My advice is to set up your data structures so as to make data access as simple and straightforward as possible. One of Perl’s greatest strengths is its highly-efficient built-in hashes, so use them to construct lookup tables for the required data. Here is how I would go about this:

#! perl use strict; use warnings; my @ComplicationsSurgicalProcedMedCare_238 = (27661, 27783, 27788, 28 +53, 28741); my @SuperficialInjuryContusion_239 = ( 9062, 9063, 9100, 91 +01); my ($infile, $outfile) = ('2009.txt', 'Output by +RID.txt'); my %DiagNames = ( 238 => 'Complications of surgical procedures or medical care', 239 => 'Superficial injury; contusion', ); my %DiagCodes; $DiagCodes{$_} = 238 for @ComplicationsSurgicalProcedMedCare_238; $DiagCodes{$_} = 239 for @SuperficialInjuryContusion_239; my %Diags; open my $fh, '<', $infile or die "Can't open file '$infile' for reading: $!"; while (<$fh>) { my ($RID, $DiagCode) = split; ++$Diags{$RID}{$DiagCode}; } close $fh or die "Can't close file '$infile': $!"; open my $fh1, '>', $outfile or die "Cannot open file '$outfile' for writing: $!"; for my $key (sort keys %Diags) { print $fh1 "$key\n{\n"; for (sort { $a <=> $b } keys %{ $Diags{$key} } ) { if (exists $DiagCodes{$_}) { printf $fh1 " %s: %d, %d\n", $DiagNames{ $DiagCodes{$_} }, $_, $Diags{$key}->{$_}; } else { printf $fh1 " Unrecognized code: %d\n", $_; } } print $fh1 "}\n\n"; } close $fh1 or die "Can't close file '$outfile': $!";

Input file “2009.txt”:

Tom_Jones 9062 John_Smith 27783 Tom_Jones 9062 Jane_Brown 9100 Tom_Jones 28741 John_Smith 9062 Tom_Jones 9062 Jane_Brown 9062 Tom_Jones 28741 Jane_Brown 2853 Jane_Brown 9062 Tom_Jones 12345

Output file “Output by RID.txt”:

Jane_Brown { Complications of surgical procedures or medical care: 2853, 1 Superficial injury; contusion: 9062, 2 Superficial injury; contusion: 9100, 1 } John_Smith { Superficial injury; contusion: 9062, 1 Complications of surgical procedures or medical care: 27783, 1 } Tom_Jones { Superficial injury; contusion: 9062, 3 Unrecognized code: 12345 Complications of surgical procedures or medical care: 28741, 2 }

P.S. In future, please supply actual sample data (not a description of what the data looks like — an actual sample of the data) together with the actual output which should result from the given input data. This will make it much easier for the Monks to help you. See How do I post a question effectively?

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^4: Putting Hash values into an array
by Raya4505 (Novice) on Mar 04, 2014 at 13:53 UTC
    Yes that helps so much! Thank you. Sorry for the confusion with the data, but due to the sensitivity of my data (HIPPA laws), I can't display any of it so, that why I just have to give examples, but I will try to give better ones in the future. I will try that code out thank you so much again.
Re^4: Putting Hash values into an array
by Raya4505 (Novice) on Mar 05, 2014 at 15:04 UTC

    Thank you so much for your response. I spent all day yesterday reformatting my code to you script. When I ran it thought, it gave me an error. I searched the error and tried some of their fixes, but with no luck. The error is:

    "exists argument is not a HASH or ARRAY element or a subroutine" and it referring to your line "if (exists my $DiagCodes{$_})".

    Do you know how to fix this? Since your script ran so well, I am hoping its something simple, but so far I have had no luck in figuring it out. Thank you so much for your help.

      Hello Raya4505, you wrote:

      your line "if (exists my $DiagCodes{$_})"

      But my line is:

      if (exists $DiagCodes{$_})

      — without the my! When you use my, you declare a new lexical variable. (And if the variable is not explicitly initialised in the declaration, it receives Perl’s default initialisation: undef if it’s a scalar, the empty list if it’s an array or hash.) So, remove the my and it should work correctly.

      Here’s a useful reference: Coping with Scoping by Dominus.

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        First of all, you are amazing. Thank you for your help. One thing I didn't put in my example and should have, is some of the diagnosis codes in my arrays start with a letter (e.g., V21564, c5415). So, I am struggling with your lines that say:

        for (sort { $a <=> $b } keys %{ $Diags{$key} } ) { if (exists $DiagCodes{$_}) { printf $fh1 " %s: %d, %d\n", $DiagNames{ $DiagCodes{$_} }, $_, $Diags{$key}->{$_}; } else { printf $fh1 " Unrecognized code: %d\n", $_; } }

        because they are set up for a numeric value with the <=>, so I changed it to:

        foreach (sort {$a cmp $b} keys %{$Diags}$key}})

        I tried some other things, but that is the one with the least errors, although it is still not running through. I PROMISE this will be the last question I ask for a long time!! Any insight you can give would be amazing!