ハッシュの値に配列を格納する
Perlでも多次元配列が使いたい場合などは、多々あります。
できれば連想配列(ハッシュ)の値に配列を格納できると、
更に便利に使えると思います。
できれば連想配列(ハッシュ)の値に配列を格納できると、
更に便利に使えると思います。
CSVファイルのデータを、特定のキーごとにまとめる際などには
役に立つのではないでしょうか。
役に立つのではないでしょうか。
#
# 配列chiba, saitamaの初期化
#
@chiba = (# 配列chiba, saitamaの初期化
#
'千葉市',
'市川市',
'佐倉市',
'長生郡');
@saitama = (
'草加市',
'川口市',
'北本市');
#
# ハッシュの値として配列を代入
#
@{$hash{'千葉県'}} = @chiba;# ハッシュの値として配列を代入
#
@{$hash{'埼玉県'}} = @saitama;
#
# キーが千葉県のハッシュの値(配列)の要素として、
# 茂原市を追加
#
push(@{$hash{'千葉県'}}, '茂原市');# キーが千葉県のハッシュの値(配列)の要素として、
# 茂原市を追加
#
#
# ハッシュ内のデータを全出力
#
#
# ハッシュをキーと値に分ける
while (($pref, $city) = each(%hash)) {# ハッシュ内のデータを全出力
#
#
# ハッシュをキーと値に分ける
#
# ハッシュの値(配列)を全て巡回する
foreach (@{$city}) {# ハッシュの値(配列)を全て巡回する
print "$pref$_\n"; # 出力
}
print "\n"; # ハッシュ毎に空行を入れる
}
ハッシュの値に配列を
ごっそり代入する場合に、
一般的には配列のリファレンスを利用します。
$hash{'千葉県'} = \@chiba;
のようにしますが、ここではリファレンスを代入するよりも、
デリファレンスした配列に配列をコピーする方が分かりやすい気がしたので、
@{$hash{'千葉県'}} = @chiba;
のように、ハッシュの値を配列型にしてから、
代入しました。
こういう場合、一般的には配列の無名リファレンスを使って、
以下のようにするんじゃないかと思います。
%hash = ('千葉県' => ['千葉市', '市川市', '佐倉市', '長生郡'], '埼玉県' => ['草加市', '川口市', '北本市']);
この書き方だと、何をどうしているのか理解しづらいと思います。
簡単に配列を代入できていて、ハッシュから値を取り出す時にも、
配列が返ってきそうな感じするのではないかと思いました。
実際には、@copy_array = $hash{'千葉県'};
のようにすると、@copy_array配列に配列のリファレンスを格納した事になってしまいます。
print ref($hash{'千葉県'});とすると、
$hash{'千葉県'}がリファレンスであり、指しているオブジェクトが配列(ARRAY)である事がわかります。
ref関数は、パラメータが非リファレンスの場合には、偽を返します。
また、デリファレンスの際に通常の感じで、@$hash{'千葉県'}のようにすると、
@$hashとしたように扱われているのではないかと思います。
こうなってしまうと、$hashが配列のレファレンスという意味になってしまい、
$hash->[0];というような事ができる事になってしまいます。
$hashはリファレンスではなく、ハッシュなのでおかしな事になってしまいます。
なので、{ }でデリファレンスする範囲が$hash{'千葉県'}である事を明確にします。
ハッシュや配列のリファレンスでなくても、デリファレンスで必ず{ }をつけても大丈夫だと思います。
サブルーチンのリファレンスに対して&{$func}($param);としてみましたが、
正常に動きました。
ごっそり代入する場合に、
一般的には配列のリファレンスを利用します。
$hash{'千葉県'} = \@chiba;
のようにしますが、ここではリファレンスを代入するよりも、
デリファレンスした配列に配列をコピーする方が分かりやすい気がしたので、
@{$hash{'千葉県'}} = @chiba;
のように、ハッシュの値を配列型にしてから、
代入しました。
こういう場合、一般的には配列の無名リファレンスを使って、
以下のようにするんじゃないかと思います。
%hash = ('千葉県' => ['千葉市', '市川市', '佐倉市', '長生郡'], '埼玉県' => ['草加市', '川口市', '北本市']);
この書き方だと、何をどうしているのか理解しづらいと思います。
簡単に配列を代入できていて、ハッシュから値を取り出す時にも、
配列が返ってきそうな感じするのではないかと思いました。
実際には、@copy_array = $hash{'千葉県'};
のようにすると、@copy_array配列に配列のリファレンスを格納した事になってしまいます。
print ref($hash{'千葉県'});とすると、
$hash{'千葉県'}がリファレンスであり、指しているオブジェクトが配列(ARRAY)である事がわかります。
ref関数は、パラメータが非リファレンスの場合には、偽を返します。
また、デリファレンスの際に通常の感じで、@$hash{'千葉県'}のようにすると、
@$hashとしたように扱われているのではないかと思います。
こうなってしまうと、$hashが配列のレファレンスという意味になってしまい、
$hash->[0];というような事ができる事になってしまいます。
$hashはリファレンスではなく、ハッシュなのでおかしな事になってしまいます。
なので、{ }でデリファレンスする範囲が$hash{'千葉県'}である事を明確にします。
ハッシュや配列のリファレンスでなくても、デリファレンスで必ず{ }をつけても大丈夫だと思います。
サブルーチンのリファレンスに対して&{$func}($param);としてみましたが、
正常に動きました。
特定の要素を、
特定のハッシュの値に追加する場合には、
push(@{$hash{'千葉県'}}, '茂原市');
のように、push関数を利用して、追加します。
この時、受取り側のハッシュは、
代入の時と同じように、
配列型にデリファレンスしておきます。
特定のハッシュの値に追加する場合には、
push(@{$hash{'千葉県'}}, '茂原市');
のように、push関数を利用して、追加します。
この時、受取り側のハッシュは、
代入の時と同じように、
配列型にデリファレンスしておきます。
配列の値を持つハッシュをeach関数で、
キーと値に分ける場合は、
値もスカラー変数として、受け取る事になるので、
受け取った後で、配列型として扱う必要があります。
その為に、foreach文のパラメータは、
@{$city}としてアクセスしています。
キーと値に分ける場合は、
値もスカラー変数として、受け取る事になるので、
受け取った後で、配列型として扱う必要があります。
その為に、foreach文のパラメータは、
@{$city}としてアクセスしています。
このサンプルの実行結果は、
以下のようになります。
以下のようになります。
埼玉県草加市
埼玉県川口市
埼玉県北本市
千葉県千葉市
千葉県市川市
千葉県佐倉市
千葉県長生郡
千葉県茂原市
埼玉県川口市
埼玉県北本市
千葉県千葉市
千葉県市川市
千葉県佐倉市
千葉県長生郡
千葉県茂原市
| 固定リンク
「Perl」カテゴリの記事
- LWP::Simpleのmirrorをgetに変更した。掲示板監視スクリプト(2014.01.25)
- XMLRPC::Liteで更新Ping(2009.05.29)
- 楽天APIで自動アフィリエイトリンク作成(2009.05.19)
- モジュールをインストールしてみる(2008.01.22)
- Perlでコールバック サブルーチンの引数としてサブルーチンの参照を渡す(2007.11.26)
この記事へのコメントは終了しました。
コメント
はじめまして。
push(@{$hash{'千葉県'}}の@{}の記法が長年
分かりませんでした。このブログでやっと解決
しました!ありがとうございました。
ところで、この記法はどの書籍に記されていた
のでしょうか?教えて頂けると幸いです。
よろしくお願いいたします。
投稿: Smoodh! | 2009-07-01 06:29