Perlのハッシュを理解しよう



  1. Perl



  2. ハッシュ

Perlの「ハッシュ」についての解説です。Perlのハッシュは、他の言語でいうところの「連想配列」のことです。

配列では、番号を指定して要素を取り出すことができましたが、「連想配列」では、文字列をキーとして指定して、要素を取り出すことができます。

ハッシュの基礎

ハッシュの基礎。ハッシュの宣言と初期化。ハッシュの出力と代入。ハッシュは、文字列を、添え字として、値を取得できる配列だと考えればよい。文字列をキーとして、値を取り出すことができる。

ハッシュの宣言と初期化

ハッシュの宣言と初期化は次のようにして行います。

my %fathers = ('Taro' => 'Kenji', 'Naoko' => 'Yoshio');
#あるいは
my %fathers = (Taro => 'Kenji', Naoko => 'Yoshio');

 変数の接頭辞はパーセント記号です「%」。(キー1 => 値1, キー2 => 値2, ...)。Taroの父親はKenji, Naokoの父親はYoshioと読むことができる

ハッシュの要素の出力
print $mothers{'Taro'};

 出力する場合は、%ではなくて$ 。単一の要素を扱う場合は$ 。{ }を使ってキーを指定する。( 配列の場合は[ ]でした )。{} はブラケットと読みます。( [] はブレース。 () はかっこ )

ハッシュの要素の代入

$mothers{'Naoko'} = 'Haruna';

ハッシュのリファレンス

ハッシュのリファレンスは以下のように作ることができます。

my $math_scores_ref = \%math_scores;

%の前に \ をつけ、ハッシュへのリファレンスを生成。生成したリファレンスを、スカラー変数 $math_score_href に代入

無名ハッシュを使って、直接ハッシュへのリファレンスを作る。
my $math_scores_ref2 = { 
  Aiko => 89,
  Kenta => 100,
  Taro => 34,
};

 ( ) の代わりに { } を使って、直接ハッシュへのリファレンスを作成できる

ハッシュの要素にアクセスする
$math_scores_ref->{Aiko}
ハッシュのリファレンスからハッシュを取り出す

 ハッシュのリファレンスからハッシュを取り出すにはデリファレンスを行います。

my %hash = %$hash_ref;
my %hash = %{$hash_ref};

ハッシュへのリファレンスをデリファレンスしてハッシュを取り出すこともできます。

my %math_scores = %$math_scores;

 %$math_scoresでデリファレンスしてハッシュを取り出すことができる。

ひとつの要素しか必要としないときは「->{key}」を使うことができます。

$math_scores->{Taro};

ハッシュのリファレンスについてはこちらで詳しく解説しています。

ハッシュを使った多次元データ構造

ハッシュを使った多次元データ構造については、以下の記事で詳しく解説しています。「配列のハッシュ」「ハッシュの配列」「ハッシュのハッシュ」について学ぶことができます。

コラム「連想配列をハッシュと呼ぶようになったのはPerlのせい」

Perlは、連想配列を言語の機能として取り入れるという素晴らしい決定をした。とてつもなく便利だ。これは、大成功で、他のほぼすべてのスクリプト言語は、影響を受けて、言語自体に連想配列を取り入れている。

連想配列という名前は長かったのか、Perlはそれをハッシュと呼ぶことにした。これは、ハッシュ関数からの連想だね。

でも、意外とぴったりと、データ構造を表現しているようにも思えるね。

サンプルコード

ハッシュの基礎

 ハッシュの基礎。ハッシュの宣言と初期化。ハッシュの出力と代入のサンプルです。

use strict;
use warnings;

# ハッシュとは
# 文字列を、添え字として、値を取得できる配列だと考えればよい。
# 文字列をキーとして、値を取り出すことができる。

# ハッシュの宣言と初期化( 変数の接頭辞は、% )
# ( キー1 => 値1, キー2 => 値2, ... )
# Taroの父親はKenji, Naokoの父親はYoshioと読む
my %fathers = ('Taro' => 'Kenji', 'Naoko' => 'Yoshio');

