in reply to Re: Manipulating data structure
in thread Manipulating data structure

Hej Sundialsvc4 and thanks for your reply,

I'm not really sure if I understood everything you wrote, but I think I might understood your idea.

But how to assign for example key CMG12 to 12th UID in the file ?

Replies are listed 'Best First'.
Re^3: Manipulating data structure
by locked_user sundialsvc4 (Abbot) on Aug 17, 2012 at 10:05 UTC

    As you parse the file one line at a time and come to CMG1=Ja, the string CMG1 is your keyword and Ja is the associated value.   If you needed to know that it was in the twelfth position, then you could for example set up a hash-of-hashes data structure such that $hoh->{'CMG1'}{'Ja'} = 12.   Or whatever else suits your fancy.   My key point was that, with auto-vivification, you can establish such data structures very easily. You refer to an unassigned variable as a hash ... and it is a hash.   You execute as an assignment-statement what I wrote just above, and the desired hash-of-hash element simply appears.   $hoh->{'CMG1'} exists, and it has a key {'Ja'}, and that key has the value 12.   Presto.   Arrays work the same way.   It’s entirely up to you to determine what structure you want, but very easy to get it.

      Hej Sundialsvc4 and thanks for your post,

      I've done some changes in this subroutine so it looks like this now:

      my @entries; my $previouskey = ""; open (KOF, "<$konfil") or die "Kan inte \xF6ppna filen $konfil"; open (NYF, ">$nyfil") or die "Kan inte \xF6ppna filen $nyfil"; flock (NYF,2) or die $!; my $offset = 0; while(<KOF>) { chomp; $value =~ s/^\s*(\S*)\s+$/$1/; if ($key =~ /^(.*)(\d+)$/) { ##### #### #### $key = $1; # # # # # # $entries[$2]{$key} = $value; ##### # # # # next; # # # # # # } # # #### #### unless ($key eq $previouskey || $previouskey eq "") { $offset = 0; } $previouskey = $key; $entries[$offset]{$key} = $value; $offset++; } my @sorted = sort { $a->{'NYTT'} <=> $b->{'NYTT'} } @entries; my $pers =0; foreach my $e (@sorted) { print NYF ($e->{'UID'}, "|", $e->{'FNA'}, "|", $e->{'ENA'}, "|", $ +e->{'PRE'}, "|", $e->{'NYTT'}, "|", $e->{"PRI"}, "|", $e->{"FOR"}, "| +", $e->{"CMG"}, "|", $e->{"MEX"}, "\n") if( $e->{"UID"} ne "" || $e-> +{"FNA"} ne "" || $e->{"ENA"} ne ""); $pers++ if ($e->{"UID"} ne ""); } close KOF; close NYF;
      and it seems to work !

      Thanks for pointing me to the right direction
        Hi SerZKO

        this line: if ($key =~ /^(.*)(\d+)$/) should be if ($key =~ /^(.*?)(\d+)$/)

        The reason you need the '?' there is that perl regexes are greedy. In your code (.*) consumes every character in $key and then fails to match any digits for the second group, (\d+). Then the regular expression engine will back up 1 character to try to make the match succeed. And it will, capturing the last char which is a digit. But what if your digits are more than 1 char? Your code would fail to capture all the digits since the regex was satisfied with only one of them.

        The question mark makes the regex look to see if the next char is a digit, and if so, start capturing in the second group.

        Chris