## 哈希是鍵/值對
如果你想按名字查詢,那么需要哈希。哈希的鍵必須唯一,但值可以是任意標量。
有時候你仍然會看到人們稱它為“關聯數組”,但不要想當然的把它作為數組。
## 通過鍵/值對列表來創建哈希
使用鍵/值對列表創建哈希:
~~~
my %stooges = (
'Moe', 'Howard',
'Larry', 'Fine',
'Curly', 'Howard',
'Iggy', 'Pop',
);
~~~
`=>`?稱為胖逗號,它與逗號相同,前面的單詞加上引號:
~~~
my %stooges = (
Moe => 'Howard',
Larry => 'Fine',
Curly => 'Howard',
Iggy => 'Pop',
);
~~~
哈希在列表環境中變成鍵/值對列表。
~~~
my @hash_as_an_array = %stooges;
# Contains ( 'Curly', 'Haward', 'Larry', 'Fine', etc... )
~~~
正如哈希的鍵和值順序事實上隨機的一樣,平展開的哈希鍵/值順序也是隨機的。
## 利用花括號訪問獨立的哈希條目
利用花括號代替中括號來獲取哈希的值。
~~~
print $stooges{'Iggy'};
# Prints "Pop"
~~~
用同樣的方式設置值:
~~~
$stooges{'Shemp'} = 'Howard';
~~~
覆蓋現有的值:
~~~
$stooges{'Iggy'} = 'Ignatowski';
~~~
從哈希中刪除條目:
~~~
delete $stooges{'Curly'};
~~~
注意:`delete`?不會刪除文件。`unlink`?才會。
~~~
unlink $stooges{'Moe'};
# Deletes a file called 'Howard';
~~~
## 獲取哈希的鍵/值
使用?`keys`?和?`values`?關鍵字:
~~~
my @stooge_first_names = keys %stooges;
my @stooge_last_names = values %stooges;
~~~
這會保證鍵和值的順序相匹配。
## 哈希鍵自引用單詞
如果你的哈希鍵是單個詞,那么你不需要引用它。
~~~
$stooges{Curly} = 'Howard';
~~~
## 哈希只能包含標量
在 Perl 哈希中的值只能是標量。它不能包含數組或數組中的列表。
~~~
$hash{comedians} = @stooges;
# Assigns the length of @stooges to the value
~~~
如果你想要在哈希中存儲數組,你將需要使用引用。
## 哈希是無序的
`keys %hash`?和?`values %hash`?的順序實事上是隨機的。每次執行程序都將不同。 它也與添加時的順序不相關。
如果你想保留哈希元素添加時的順序,那么可以使用?[Tie::IxHash](https://metacpan.org/module/Tie::IxHash)?模塊。
## 你無法排序哈希
在 Perl 中排序哈希的想法不存在,因為哈希是無序的。你可以排序哈希的鍵, 或哈希的值,它們只是列表而已。
## 使用列表賦值合并哈希
要合并兩個哈希,將它們看作列表,并賦給哈希。
~~~
my %new_hash = (%hash1, %hash2);
~~~
等號右邊是來自兩個哈希的鍵/值對長列表。然后將該列表賦給?`%new_hash`。 如果在`%hash2`?中的任意鍵與?`%hash1`?中的鍵重復,那么?`%hash2`?中的鍵/值 對具有更高的優先級,因為它們賦值更晚。
## 何時使用哈希,何時使用數組
如果你做線性、有序的序列,那么使用數組。
* 要讀取的文件列表
* 隊列中的人列表
如果你做想要查詢的無序的事,那么使用哈希。
* 姓索引,通過名字查詢
* 顯示文件大小的索引,按名稱查詢
## `defined`?與?`exists`?的差異
使用?`defined`?來看哈希元素是否有?`undef`?之外的值。如果哈希元素有任意?`undef`?之外的值,甚至求值為假的 0 和 ""(空字符串),都將返回真。
使用?`exists`?來看哈希元素是否已被初始化,即便它沒有被定義(如,它有值`undef`)。
~~~
my %h;
$h{'foo'} = undef;
defined $h{'foo'} ? print 1 : print 0;
# $h{'foo'} is not defined, so it prints 0
exists $h{'foo'} ? print 1 : print 0;
# but it has been initialized nonetheless, and so this line prints 1
~~~
哈希元素僅被定義后才為真。它僅在存在后才能被定義。
然而,哈希元素未被定義仍能存在。這意味著即便它存在,也不會返回真。
~~~
if ( $h{'foo'} ) {
print 'true';
}
else {
print 'false';
}
# prints 'false'; since $h{'foo'} is not defined, it cannot be true
~~~