2011年10月27日 星期四

雜湊(Hash)

雜湊(Hash)

雜湊(Hash),你可以想像是兩個物品,彼此之間是有繩子綁住,

當我取得其中一個時,另一個也會被我取下。

而在這裡,Hash所扮演的角色就是連接兩物品的那條繩子。

換句話說,因為有繩子的關係,所以不管資料多麼凌亂,

一旦取得一筆資料,與他相連的資料也會被找到,這就是Hash的功用。

Perl敘述用百分比符號(%)表示雜湊,後面要賦予這個雜湊的名稱,並且要以英文開頭,

可以再給予英文以及數字,像是%a%a11%aaa1

同樣要注意,大寫、小寫視為不同雜湊,別搞混了!


接著來用阿逸自己的方式,解釋Hash所綁住的這兩個東西吧!

Hash綁住的兩樣東西,分別叫做 鍵(key) 以及 值(value)

鍵(key)跟值(value)都可以任意放入你想放的東西,比方說,

都可以放入字串、數字、變數(Scalar)甚至是陣列(Array),或是再放雜湊(Hash)進去,都可以!

其中,放入陣列(Array)或是放入雜湊(Hash)都是比較高階的用法了,

這裡就不提這兩個,有興趣的人,可以試著用這些關鍵字找看看,

(像是 Hash of Hash、Hash of Array、Array of Array 等)


Hash的使用方式,整個Hash用%表示(跟整個陣列用@表示一樣)。

取值也跟陣列很像,陣列:陣列名稱換成變數,加上中括號[]表示位置。如 $array[0]

而雜湊則是:雜湊名稱換成變數,加上大括號{}表示鍵(key)。如 $hash{key}

用一個簡單的例子來說明怎麼使用吧!

my %Hash;# 宣告一個Hash

$Hash{'阿信'}= '主唱'; # 鍵(key)設為阿信 值(value)設為主唱

$Hash{'怪獸'}= '吉他手'; # ...

$Hash{'石頭'}= '吉他手'; # ...

$Hash{'冠佑'}= '鼓手'; # ...

$Hash{'瑪莎'}= '貝斯手'; #...

print "請輸入五月天的成員:"; # 先印出一段文字給使用者看

my $name = <STDIN>; # 等待使用者輸入 並且將字串存到變數裡

chomp $name; # 把使用者輸入的字串做chomp 把多餘的Enter拿掉 (因為輸入後 會按Enter)

print "$name 是 $Hash{$name}"; # 印出鍵(Key) 以及 值(value)

執行結果就會是:

有趣吧!值得注意的是,在Hash裡,

值(value)是允許有重複的(如上圖有兩個吉他手),而鍵(key)則不允許。


從上面的程式碼,我們可以知道利用$Hash{'阿信'}= '主唱';的方式,

來給予一對鍵(key)、值(value)給雜湊,

當然,我們也可以像是陣列(Array)那篇有介紹過一樣,利用串列來賦予鍵值:

my %Hash = qw/阿信 主唱 怪獸 吉他手/; # 串列會依序給予鍵、值

這樣的寫法,得到的結果,會跟上面給予鍵、值方式一樣。

另一種則是利用箭號(=>)表示雜湊中,鍵跟值的相對關係。

而且在一對鍵、值的後面要加上逗號作為區隔:

my %Hash = (

阿信 => '主唱',

怪獸 => '吉他手',

);

不過當你在使用箭號進行指定時,箭號左邊的鍵(key)會被視為一個字串。


知道如何賦予鍵、值後,接下來我們來看看怎麼取出這些鍵、值。

如果我要取出全部的鍵,會使用到一個保留字 keys

表示我要取出所有鍵(keys),而取出的鍵,我們會用一個陣列(array)來存放:

my @keys = keys(%Hash); # 將所有鍵取出 存入陣列

同樣的,取出所有值(values):

my @values = values(%Hash); # 將所有值取出 存入陣列

上面兩個例子都是分別取出所有鍵、或是所有值。

而如果希望取出每一對鍵、值,則會使用each

each的作用,跟陣列裡,使用foreach取得所有元素的性質一樣。

我們拿之前的例子來看:

my %Hash;# 宣告一個Hash

$Hash{'阿信'}= '主唱'; # 鍵(key)設為阿信 值(value)設為主唱

$Hash{'怪獸'}= '吉他手'; # ...

$Hash{'石頭'}= '吉他手'; # ...

$Hash{'冠佑'}= '鼓手'; # ...

$Hash{'瑪莎'}= '貝斯手'; #...

while (my ($key, $value) = each(%Hash)) # 逐次把Hash裡的鍵、值 分別放入變數

{

print "$key 是 $value\n"; # 逐次印出每一對的鍵、值 並換行一次

}

執行結果就會是:


知道怎麼給予雜湊鍵與值後,最後我們來講雜湊的操作。

阿逸認為最重要的就是這兩個:exist以及delete

最常出現的例子就是,我要如何知道某鍵(key)到底有沒有出現過?

判別方式就是使用exist對雜湊做判定。

一樣我們直接看例子:

my %Hash;# 宣告一個Hash

$Hash{'阿信'}= '主唱'; # 鍵(key)設為阿信 值(value)設為主唱

$Hash{'怪獸'}= '吉他手'; # ...

$Hash{'石頭'}= '吉他手'; # ...

$Hash{'冠佑'}= '鼓手'; # ...

$Hash{'瑪莎'}= '貝斯手'; #...

if (exists $Hash{'阿信'})# 如果阿信存在

{

print "阿信 是 $Hash{'阿信'}"; # 印出鍵(Key) 以及 值(value)

}

而如果某一對鍵、值我們不需要了,就可以用delete移除。

使用的方式也很簡單:

delete $Hash{'士杰'};

就可以清除掉我們不需要的鍵、值。

知道雜湊的鍵、值賦予以及對雜湊的操作後,

接下來就要講副常式(Subroutine)的使用了!

沒有留言:

張貼留言