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

272 lines
17 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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>