blog/content/post/2008-01-18-00000756.md

272 lines
17 KiB
Markdown
Raw Normal View History

2019-03-31 11:00:21 +00:00
---
title: ハッシュの勉強
author: kazu634
date: 2008-01-18
url: /2008/01/18/_809/
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', '連想配列 &#8211; Wikipedia');" target="_blank">連想配列 &#8211; 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> =&#62; <span class="synConstant">26</span>,
<span class="synConstant">'Take'</span> =&#62; <span class="synConstant">24</span>,
<span class="synConstant">'Yukari'</span> =&#62; <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">&#34;</span><span class="synIdentifier">$key</span><span class="synConstant"> --&#62; </span><span class="synIdentifier">$value</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</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">&#34;</span><span class="synIdentifier">$_</span><span class="synConstant"> --&#62; </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">&#34;</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>
 例はこんな感じになる。ここでは&#8217;Nanbu&#8217;をキーとする値を%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> =&#62; <span class="synConstant">26</span>,
<span class="synConstant">'Take'</span> =&#62; <span class="synConstant">24</span>,
<span class="synConstant">'Yukari'</span> =&#62; <span class="synConstant">23</span>,
);
<span class="synStatement">print</span> <span class="synConstant">&#34;not added yet:</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</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">&#34;</span><span class="synIdentifier">$key</span><span class="synConstant"> --&#62; </span><span class="synIdentifier">$value</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>;
}
<span class="synIdentifier">$hash</span>{<span class="synConstant">'Nanbu'</span>} = <span class="synConstant">20</span>;
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">added:</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>;
<span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) {
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synIdentifier">$_</span><span class="synConstant"> --&#62; </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">&#34;</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> =&#62; <span class="synConstant">26</span>,
<span class="synConstant">'Take'</span> =&#62; <span class="synConstant">24</span>,
<span class="synConstant">'Yukari'</span> =&#62; <span class="synConstant">23</span>,
);
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">Not Chnage the value yet</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>;
<span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) {
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synIdentifier">$_</span><span class="synConstant"> --&#62; </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">&#34;</span>;
}
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">change value:</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</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">&#34;</span><span class="synIdentifier">$_</span><span class="synConstant"> --&#62; </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">&#34;</span>;
}
</pre>
<p>
というようにすると、$hash{&#8216;Kazu&#8217;}の値が変わることになる。
</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> =&#62; <span class="synConstant">26</span>,
<span class="synConstant">'Take'</span> =&#62; <span class="synConstant">24</span>,
<span class="synConstant">'Yukari'</span> =&#62; <span class="synConstant">23</span>,
);
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">Not Sorted:</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>;
<span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) {
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synIdentifier">$_</span><span class="synConstant"> --&#62; </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">&#34;</span>;
}
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">Sorted:</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</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">&#34;</span><span class="synIdentifier">$_</span><span class="synConstant"> --&#62; </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">&#34;</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> =&#62; <span class="synConstant">26</span>,
<span class="synConstant">'Take'</span> =&#62; <span class="synConstant">24</span>,
<span class="synConstant">'Yukari'</span> =&#62; <span class="synConstant">23</span>,
);
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">Not Sorted:</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>;
<span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%hash</span>) {
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synIdentifier">$_</span><span class="synConstant"> --&#62; </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">&#34;</span>;
}
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synSpecial">\n</span><span class="synConstant">Sorted:</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>;
<span class="synStatement">foreach</span> (<span class="synStatement">sort</span> { <span class="synIdentifier">$hash</span>{<span class="synIdentifier">$a</span>} &#60;=&#62; <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">&#34;</span><span class="synIdentifier">$_</span><span class="synConstant"> --&#62; </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">&#34;</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">&#34;</span><span class="synIdentifier">@uniqarray</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</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">&#34;値, 出現回数</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>;
<span class="synStatement">foreach</span> (<span class="synStatement">keys</span> <span class="synIdentifier">%uniq</span>) {
<span class="synStatement">print</span> <span class="synConstant">&#34;</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">&#34;</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>