Perl で配列とハッシュをネストしたときの書き方

他の言語だと、配列にハッシュを、ハッシュに配列をネストするときに、リファレンスで代入したりするなど、いざ使うときに混乱するので、サンプルコードを残しておく。

配列にハッシュをネストさせたものを、ハッシュに配列をネストさせたものにする場合

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Data::Dumper;

my @countries = (
    # 無名ハッシュを配列内に代入する
    {country => 'Japan',  'city' => 'Tokyo'},
    {country => 'Japan',  'city' => 'Osaka'},
    {country => 'US',     'city' => 'Washington'},
    {country => 'US',     'city' => 'New York'},
    {country => 'UK',     'city' => 'London'},
    {country => 'France', 'city' => 'Paris'},
);

print "配列をダンプする\n";
print Dumper(@countries);

my %city;

foreach my $country (@countries) {
    if ($city{$country->{'country'}}) {
        push(@{$city{$country->{'country'}}}, $country->{'city'});
    } else {
        @{$city{$country->{'country'}}} = ($country->{'city'})
    }
}

print "ハッシュをダンプする\n";
print Dumper(%city);

foreach my $key (keys %city) {
    foreach my $cities (@{$city{$key}}) {
        printf("Key: %s. Value: %s\n", $key, $cities);
    }
}

実行結果は下記のようになる。

配列をダンプする
$VAR1 = {
          'country' => 'Japan',
          'city' => 'Tokyo'
        };
$VAR2 = {
          'country' => 'Japan',
          'city' => 'Osaka'
        };
$VAR3 = {
          'country' => 'US',
          'city' => 'Washington'
        };
$VAR4 = {
          'country' => 'US',
          'city' => 'New York'
        };
$VAR5 = {
          'country' => 'UK',
          'city' => 'London'
        };
$VAR6 = {
          'country' => 'France',
          'city' => 'Paris'
        };
ハッシュをダンプする
$VAR1 = 'France';
$VAR2 = [
          'Paris'
        ];
$VAR3 = 'UK';
$VAR4 = [
          'London'
        ];
$VAR5 = 'US';
$VAR6 = [
          'Washington',
          'New York'
        ];
$VAR7 = 'Japan';
$VAR8 = [
          'Tokyo',
          'Osaka'
        ];
Key: France. Value: Paris
Key: UK. Value: London
Key: US. Value: Washington
Key: US. Value: New York
Key: Japan. Value: Tokyo
Key: Japan. Value: Osaka

ハッシュに配列をネストさせたものを、配列にハッシュをネストさせたものにする場合

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Data::Dumper;

my %city = (
    # 無名配列をハッシュ内に代入する
    Japan => ['Tokyo', 'Yokohama', 'Sendai', 'Osaka'],
    US    => ['Washington', 'New York', 'San Francisco', 'Los Angels'],
    China => ['Beijing', 'Shanghai'],
    UK    => ['London'],
);

print "ハッシュをダンプする\n";
print Dumper(%city);

my @countries;

foreach my $key (keys %city) {
    foreach my $city (@{$city{$key}}) {
        push(@countries, {country => $key, city => $city});
    }
}

print "配列をダンプする\n";
print Dumper(@countries);

foreach my $country (@countries) {
    foreach my $key (keys %{$country}) {
        printf("Key: %s Value: %s\n", $key, $country->{$key});
    }
}

実行結果は下記の通りになる。

ハッシュをダンプする
$VAR1 = 'UK';
$VAR2 = [
          'London'
        ];
$VAR3 = 'China';
$VAR4 = [
          'Beijing',
          'Shanghai'
        ];
$VAR5 = 'US';
$VAR6 = [
          'Washington',
          'New York',
          'San Francisco',
          'Los Angels'
        ];
$VAR7 = 'Japan';
$VAR8 = [
          'Tokyo',
          'Yokohama',
          'Sendai',
          'Osaka'
        ];
配列をダンプする
$VAR1 = {
          'country' => 'UK',
          'city' => 'London'
        };
$VAR2 = {
          'country' => 'China',
          'city' => 'Beijing'
        };
$VAR3 = {
          'country' => 'China',
          'city' => 'Shanghai'
        };
$VAR4 = {
          'country' => 'US',
          'city' => 'Washington'
        };
$VAR5 = {
          'country' => 'US',
          'city' => 'New York'
        };
$VAR6 = {
          'country' => 'US',
          'city' => 'San Francisco'
        };
$VAR7 = {
          'country' => 'US',
          'city' => 'Los Angels'
        };
$VAR8 = {
          'country' => 'Japan',
          'city' => 'Tokyo'
        };
$VAR9 = {
          'country' => 'Japan',
          'city' => 'Yokohama'
        };
$VAR10 = {
           'country' => 'Japan',
           'city' => 'Sendai'
         };
$VAR11 = {
           'country' => 'Japan',
           'city' => 'Osaka'
         };
Key: country Value: UK
Key: city Value: London
Key: country Value: China
Key: city Value: Beijing
Key: country Value: China
Key: city Value: Shanghai
Key: country Value: US
Key: city Value: Washington
Key: country Value: US
Key: city Value: New York
Key: country Value: US
Key: city Value: San Francisco
Key: country Value: US
Key: city Value: Los Angels
Key: country Value: Japan
Key: city Value: Tokyo
Key: country Value: Japan
Key: city Value: Yokohama
Key: country Value: Japan
Key: city Value: Sendai
Key: country Value: Japan
Key: city Value: Osaka