omoonのブログ

旅の思い出を写真とともに書いてみるか。

perlのハッシュの順序をphpの連想配列みたいに保持したい

皆さんご無沙汰しております。「phpのあれ、perlでどうやるの?」のコーナー第2回*1、今日はperlのハッシュの順序についてです。

phpの方が手に馴染んでいる僕にとって、perlのハッシュを扱っていて「うまくいけへんやんけ!うきー!」ってなることナンバーワンは、ハッシュの順序の振る舞いです。

php連想配列では設定時の順序を保持してくれるのに対し、perlのハッシュはでは順序が保持されないのです。

つまり、phpでは、

<?php
$values = array(
    'a' => 1,
    'b' => 2,
    'c' => 3,
);
foreach ( $values as $key => $val ) {
    printf( "%s => %s\n", $key, $val );
}
?>

とすると、

% php sample.php
a => 1
b => 2
c => 3

となるのに対し、perlでは、

#!/usr/bin/perl
my %values = (
    a => 1,
    b => 2,
    c => 3,
);
foreach my $key ( keys %values ) {
    printf "%s => %s\n", $key, $values{$key};
}

が、

% perl sample.pl
c => 3
a => 1
b => 2

となり、順序が全然保持されないのです。保持されることに慣れっこになってしまったこの体には、相当「いやん」なのです。

そこで、Tie::IxHashです。
Tie::IxHash - ordered associative arrays for Perl - metacpan.org

#!/usr/bin/perl
use Tie::IxHash;
my %values = ();
tie %values, 'Tie::IxHash';
%values = (
    a => 1,
    b => 2,
    c => 3,
);
foreach my $key ( keys %values ) {
    printf "%s => %s\n", $key, $values{$key};
}

こんな感じで使ってやると、

% perl sample.pl
a => 1
b => 2
c => 3

めでたく、順番が保持されました。やったー!CPAN万歳!
今回はそんなところです。皆さん、また次回お会いしましょう。

参考)