perlperl-hash

Inserting and iterating over hash of arrays


I have following input data

Country1:operator1
Country1:operator2
Country1:operator3

Country2:operator1
Country2:operator2
Country2:operator3

I would like to insert this data into hash %INFO such that every key corresponds to an array of "operators", so I could iterate in following way

foreach $i ( keys %INFO ) {

    foreach $operator ( $INFO{$i} ) {
        print " $i ---> $operator \n";  
    }
}

Here is my own solution that doesn't work properly

open($fh, "$info_file");

while (my $row = <$fh>) {
    chomp $row;
    @tokens = split(":",$row);

    $name     = $tokens[0];
    $operator = $tokens[2];

    if ($name =~ /^[A-Z]/) {

        if ( exists $INFO{$name} ) {
            $ptr = \$INFO{$name};
            push(@ptr, $operator);
        }
        else {
            @array = ( "$operator" );
            $INFO{$name} = [ @array ];
        }
    }
}

close($f);

Solution

  • You're over-complicating massively, I'm afraid.

    open my $fh, '<', $info_file or die "Can't open '$info_file': $!";
    
    my %info;
    
    while (<$fh>) {
      next unless /^[A-Z]/;
      chomp;
      my ($name, $operator) = split /:/;
      push @{ $info{$name} }, $operator;
    }
    

    And to access it:

    foreach my $i (keys %info) {
      foreach my $op (@{ $info{$i} }) {
        say "$i ----> $op";
      }
    }
    

    If you treat a hash value as though it's an array reference, then Perl will make it an array reference.

    See the Perl Data Structures Cookbook for more details.