Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Hash of Hash of Arrays

by voltas (Novice)
on Aug 24, 2016 at 12:04 UTC ( #1170305=perlquestion: print w/replies, xml ) Need Help??

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

I have a working code that reads a log file and produces output like below:
=> [ 'Testing { ', 'JIRA' => 'COM-6789 ', 'Program' => 'Testing ', 'rev' => 'r876391 ', 'Reviewer' => 'Balise Mat ' 'Description' => 'Audited }, { ', 'Program' => 'Testing ', 'rev' => 'r698392 ', 'Reviewer' => 'Chan Joe ', 'JIRA' => 'COM-6789 ' 'Description' => 'SO hwat }, { ', 'JIRA' => 'COM-6789 ', 'Reviewer' => 'Chan Joe ', 'Program' => 'Testing ', 'rev' => 'r327896 ' 'Description' => 'Paid the Due } ], ' => [ 'Development { ', 'JIRA' => 'COM-1234 ', 'Reviewer' => 'John Wick ', 'rev' => 'r345676 ', 'Program' => 'Development ' 'Description' => 'Genral fix }, { ', 'Program' => 'Development ', 'rev' => 'r909276 ', 'Reviewer' => 'None ', 'JIRA' => 'COM-1234 ' 'Description' => 'Updating Received } ],
I want to print my output like Hash of Hash of Arrays, i.e. take Development as my first hash with the JIRA ID as the values and JIRA ID as the 2nd hash and the associated values. Example :
'Development { COM-1234 { ', 'JIRA' => 'COM-1234 ', 'Reviewer' => 'John Wick ', 'rev' => 'r345676 ', 'Program' => 'Development ' 'Description' => 'Genral fix }, { ', 'Program' => 'Development ', 'rev' => 'r909276 ', 'Reviewer' => 'None ', 'JIRA' => 'COM-1234 ' 'Description' => 'Updating Received } }, ],
Code snippet:
#!/usr/bin/perl use strict; use warnings; use 5.010; use Data::Dumper; my @records = do { local $/ = '------------------------------------------'; <>; }; chomp @records; my %jira; foreach (@records) { next unless /\S/; my %rec = /^(\w+):\s*(.+?)$/mg; push @{$jira{$rec{JIRA}}}, \%rec; } say Dumper \%jira; my %prog foreach (@records) { next unless /\S/; my %rec = /^(\w+):\s*(.+?)$/mg; push @{$jira{$rec{Program}}}, \%rec; } say Dumper \%prog;

Replies are listed 'Best First'.
Re: Hash of Hash of Arrays
by duyet (Friar) on Aug 24, 2016 at 16:07 UTC
    Your code is incomplete, as i don't see assignment of Program Reviewer, rev, etc. Also i don't see how you can fill different JIRA and Program with same data (@records).

    There is no example how your input looks like. It's difficult to figure out how it should be done.

    Below is short example of how data can be processed:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; $Data::Dumper::Sortkeys = 1; $Data::Dumper::Terse = 1; my $hash = {}; foreach my $line ( <DATA> ) { chomp $line; my ( $jira, $program, $rev, $reviewer, $desc ) = split /:/, $line; my $data = { JIRA => $jira, Program => $program, rev => $rev, Reviewer => $reviewer, Description => $desc, }; push @{ $hash->{ $program }}, $data; } print 'hash = ' . Dumper( $hash ); __DATA__ COM-6789:Testing:r876391:Balise Mat:Audited COM-6789:Testing:r698392:Chan Joe:SO hwat COM-6789:Testing:r327896:Chan Joe:Paid the Due COM-1234:Development:r345676:John Wick:General fix COM-1234:Development:r909276:None:Updating Received
    which has the following data:
    hash = { 'Development' => [ { 'Description' => 'General fix', 'JIRA' => 'COM-1234', 'Program' => 'Development', 'Reviewer' => 'John Wick', 'rev' => 'r345676' }, { 'Description' => 'Updating Received', 'JIRA' => 'COM-1234', 'Program' => 'Development', 'Reviewer' => 'None', 'rev' => 'r909276' } ], 'Testing' => [ { 'Description' => 'Audited', 'JIRA' => 'COM-6789', 'Program' => 'Testing', 'Reviewer' => 'Balise Mat', 'rev' => 'r876391' }, { 'Description' => 'SO hwat', 'JIRA' => 'COM-6789', 'Program' => 'Testing', 'Reviewer' => 'Chan Joe', 'rev' => 'r698392' }, { 'Description' => 'Paid the Due', 'JIRA' => 'COM-6789', 'Program' => 'Testing', 'Reviewer' => 'Chan Joe', 'rev' => 'r327896' } ] }
      Hi @duyet, Really appreciate your help here. Now shared the entire details. My input log file is below:
      JIRA: COM-1234 Program:Development Reviewer:John Wick Description:Genral fix rev:r345676 ------------------------------------------ JIRA:COM-1234 Program:Development Reviewer:None Description:Updating Received rev:r909276 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Balise Mat Description:Audited rev:r876391 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Chan Joe Description:SO hwat rev:r698392 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Chan Joe Description:Paid the Due rev:r327896 ------------------------------------------
      My incomplete code is below.
      #!/usr/bin/perl use strict; use warnings; use 5.010; use Data::Dumper; my @records = do { local $/ = '------------------------------'; <>; }; chomp @records; my %jira; foreach (@records) { next unless /\S/; my %rec = /^(\w+):\s*(.+?)$/mg; push @{$jira{$rec{Program}}{$rec{JIRA}}}, \%rec; } #say Dumper \%jira; foreach $prg (keys %jira) { print "=========================================================== +=\n"; print " PROGRAM : prg + \n"; print "=========================================================== +=\n"; foreach $jira (keys %{$jira{$prg}}) { print "******************\n"; print "JIRA ID : $jira\n"; print "******************\n"; @myarr = @{$jira{$prg}{$jira}}; foreach $val (@myarr) { for $i ( 0 .. $#myarr ) { print "NO:$i\n"; foreach $key (keys %{$myarr[$i]}) { #print "KEY: $key\n"; print " ======> $val[$i]{revision}\n"; } } } } }
      What I'm trying to accomplish is to read the log file and print the output in the below format.
      ================================== Program: Development =================================== ***************** JIRA ID: COM 1234 ***************** rev => r345676 Reviewer => John Wick Description => Genral fix rev => r909276 Description => Updating Received Reviewer => None ================================== Program: Testing =================================== ***************** JIRA ID: COM 6789 ***************** rev => r876391 Description => Audited Reviewer => Balise Mat rev => r698392 Reviewer => Chan Joe Description => SO hwat rev => r327896 Reviewer' => Chan Joe Description' => Paid the Due
      I'm able to print the unique Program & JIRA ID but the revision, Reviewer and Description values are getting displayed multiple times for every single JIRA ID. Would you really appreciate any inputs. Thanks in advance.
        Below is how i did it. The data is saved in a separate file, and read line by line. There are other ways to read file, eg. File::Slurp or File::Map.

        It could have been done in 1 while loop, but i prefer 2 steps: 1st process the data, 2nd output the data. Then the code can be put in short subroutines, which i can easily create tests for them.

        #!/usr/bin/perl use strict; use warnings; use Data::Dumper; $Data::Dumper::Sortkeys = 1; $Data::Dumper::Terse = 1; my $file = 'perlmonk_1170305_02_data.txt'; open FH, $file or die "Couldn't open file: [$!]\n"; my $data = {}; my $hash = {}; while ( <FH> ) { my $line = $_; chomp $line; if ( $line =~ m/(-){2,}/ ) { # save all stored data if we see dashes line my $program = $hash->{Program} || ''; my $jira = $hash->{JIRA} || ''; if ( $program && $jira ) { push @{ $data->{ $program }{ $jira }}, $hash; $hash = {}; } } else { # store data in a temp hash my ( $key, $value ) = split /:\s*/, $line; $hash->{ $key } = $value; } } #print 'data = ' . Dumper( $data ); foreach my $prg ( sort keys %{ $data } ) { print "=========================================================== +=\n"; print " PROGRAM : $prg + \n"; print "=========================================================== +=\n"; foreach my $jira ( sort keys %{ $data->{ $prg }}) { print "******************\n"; print "JIRA ID : $jira\n"; print "******************\n"; foreach my $hash ( @{ $data->{ $prg }{ $jira }} ) { foreach my $key ( keys %{ $hash }) { # print the data except Program and JIRA next if $key =~ m/(Program|JIRA)/; print " $key => $hash->{ $key }\n"; } print "\n"; } } }
        Output:
        ============================================================ PROGRAM : Development ============================================================ ****************** JIRA ID : COM-1234 ****************** rev => r345676 Reviewer => John Wick Description => Genral fix rev => r909276 Reviewer => None Description => Updating Received ============================================================ PROGRAM : Testing ============================================================ ****************** JIRA ID : COM-6789 ****************** rev => r876391 Reviewer => Balise Mat Description => Audited rev => r698392 Reviewer => Chan Joe Description => SO hwat rev => r327896 Reviewer => Chan Joe Description => Paid the Due
Re: Hash of Hash of Arrays
by GotToBTru (Prior) on Aug 24, 2016 at 12:40 UTC

    Is the example data the output of the code snippet? %prog?

    But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

      No, its the output I'm expecting. the output of my code snippet is in the top portion of the post.Thanks
        Appreciate your response, shared the entire details. My log file is below:
        JIRA: COM-1234 Program:Development Reviewer:John Wick Description:Genral fix rev:r345676 ------------------------------------------ JIRA:COM-1234 Program:Development Reviewer:None Description:Updating Received rev:r909276 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Balise Mat Description:Audited rev:r876391 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Chan Joe Description:SO hwat rev:r698392 ------------------------------------------ JIRA: COM-6789 Program:Testing Reviewer:Chan Joe Description:Paid the Due rev:r327896 ------------------------------------------
        My incomplete code is below.
        #!/usr/bin/perl use strict; use warnings; use 5.010; use Data::Dumper; my @records = do { local $/ = '------------------------------'; <>; }; chomp @records; my %jira; foreach (@records) { next unless /\S/; my %rec = /^(\w+):\s*(.+?)$/mg; push @{$jira{$rec{Program}}{$rec{JIRA}}}, \%rec; } #say Dumper \%jira; foreach $prg (keys %jira) { print "=========================================================== +=\n"; print " PROGRAM : prg + \n"; print "=========================================================== +=\n"; foreach $jira (keys %{$jira{$prg}}) { print "******************\n"; print "JIRA ID : $jira\n"; print "******************\n"; @myarr = @{$jira{$prg}{$jira}}; foreach $val (@myarr) { for $i ( 0 .. $#myarr ) { print "NO:$i\n"; foreach $key (keys %{$myarr[$i]}) { #print "KEY: $key\n"; print " ======> $val[$i]{revision}\n"; } } } } }
        What I'm trying to accomplish is to read the log file and print the output in the below format.
        ================================== Program: Development =================================== ***************** JIRA ID: COM 1234 ***************** rev => r345676 Reviewer => John Wick Description => Genral fix rev => r909276 Description => Updating Received Reviewer => None ================================== Program: Testing =================================== ***************** JIRA ID: COM 6789 ***************** rev => r876391 Description => Audited Reviewer => Balise Mat rev => r698392 Reviewer => Chan Joe Description => SO hwat rev => r327896 Reviewer' => Chan Joe Description' => Paid the Due
        I'm able to print the unique Program & JIRA ID but the revision, Reviewer and Description values are getting displayed multiple times for every single JIRA ID. Looking forward for your suggestions.Thanks much.
Re: Hash of Hash of Arrays
by neilwatson (Priest) on Aug 24, 2016 at 12:58 UTC
      No, the Output is stored in a log file. I'm reading it from there.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1170305]
Approved by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2019-05-21 02:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you enjoy 3D movies?



    Results (129 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!