第4章 ハッシュ変数
4-1. ハッシュ変数とは
ハッシュとは、連想配列とも呼ばれ、「キー」と「値」を1組のペアとして関連付けされた配列です。
ただし、配列自体は順序付けされていないところに特徴があります。
ハッシュの変数のことを、ハッシュ変数といい、% (パーセント) + 英字1文字から始まり、それ以降は数字、英字およびアンダースコア ( _ ) を用いることができます。また大文字と小文字が区別されますので、たとえば %a と %A は別物として扱われます。
4-2. ハッシュ変数の操作
ハッシュ変数は、キーと値をペアにして、数値や文字列を代入します。
%fruit = ("red" => "apple", "yellow" => "banana");上記の場合、red(キー)とapple(値)というペアと、yellow(キー)とbanana(値)というペアを、それぞれ%fruitに代入します。
ハッシュ変数の中の各要素(各ペア)は、$ハッシュ変数名 { キー } という形式で、それに対応する「値」を参照することができます。
したがって、前述の%fruitは、以下のように記述することもできます。
したがって、前述の%fruitは、以下のように記述することもできます。
$fruit{"red"} = "apple"; $fruit{"yellow"} = "banana";
ハッシュ変数の各要素には、「キー」を指定することで「値」にアクセスすることができます。
%fruit = ("red" => "apple", "yellow" => "banana", "purple" => "grape"); print "$fruit{'red'}\n";
> apple
ちなみに、「キー」の文字列が全て「英数字・アンダースコア」の場合には、クォーテーションによる括りを省略しても構いません。
ちょっとしたことですが、結構便利です。
# キーのクォーテーションを省略した例-1 %fruit = (red => "apple", yellow => "banana", purple => "grape"); # キーのクォーテーションを省略した例-2 print "$fruit{red}\n";
4-3. ハッシュ関数
ハッシュを操作するための関数として、次のような関数が用意されています。
関数 | 内容 |
---|---|
keys | すべてのキーを取り出す |
values | すべての値を取り出す |
each | 1組のキーと値を取り出す |
delete | 特定の要素を取り除く |
1. keys
すべての「キー」を取り出します。
ただし、取り出された配列の順序は一定でないことに注意します。 これはハッシュが順序付けられた配列ではないためです。
ただし、取り出された配列の順序は一定でないことに注意します。 これはハッシュが順序付けられた配列ではないためです。
%fruit = (red => "apple", yellow => "banana", purple => "grape"); @file = keys %fruit; print "@file\n";
> purple yellow red
2. values
すべての「値」を取り出します。
keys関数同様、取り出された配列の順序は一定ではありません。
keys関数同様、取り出された配列の順序は一定ではありません。
%fruit = (red => "apple", yellow => "banana", purple => "grape"); @file = values %fruit; print "@file\n";
> grape banana apple
3. each
1組の「キー」と「値」を取り出します。
%fruit = (red => "apple", yellow => "banana", purple => "grape"); ($key, $val) = each %fruit; print "$key : $val\n";
> purple : grape
しかしながら、上記の場合、どのペアが取り出されるかが不定であり、しかも1組だけが抽出されるので、通常each関数の場合は次のようにwhile構文と併用した形で使用されます。
%fruit = (red => "apple", yellow => "banana", purple => "grape"); # ハッシュの全要素を展開 while ( my ($key, $val) = each %fruit ) { print "$key : $val\n"; }
> purple : grape > yellow : banana > red : apple
4. delete
特定の要素を取り除きます。
変数によるキーを指定することで、そのキーと値のペアをハッシュから削除します。
変数によるキーを指定することで、そのキーと値のペアをハッシュから削除します。
%fruit = (red => "apple", yellow => "banana", purple => "grape"); # 要素を削除(yellow - banana の要素) delete $fruit{yellow}; # 残りの要素を全て展開 while ( my ($key, $val) = each %fruit ) { print "$key : $val\n"; }
> purple : grape > red : appleちなみに、上記のdelete関数は特定の要素を削除する場合ですが、全要素を削除する場合には、空リストを代入すると、全要素が削除されます。
%fruit = ();ただし、上記の場合中身が空ですが、定義値のままです。 もし、未定義値にしたい場合には、undef関数を使用します。
undef %fruit;
4-4. ハッシュスライス
配列変数に対する場合と同様に、ハッシュのスライスを使用すれば、各要素の集合にアクセスすることができます。
たとえば、次のようなメンバーの年齢データがあったとします。
tomとmikeが今月誕生日を迎えました。年齢を更新してみましょう。
%age = (tom => 21, mike => 19, kent => 25, nancy => 17);これをスライスを使うと、次のように記述できます。先頭が、%ではなく@であることに注意してください。
@age{ qw(tom mike kent nancy) } = (21,19,25,17);以下に、コード例で見てみましょう。
tomとmikeが今月誕生日を迎えました。年齢を更新してみましょう。
use strict; # 年齢データ my %age = (tom => 21, mike => 19, kent => 25, nancy => 17); # tomとmikeを更新 @age{ qw(tom mike) } = (22,20); # データの中身を見る while ( my ($key, $val) = each %age ) { print "$key : $val\n"; }
> nancy : 17 > kent : 25 > tom : 22 > mike : 20また、スライスを使うことで、任意の要素の値をリストとして取り出すこともできます。
use strict; # 年齢データ my %age = (tom => 21, mike => 19, kent => 25, nancy => 17); # kentとnancyの年齢を取り出す my @data = @age{ qw(kent nancy) }; # リストの中身を見る print "@data\n";
> 25 17
4-5. ハッシュを代入順に並べる
ハッシュの配列は、順番どおりには並ばないことは前に述べました。
しかしながら、どうしてもキーや値を順番通りに取り出したい場合には、実はTie::IxHashモジュールを利用することで実現できます。
使い方によっては、大変便利なモジュールですので、ご紹介しておきます。
しかしながら、どうしてもキーや値を順番通りに取り出したい場合には、実はTie::IxHashモジュールを利用することで実現できます。
使い方によっては、大変便利なモジュールですので、ご紹介しておきます。
Tie::IxHashの使い方のポイントは、必ず対象のハッシュを呼び出す前に、tie関数で関連付けしておきます。
use strict; use Tie::IxHash; # %hashを関連付け tie ( my %hash, 'Tie::IxHash' ); # ハッシュに代入 %hash = ( Sun => 0, Mon => 1, Tue => 2, Wed => 3, ); # 全要素を展開 while( my ($key, $val) = each %hash ) { print "$key : $val\n"; }
> Sun : 0 > Mon : 1 > Tue : 2 > Wed : 3上記のように、全てのキーと値を代入順に取り出すことができます。
ちなみに、Tie::IxHashモジュールは標準モジュールではありませんので、各自でインストールする必要があります。
ただし、PurePerl(すべてPerl言語で書かれたもの)のため、Perlライブラリ(jcode.pl, cgi-lib.pl等)のように、ホームディレクトリの中に置いて使用することが可能です。
ただし、PurePerl(すべてPerl言語で書かれたもの)のため、Perlライブラリ(jcode.pl, cgi-lib.pl等)のように、ホームディレクトリの中に置いて使用することが可能です。
参考 : 【コラム】Perlモジュールの組み込み
4-6. 多次元ハッシュ
ハッシュは、配列と同様に多次元に展開させることができます。ハッシュの中にハッシュを作ることができます。
以下のハッシュは、いわゆる二次元ハッシュになります。
%hash = ( A => { a => 1, b => 2, c => 3 }, B => { d => 4, e => 5, f => 6 }, );波括弧(ブレース)の部分を、1つのスカラーと読み替えると、分かりやすいかもしれません。
%hashにおいて、キー「A」に対する値の中の最初のキー「a」の値「1」にアクセスするには、添字を使用して次のように記述することができます。
%hash = ( A => { a => 1, b => 2, c => 3 }, B => { d => 4, e => 5, f => 6 }, ); print "$hash{A}{a}\n";
> 1リファレンスを使って、キー「A」に対する値(配列)を展開するには、次のように記述します。
%hash = ( A => { a => 1, b => 2, c => 3 }, B => { d => 4, e => 5, f => 6 }, ); while ( my ($key, $val) = each %{$hash{A}} ) { print "$key : $val\n"; }
> c : 3 > a : 1 > b : 2%hashの中の全てのキーと値を展開するには、次のように記述します。
%hash = ( A => { a => 1, b => 2, c => 3 }, B => { d => 4, e => 5, f => 6 }, ); foreach my $tmp ( keys %hash ) { while ( my ($key, $val) = each %{$hash{$tmp}} ) { print "$key : $val\n"; } }
> c : 3 > a : 1 > b : 2 > e : 5 > d : 4 > f : 6%hashに対して、二次元のキーと値をさらに追加してみましょう。
%hash = ( A => { a => 1, b => 2, c => 3 }, B => { d => 4, e => 5, f => 6 }, ); # キー「C」に対する二次元の値を追加 $hash{C} = { g => 7, h => 8, i => 9 }; while ( my ($key, $val) = each %{$hash{C}} ) { print "$key : $val\n"; }
> h : 8 > g : 7 > i : 9特定のキーに対する値に、要素を追加してみましょう。
%hash = ( A => { a => 1, b => 2, c => 3 }, B => { d => 4, e => 5, f => 6 }, ); # キー「A」に対する値に要素追加 $hash{A}{x} = 7; while ( my ($key, $val) = each %{$hash{A}} ) { print "$key : $val\n"; }
> c : 3 > a : 1 > b : 2 > x : 7