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

Dear Monks, I think I may need a hash of hashes for my program. Could you confirm it ?

In the input data, I have a list of airports (first column) their departure time (second column) and ID (third column). I would like to reorganize the flights so they depart from each airport with their departure time equally distributed per hour

Here is the code

#! perl -slw use strict; use diagnostics; use Data::Dump qw[ pp ]; my %in; my %former_in; my %airport_hash; # first select and the data whether the airport is AAAA or BBBB while (<DATA>){ $_ =~ s/\s+$//; m[^(\w\w\w\w)] and push @{$airport_hash{$1}}, $_; } foreach my $airport ( keys %airport_hash){ my @lines = @{$airport_hash{$airport}}; foreach my $line(@lines){ # print STDOUT "line is $line"; if ($line =~ /(\w\w\w\w\s)(\d\d):(\d\d) (.+)/){ push @{ $in{ $2 } }, $line and $former_in{$line} = $3; print STDOUT "1 is $1"; # print STDOUT "2 is $2"; # print STDOUT "3 is $3"; # print STDOUT "4 is $4"; } } for my $hr ( sort{ $a <=> $b } keys %in ) { my $n = $#{ $in{ $hr } }; my $step = 60 / $n; my $min = 0; for my $flight ( @{ $in{ $hr } } ) { my $former_time = $former_in{$flight}; # relative difference my $diff = int( $min ) - $former_in{$flight}; printf( "%02d:%02d %s %s\n", $hr, int( $min ), $flight, $d +iff ); $min += $step; $min = 59 if $min > 59; } } } # AAAA and BBBB represent two airports __DATA__ AAAA 11:01 A1 AAAA 11:03 A3 BBBB 11:10 B4 AAAA 11:30 C4 AAAA 11:30 C6 BBBB 11:50 D5 AAAA 12:01 E15 AAAA 12:01 F16 BBBB 12:02 G6 BBBB 12:25 H2 BBBB 12:27 Z6 BBBB 12:27 Y2 AAAA 12:25 I8 BBBB 12:30 J3 AAAA 12:30 K7 BBBB 12:50 L15 AAAA 12:55 M16

The problem is that for the second case of airport (BBBB), the hash %in still takes into account the AAAA lines so the computation is made with the AAAA flights.. That's why I think I may need a hash of hash but I do not know how to build one.

Replies are listed 'Best First'.
Re: hash of hashes maybe needed
by brsaravan (Scribe) on Nov 27, 2008 at 11:08 UTC
    The problem is that for the second case of airport (BBBB), the hash %in still takes into account the AAAA lines so the computation is made with the AAAA flights ....because you declared %in hash at the beginning and you are not reinitializing the same on your code (first foreach loop). You may change your code as
    foreach my $airport ( keys %airport_hash){ my @lines = @{$airport_hash{$airport}}; my %in; ...... .....

      Thanks a lot brsaravan

      It works ! Now I would like to save the values found, that's why I think I need a hash of hash

Re: hash of hashes maybe needed
by BrowserUk (Patriarch) on Nov 27, 2008 at 11:31 UTC

    Try this:

    #! perl -slw use strict; my %in; while( <DATA> ) { if( m[(\S+) (\d\d):\d\d (.+)$] ) { push @{ $in{ $1 }{ $2 } }, $3; } else { die 'Bad data'; } } for my $airport ( sort keys %in ) { for my $hr ( sort{ $a <=> $b } keys %{ $in{ $airport } } ) { my $n = $#{ $in{ $airport }{ $hr } }; my $step = 60 / $n; my $min = 0; for my $flight ( @{ $in{ $airport }{ $hr } } ) { printf( "%s %02d:%02d %s\n", $airport, $hr, int( $min ), $ +flight ); $min += $step; $min = 59 if $min > 59; } } } __DATA__ ...

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.