Perl: Generating Arrays inside a Complex Hash

后端 未结 3 1661
臣服心动
臣服心动 2021-01-16 09:54

In the quest to make my data more accessible, I want to store my tabulated data in a complex hash. I am trying to grow a \'HoHoHoA\' as the script loops over my data. As per

3条回答
  •  感动是毒
    2021-01-16 10:16

    This should do it for you.

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use List::Util qw/sum/;
    sub avg { sum(@_) / @_ }
    
    my $fileName = shift;
    
    open my $fh, "<", $fileName
        or die "Unable to open $fileName: $!\n";
    
    my %monthData;
    
    chomp(my @headers = split /\t+/, <$fh>);
    
    while (<$fh>) {
        chomp;
        my %rec;
        @rec{@headers} = split /\t+/;
        my ($hour) = split /:/, $rec{TIME}, 2;
    
        for my $key (grep { not /^(DATE|TIME)$/ } keys %rec) {
            push @{ $monthData{$key}{$rec{DATE}}{$hour} }, $rec{$key};
        }
    }
    
    for my $column (keys %monthData) {
        for my $date (keys %{ $monthData{$column} }) {
            for my $hour (keys %{ $monthData{$column}{$date} }) {
                my $avg = avg @{ $monthData{$column}{$date}{$hour} };
                print "average of $column for $date $hour is $avg\n";
            }
        }
    }
    

    Things to pay attention to:

    • strict and warnings pragmas
    • List::Util module to get the sum function
    • putting an array in scalar context to get the number of items in the array (in the avg function)
    • the safer three argument version of open
    • the lexical filehandle (rather than the old bareword style filehandle)
    • reading the headers first outside the loop to avoid having to have special logic inside it
    • using a hash slice to get the file data into a structured record
    • avoiding splitting the time more than necessary with the third argument to split
    • avoiding useless variables by only specifying the variable we want to catch in the list assignment
    • using grep to prevent the DATE and TIME keys from being put in %monthData
    • the nested for loops each dealing with a level in the hash

提交回复
热议问题