--- title: ハッシュの勉強 author: kazu634 date: 2008-01-18 wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:3625;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - Perl --- <div class="section"> <p> 『<a href="http://d.hatena.ne.jp/asin/4797336803" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/asin/4797336803', '新版Perl言語プログラミングレッスン入門編');">新版Perl言語プログラミングレッスン入門編</a>』を見ながらPerlの勉強中。ハッシュのところを現在読んでいる。ちなみにハッシュというのは </p> <blockquote title="連想配列 - Wikipedia" cite="http://ja.wikipedia.org/wiki/%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97"> <p> 連想配列(れんそうはいれつ)とは、プログラミング言語において、添え字に文字列等のスカラー数値以外のデータ型も使用できる配列である。抽象データ型のひとつ。連想コンテナ、辞書とも呼ばれる。 </p> <p> <cite><a href="http://ja.wikipedia.org/wiki/%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://ja.wikipedia.org/wiki/%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97', '連想配列 – Wikipedia');" target="_blank">連想配列 – Wikipedia</a></cite> </p> </blockquote> <p> ということで、配列の一種で添え字が数字ではないものだそうです。言われてみると、ハッシュってそういう構造をしている。調べて良かったWikipedia。 </p> <p> <a name="seemore"></a><br /> </p> <h4> ハッシュの基本 </h4> <pre class="syntax-highlight"> <span class="synStatement">use strict</span>; <span class="synStatement">use warnings</span>; <span class="synStatement">my</span> <span class="synIdentifier">%hash</span> = ( <span class="synConstant">'Kazu'</span> => <span class="synConstant">26</span>, <span class="synConstant">'Take'</span> => <span class="synConstant">24</span>, <span class="synConstant">'Yukari'</span> => <span class="synConstant">23</span>, ); <span class="synStatement">foreach</span> <span class="synStatement">my</span> <span class="synIdentifier">$key</span> (<span class="synStatement">keys</span>(<span class="synIdentifier">%hash</span>)){ <span class="synStatement">my</span> <span class="synIdentifier">$value</span> = <span class="synIdentifier">$hash</span>{<span class="synIdentifier">$key</span>}; <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$key</span><span class="synConstant"> --> </span><span class="synIdentifier">$value</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } </pre> <p> こんな感じで使うらしい。foreachのところはイディオムらしいので丸暗記推奨とのことらしい。このイディオムは別な書き方として </p> <pre class="syntax-highlight"> <span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) { <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant"> --> </span><span class="synIdentifier">$hash</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } </pre> <p> でもよい。 </p> <h4> ハッシュに要素を追加する </h4> <p> 基本的に </p> <pre class="syntax-highlight"> <span class="synIdentifier">$hash</span>{<span class="synIdentifier">$key</span>} = <span class="synIdentifier">$value</span>; </pre> <p> という形式で書けば大丈夫。%じゃなくて$だよ。 </p> <p> 例はこんな感じになる。ここでは’Nanbu’をキーとする値を%hashに追加している。 </p> <pre class="syntax-highlight"> <span class="synStatement">use strict</span>; <span class="synStatement">use warnings</span>; <span class="synStatement">my</span> <span class="synIdentifier">%hash</span> = ( <span class="synConstant">'Kazu'</span> => <span class="synConstant">26</span>, <span class="synConstant">'Take'</span> => <span class="synConstant">24</span>, <span class="synConstant">'Yukari'</span> => <span class="synConstant">23</span>, ); <span class="synStatement">print</span> <span class="synConstant">"not added yet:</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synStatement">foreach</span> <span class="synStatement">my</span> <span class="synIdentifier">$key</span> (<span class="synStatement">keys</span>(<span class="synIdentifier">%hash</span>)){ <span class="synStatement">my</span> <span class="synIdentifier">$value</span> = <span class="synIdentifier">$hash</span>{<span class="synIdentifier">$key</span>}; <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$key</span><span class="synConstant"> --> </span><span class="synIdentifier">$value</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } <span class="synIdentifier">$hash</span>{<span class="synConstant">'Nanbu'</span>} = <span class="synConstant">20</span>; <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synSpecial">\n</span><span class="synConstant">added:</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) { <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant"> --> </span><span class="synIdentifier">$hash</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } </pre> <h4> ハッシュで同じキーを使った場合 </h4> <p> 一つのハッシュの中に同じキーが二つ存在することはないので、すでに存在するキーを用いて代入を行うと元の値は失われます。だから、 </p> <pre class="syntax-highlight"> <span class="synStatement">use strict</span>; <span class="synStatement">use warnings</span>; <span class="synStatement">my</span> <span class="synIdentifier">%hash</span> = ( <span class="synConstant">'Kazu'</span> => <span class="synConstant">26</span>, <span class="synConstant">'Take'</span> => <span class="synConstant">24</span>, <span class="synConstant">'Yukari'</span> => <span class="synConstant">23</span>, ); <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synSpecial">\n</span><span class="synConstant">Not Chnage the value yet</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) { <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant"> --> </span><span class="synIdentifier">$hash</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synSpecial">\n</span><span class="synConstant">change value:</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synIdentifier">$hash</span>{<span class="synConstant">'Kazu'</span>} =<span class="synConstant">13</span>; <span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) { <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant"> --> </span><span class="synIdentifier">$hash</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } </pre> <p> というようにすると、$hash{‘Kazu’}の値が変わることになる。 </p> <h4> キーによる並び替え </h4> <p> ハッシュではキーと値の組の順番を気にする必要はないけど、目で見るときには並び替えたくなるんだよ!そういうときはsortを使うよ。 </p> <pre class="syntax-highlight"> <span class="synStatement">use strict</span>; <span class="synStatement">use warnings</span>; <span class="synStatement">my</span> <span class="synIdentifier">%hash</span> = ( <span class="synConstant">'Kazu'</span> => <span class="synConstant">26</span>, <span class="synConstant">'Take'</span> => <span class="synConstant">24</span>, <span class="synConstant">'Yukari'</span> => <span class="synConstant">23</span>, ); <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synSpecial">\n</span><span class="synConstant">Not Sorted:</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) { <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant"> --> </span><span class="synIdentifier">$hash</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synSpecial">\n</span><span class="synConstant">Sorted:</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synStatement">foreach</span> (<span class="synStatement">sort</span> <span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>){ <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant"> --> </span><span class="synIdentifier">$hash</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } </pre> <h4> 値による並び替え </h4> <p> 値で並び替えるときもsortを使うけどごにゃごにゃしてよくわからないや。とりあえずこんな感じらしい。 </p> <pre class="syntax-highlight"> <span class="synStatement">use strict</span>; <span class="synStatement">use warnings</span>; <span class="synStatement">my</span> <span class="synIdentifier">%hash</span> = ( <span class="synConstant">'Kazu'</span> => <span class="synConstant">26</span>, <span class="synConstant">'Take'</span> => <span class="synConstant">24</span>, <span class="synConstant">'Yukari'</span> => <span class="synConstant">23</span>, ); <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synSpecial">\n</span><span class="synConstant">Not Sorted:</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) { <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant"> --> </span><span class="synIdentifier">$hash</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synSpecial">\n</span><span class="synConstant">Sorted:</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synStatement">foreach</span> (<span class="synStatement">sort</span> { <span class="synIdentifier">$hash</span>{<span class="synIdentifier">$a</span>} <=> <span class="synIdentifier">$hash</span>{<span class="synIdentifier">$b</span>} } <span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) { <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant"> --> </span><span class="synIdentifier">$hash</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } </pre> <h4> ハッシュの実例 -配列の要素から重複を除いたリストを作るよ- </h4> <pre class="syntax-highlight"> <span class="synStatement">use strict</span>; <span class="synStatement">use warnings</span>; <span class="synStatement">my</span> <span class="synIdentifier">%uniq</span>; <span class="synStatement">my</span> <span class="synIdentifier">@array</span> = (<span class="synConstant">3</span>, <span class="synConstant">1</span>, <span class="synConstant">4</span>, <span class="synConstant">1</span>, <span class="synConstant">5</span>, <span class="synConstant">9</span>, <span class="synConstant">2</span>, <span class="synConstant">6</span>, <span class="synConstant">5</span>, <span class="synConstant">3</span>, <span class="synConstant">5</span>); <span class="synStatement">foreach</span> (<span class="synIdentifier">@array</span>) { <span class="synIdentifier">$uniq</span>{<span class="synIdentifier">$_</span>} = <span class="synConstant">1</span>; } <span class="synStatement">my</span> <span class="synIdentifier">@uniqarray</span> = <span class="synStatement">keys</span> (<span class="synIdentifier">%uniq</span>); <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">@uniqarray</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; </pre> <p> </p> <h4> ハッシュの実例 -配列の中から値の出現頻度を調べるよ- </h4> <pre class="syntax-highlight"> <span class="synStatement">use strict</span>; <span class="synStatement">use warnings</span>; <span class="synStatement">my</span> <span class="synIdentifier">%uniq</span>; <span class="synStatement">my</span> <span class="synIdentifier">@array</span> = (<span class="synConstant">3</span>, <span class="synConstant">1</span>, <span class="synConstant">4</span>, <span class="synConstant">1</span>, <span class="synConstant">5</span>, <span class="synConstant">9</span>, <span class="synConstant">2</span>, <span class="synConstant">6</span>, <span class="synConstant">5</span>, <span class="synConstant">3</span>, <span class="synConstant">5</span>); <span class="synStatement">foreach</span> (<span class="synIdentifier">@array</span>) { <span class="synIdentifier">$uniq</span>{<span class="synIdentifier">$_</span>}++; } <span class="synStatement">print</span> <span class="synConstant">"値, 出現回数</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; <span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%uniq</span>) { <span class="synStatement">print</span> <span class="synConstant">"</span><span class="synIdentifier">$_</span><span class="synConstant">, </span><span class="synIdentifier">$uniq</span><span class="synConstant">{</span><span class="synIdentifier">$_</span><span class="synConstant">}</span><span class="synSpecial">\n</span><span class="synConstant">"</span>; } </pre> <h4> keys, values, exitsts, delete, undef </h4> <dl> <dt> keys(%hash) </dt> <dd> ハッシュの中にあるキーをすべてリストにして返す関数 </dd> <dt> values(%hash) </dt> <dd> ハッシュの中にある値をすべてリストにして返す関数 </dd> <dt> exists($hash{$key}) </dt> <dd> ハッシュの中にあるキーが存在するかどうかを調べる関数 </dd> <dt> delete $hash{$key} </dt> <dd> ハッシュの中からあるキーとその値を削除する関数 </dd> <dt> undef %hash </dt> <dd> ハッシュの中からすべてのキーと値を削除する関数 </dd> </dl> </div>