# よりPerl的な書き方
# => の左側の''は省略できる
my %mathers = (Taro => 'Tomoko', Naoko => 'Shizuka');

# 1: ハッシュの要素出力
print "1:ハッシュの要素の出力\n";  
# 出力する場合は、%ではなくて$
# {} ブラケットを使う 
print "\$mathers{'Taro'} = ", $mathers{'Taro'}, "\n"; 
print "\n";

# 2: ハッシュの要素の代入
print "2:ハッシュの要素の代入\n";
$mathers{'Naoko'} = 'Haruna';
print "\$mathers{'Naoko'} = ", $mathers{'Naoko'} . "\n";

 実行結果

1:ハッシュの要素の出力
$mothers{'Taro'} = Tomoko

2:ハッシュの要素の代入
$mothers{'Naoko'} = Haruna
ハッシュのリファレンス

ハッシュのリファレンスを使ったのサンプルです。

use strict;
use warnings;
use Data::Dumper;

# 生徒の数学の点数
my %math_scores = ( 
  Aiko => 89,
  Kenta => 100,
  Taro => 34,
);

# 1:ハッシュのリファレンス %の前に \ をつけ、ハッシュへのリファレンスを生成。
# 生成したリファレンスを、スカラー変数 $math_scores_ref に代入
my $math_scores_ref = \%math_scores;
print "1:  ハッシュのリファレンス\n";
print Data::Dumper->Dump([$math_scores_ref], ['$math_scores_ref']);
print "\n\n";

# 2:無名ハッシュ( { } )を使って、直接ハッシュへのリファレンスを作る。
my $math_scores_ref2 = { 
  Aiko => 89,
  Kenta => 100,
  Taro => 34,
};

print "2: 無名ハッシュ\n";
print Data::Dumper->Dump([$math_scores_ref2], ['$math_scores_ref2']);
print "\n\n";

# 3:ハッシュの要素にアクセスする。($hash_ref->{key})
print "3: ハッシュの要素にアクセスする。\n";
print "\$math_scores_ref->{Aiko} = $math_scores_ref->{Aiko}\n";
print "\$math_scores_ref->{Kenta} = $math_scores_ref->{Kenta}\n";

 実行結果

1:  ハッシュのリファレンス
$math_scores_ref = {
                     'Aiko' => 89,
                     'Kenta' => 100,
                     'Taro' => 34
                   };


2: 無名ハッシュ
$math_scores_ref2 = {
                      'Aiko' => 89,
                      'Kenta' => 100,
                      'Taro' => 34
                    };


3: ハッシュの要素にアクセスする。
$math_scores_ref->{Aiko} = 89
$math_scores_ref->{Kenta} = 100
ハッシュのリファレンスのデリファレンス

ハッシュのリファレンスをデリファレンスするサンプルです。

use strict;
use warnings;
use Data::Dumper;

# 生徒の数学の点数
my $math_scores = {
  Taro => 89,
  Naoko => 54,
  Kenji => 54
};

# 1:デリファレンスしてハッシュのすべての要素を出力する
print "1: デリファレンスしてハッシュのすべての要素を出力する\n";
for my $key (keys %$math_scores){
  print "\$math_scores->{$key} = " . $math_scores->{$key} . "\n";
}
print "\n";

# 2:ひとつの要素を参照するときは、-> 演算子を使う。
print "2: ひとつのキーを削除\n";
delete $math_scores->{Taro};

print Data::Dumper->Dump([$math_scores], ['$math_scores']);

 実行結果

1: デリファレンスしてハッシュのすべての要素を出力する
$math_scores->{Kenji} = 54
$math_scores->{Taro} = 89
$math_scores->{Naoko} = 54

2: ひとつのキーを削除
$math_scores = {
                 'Kenji' => 54,
                 'Naoko' => 54
               };