ハッシュ(3) 要素の操作

ハッシュ内の要素(キーと値のペア)を操作する関数を調べます。
まずは要素の削除から。ハッシュ内の特定の要素を削除するには delete 関数を使います。

# hash6.pl
my %tastes = (
	pepper => 'hot',
	cake   => 'sweet',
	lemon  => 'sour',
);
 
sub eat {
	for (sort keys %tastes) {
		print "Eating a $_ ... so $tastes{$_}!\n";
	}
	print "Bulp.\n";
}
 
eat();
delete $tastes{pepper};   # pepper を削除
eat();

delete $tastes{pepper}; でハッシュ %tastes から、キーが pepper である要素を削除しています。
eat は %tastes の食べ物を食べて感想を述べる(+ゲップする)関数です。(^_^;)
実行結果です。

Eating a cake ... so sweet!
Eating a lemon ... so sour!
Eating a pepper ... so hot!
Bulp.
Eating a cake ... so sweet!
Eating a lemon ... so sour!
Bulp.

pepper を削除した後の eat では pepper が表示されていない事がわかります。
ハッシュの要素が定義されているか調べるには関数 exists を使います。

# hash7.pl
my %fruits_basket = (
	apples  => 3,
	bananas => 5,
	oranges => 2,
);
 
print "The basket has: ";
for (sort keys %fruits_basket) {
	print "$fruits_basket{$_} $_, ";
}
print "\n";
 
print "Got apples? => ";
print exists $fruits_basket{apples} ? "Yes!" : "No.", "\n";
 
print "Got grapes? => ";
print exists $fruits_basket{grapes} ? "Yes!" : "No.", "\n";

exists で果物がバスケットに存在するかを尋ねています。三項演算子である A ? B : C は、A が真である時に B を、偽である時は C を返します。
実行結果です。

The basket has: 3 apples, 5 bananas, 2 oranges,
Got apples? => Yes!
Got grapes? => No.

気をつけるべきなのは、たとえ値が偽でもハッシュに存在すれば exists で真と評価されるという事です。
例えば、

# hash8.pl
my %fruits_basket = (apples => 3, bananas => 5, oranges => 2);
 
$fruits_basket{apples} = 0;
print "All apples are eaten.\n";
 
print "How many apples? => ";
print "$fruits_basket{apples} apples.\n";
print "Got apples? => ";
print exists $fruits_basket{apples} ? "Yes!" : "No.", "\n";

を実行すると、以下のように表示されます。

All apples are eaten.
How many apples? => 0 apples.
Got apples? => Yes!

リンゴは全て食べてしまって「0個」になっているにもかかわらず、「Got apples?(リンゴはありますか?)」の問いに「Yes!」と答えています。(^_^;)
この場合は、exists を使わずに $fruits_basket{apples} を直接評価するようにすれば大丈夫です。(もしくは delete してハッシュから削除する)

# hash8.pl
my %fruits_basket = (apples => 3, bananas => 5, oranges => 2);
 
$fruits_basket{apples} = 0;
print "All apples are eaten.\n";
 
print "How many apples? => ";
print "$fruits_basket{apples} apples.\n";
print "Got apples? => ";
print $fruits_basket{apples} ? "Yes!" : "No.", "\n";

実行結果です。

All apples are eaten.
How many apples? => 0 apples.
Got apples? => No.

今度はちゃんと答えてくれました。(^_^)