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

Ok, I did find this thread on here already, but situation is a little different and that is the kicker for me. I am making a hash from two columns from a delimited text file. However, I need one of those items to be renamed and then print the renamed item and not the original values that were pasted in from the text file. Code below. Thank you in advance for your amazing help. I'm super new so please be very gentle...and simple.

my @ComplicationsSurgicalProcedMedCare_238 = qw(27661 27783 27788 2853 + 28741); my @SuperficialInjuryContusion_239 = qw(9062 9063 9100 9101); my %diags = ( "Complications of surgical procedures or medical care" =>\@Complicatio +nsSurgicalProcedMedCare_238, "Superficial injury; contusion" =>\@SuperficialInjuryContusion_239, ); my %Diag; my $file = "2009.txt"; open my $fh, "<", $file or die "Can't open $file: $!"; while (<$fh>) { my ($RID, $DiagCode) = split; push @{ $Diag{$RID} }, $DiagCode; } #Print items of array to text file open my $fh1, '>', "Output by RID.txt" or die "Cannot open output.txt: + $!"; foreach (my $RID) { print $fh1 Dumper(\%Diag); } my @Search = <$fh1> ; my %frequency; for my $Search (@Search) { for my $diag ( keys %diags ) { if( my @found = grep { $_ eq $Search } @{$diags{$diag}} ) { my $found = join ",", @found; print "Diagnosis Found: $diag, $found\n"; $frequency{$Search}++; } } } foreach (@Search) { print $fh1 "$_\n"; # Print each entry in our array to the file } close $fh1; #count how many times a variable is repeated my %counts = (); for (@Search) { $counts{$_}++; } print "\n Completed!\n";

So, I feel like I have all the pieces there, they aren't connecting though. I also would love for the output to look like this in one text file:

RID1 {DiagName: DiagCode1, count (for that specific RID)

DiagName: DiagCode2, count (for that specific RID)

}

RID2 {DiagName:DiagCode3, count (for that specific RID)

DiagName:DiagCode4, count (for that specific RID)

}

So, if the DiagCode repeats for different RIDs it will only give you the count for that particular RID. If someone has any ideas, I would be so grateful! Thank you!

Replies are listed 'Best First'.
Re: Putting Hash values into an array
by Athanasius (Archbishop) on Feb 28, 2014 at 02:30 UTC

    Hello Raya4505,

    As you haven’t shown any sample input data, it’s difficult to guess what you are trying to do. However, I do have some observations on the code:

    1. The code as given is incomplete. I presume it begins with:

      use strict; use warnings; use Data::Dumper; # for Dumper()
    2. The line:

      open my $fh1, '>', "Output by RID.txt" or die "Cannot open output.txt: + $!";

      contradicts itself. Is the output file to be named “Output by RID.txt” (with spaces) or “output.txt”?

    3. The body of the loop beginning foreach (my $RID) will never be entered: my declares $RID as a new lexical variable, so its value is undef and the loop immediately terminates.

    4. Having just opened the filehandle $fh1 for writing, you then immediately attempt to read from it: my @Search = <$fh1> ; This guarantees that @Search is empty.

    5. The hashes %frequency and %counts are populated, but never used.

    Hope that helps,

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

      Hello Athanasius,

        The body of the loop beginning foreach (my $RID) will never be entered: my declares $RID as a new lexical variable, so its value is undef and the loop immediately terminates.

      I was going to say the same thing and then I did the 1 liner:
      perl -E 'use strict; foreach (my $RID) { say "okay"; }' --------------------------------- Output: 'okay'

      I changed the 'foreach' to 'while' and it didn't enter the loop. Some monk more familiar with the internals of Perl, will have to clarify. I'm guessing that 'while' tests at the beginning of the loop, and 'foreach' tests at the end of the loop. But that is just a guess.

      I did the test to see if 'use strict;' would pick up the error. But if didn't and the script worked, so I kept my mouth shut and looked for someone to give a better answer, which you did(++).

      Regards...Ed

      "Well done is better than well said." - Benjamin Franklin

        You’re right! But at least warnings raises a red flag:

        18:38 >perl -Mstrict -wE "foreach (my $RID) { say qq[\$RID = >$RID<]; +}" Use of uninitialized value $RID in concatenation (.) or string at -e l +ine 1. $RID = >< 18:43 >

        I wasn’t expecting the loop to be entered at all, and Foreach Loops doesn’t seem to shed much light on the issue. But I’m guessing it’s the difference between a scalar undef and an empty list:

        18:45 >perl -Mstrict -wE "foreach (my @RID) { say 'okay'; }" 18:46 >

        Seems the foreach is treating $RID as a list containing one element (with the value undef), as though it were foreach (my @RID = (undef)):.

        18:46 >perl -Mstrict -wE "foreach (my @RID = (undef)) { say 'okay'; }" okay 18:51 >

        Thanks for pointing this out!

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

      Thank you for your response! Yes, I have all those typical things at the top, so no problem there. The only data that is coming in that isn't listed, is from the 2009.txt file. The information is two columns: Names of people which becomes the key of the %Diag hash called "$RID" and diagnosis codes that are the values labelled "$DiagCode". I fixed the typo with the file name. It should be "Output by RID".

      Now for the technical stuff. So, I understant what you are saying, the $RID should not have a "my" in front of it even though I'm using strict, because that makes it a new variable. Check, removed "my"

      I re-opened the file because I was thinking that the script wrote the hash to "Output by RID" then I closed it, then I would reopen it and essentially rename the $DiagCode that were in that file with their technical name using the @Search %Frequency lines. So, I guess that is the wrong way of doing it. Can you please give me a suggestion on how I can import that 2009.txt file into the hash and then rename just the $DiagCode to their technical names using the @Search %frequency?

      Finally how would I print everything? Do you just keep appending to the file? As noted in my original question, I need the format to look like the above, but I'm not sure how to merge things. I tried printing a block with EOF, but it didn't work. I tried printing them to different files and merging them, I tried appending the file a bunch of times, but surely there is an easier way! Thanks so much for your help.

        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:

        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,