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

Given the following data structure from the perl debugger:
8 'Mailsrv1_Wed' 9 HASH(0x85da80) 'class' => 'Mailsrv1_Wed' 'classtype' => 0 'client' => 'mailsrv1' 'compression' => 1 'elapsed' => 0000007201 'ended' => 1023811336 'filelistcount' => 1 'files' => '/opt/netscape/mailbox1H' 'fileslastwritten' => 0 'group' => 'other' 'jobid' => 216975 'jobpid' => 20553 'jobtype' => 'immediate' 'kbytes' => 1155537 'kbyteslastwritten' => 0 'masterserver' => 'netbackup1' 'operation' => '' 'owner' => 'root' 'path' => '' 'percent' => '' 'priority' => 0 'retentionperiod' => 1 'retentionunits' => 3 'schedule' => 'Mailsrv_Inc' 'schedule_type' => 1 'server' => 'netbackup1' 'started' => 1023804135 'state' => 'done' 'status' => 0
I need to process each 'jobid' after sorting by several criteria, and I'm not sure how to build a data structure to accomodate this criteria.

Currently, my program makes one, big table of all job id's, sorted by pass, fail, or partial. My goal is to create 1 HTML table for each key ( class name) )in the hash above. What seems important to me is to sort the data as such:

$key = "class_name" $list_1 = "list_of_successful_jobIDs" $val1 = "12345", $val2 = "65432".....(and so on) $list_2 = "list_of_failed_jobIDs" $val = "98765", $val2 = "34567".....{and so on) $list_3 = "list_of_part_success_jobIDs" $val = "121212", $val2 = "393939".....{and so on)
in order to process each jobID.

Here's what I came up with, which obviously doesn't work. I post it here in case it gives any of you some more insight into what I'm trying to do.

use strict; use NBUX; my $newkey; my %jobs = bpdbjobs(); my %jobsClassKey; my %classClient; my %masterClassHash; my (@successfuljobs, @partiallysuccessful,@failedjobs); ## populate 2nd hash with class as key foreach my $key (keys %jobs) { $newkey = $jobs{$key}->{class}; $jobsClassKey{$newkey} = $jobs{$key}; } foreach my $class (sort keys %jobsClassKey) { my $jobid = $jobsClassKey{$class}->{jobid}; my $status = $jobsClassKey{$class}->{status}; push @{$masterClassHash{$class}{$successfuljobs}} , $jobid if ($s +tatus == 0); push @{$masterClassHash{$class}{$partiallysuccessful}} , $jobid if ( +$status == 1); push @{$masterClassHash{$class}{$failedjobs}} , $jobid if +(($status > 1) && \ ($status != 150)); # Termination +requested by admin }
Currently, the way I do it is populate an array of jobID's and process as such:
# Partially successful if ($#partiallysuccessful > 0) { print <<EOC; <tr> <td colspan="13" align="center" valign="middle" bgcolor="#ff +cc00"> <h2 align="center">$#partiallysuccessful partial successfu +ly jobs</h2> </td> </tr> <tr> <th align="center">Class</th> <th align="center">Hostname</th> <th align="center">Job-ID</th> <th align="center">Schedule</th> <th align="center">Status</th> <th align="center">Server</th> <th align="center">Files</th> <th align="center">Tries</th> <th align="center">Start </th> <th align="center">End </th> <th align="center">Duration</th> <th align="center">Mbytes</th> <th align="center">Speed</th> </tr> EOC foreach $jobid ( sort @partiallysuccessful ) { my $thisjob = $alljobs { $jobid }; my $MB = $thisjob->{kbytes} / 1000; &print_report_line($thisjob->{class}, $thisjob->{client}, $thisjob->{jobid}, $thisjob->{schedule}, $thisjob->{status}, $thisjob->{server}, $thisjob->{files}, $thisjob->{trycount}, &format_hhmmss_time($thisjob->{started}), &format_hhmmss_time($thisjob->{ended}), $thisjob->{elapsed}, #&beautify_number($thisjob->{kbytes}), &round($MB), ($thisjob->{elapsed} > 0 ? int(($thisjob->{kbytes}/$thisjob->{elapsed})*1 +00)/100 : "0.00")); }

Replies are listed 'Best First'.
Re: Nested Data Structure Help
by r0b (Pilgrim) on Jun 12, 2002 at 21:43 UTC
    I think the data structure your looking for is:
    %hash = ( 'class_name' => { 'list_of_successful_jobIDs' => [ qw(foo bar) ], 'list_of_failed_jobIDs' => [ qw(val1 val2) ], }, );
    To print out the 2nd element of list_of_successful_jobIDs of class_name you would use the following: print $hash{class_name}{list_of_successful_jobIDs}[1]; Good luck!

    ~~rob
    ____________________________________________________________
    eval pack "h*", "072796e647022245d445f475454494c5e622b3";

      Right. But doing this from within a foreach loop is where things are getting fuzzy. The following doesn't work:
      foreach my $class (sort keys %jobsClassKey) { my $jobid = $jobsClassKey{$class}->{jobid}; my $status = $jobsClassKey{$class}->{status}; $masterClassHash{$class}{'successfuljobs'},$jobid if ($status == 0); $masterClassHash{$class}{'partiallysuccessful'},$jobid if ($status == +1); $masterClassHash{$class}{'failedjobs'}, $jobid if (($status > 1) && ( +$status != 150)); #Termination requested by admin } print $masterClassHash{$class}{successfuljobs}[1]

      What I need to do is:

      for every class, divide jobids by fail, partially fail, and succeed.

        Do you mean something like:
        foreach my $class (sort keys %jobsClassKey) { my ($jobid, $status) = @{$jobsClassKey {$class}} {'jobid', 'st +atus'}; my $key = $status == 0 ? 'successfuljobs' : $status == 1 ? 'partiallysuccessful' : $status == 150 ? next : $status > 1 ? 'failedjobs' : next; push @{$masterClassHash {$class} {$key}} => $jobid; }

        Abigail