exists/delete

2013-08-24 01:37

5.6 雜湊的操作 
毫無疑問,雜湊這樣的資料結構對於程式的寫作有著莫大的幫助,但是我們必須能熟悉對雜湊的操作才能夠讓我們更容易發揮雜湊的功能。其中最重要的大概就是 exists跟delete兩個函數了,這兩個函式能讓我們有效的掌握雜湊的元素,同時它們也是perl內建相關於雜湊函數的最後兩個(註一)。
5.6.1 exists
我們就繼續用ip跟主機的雜湊當例子吧。假如我有一個ip,我不確定我是否有這部主機的資料,如果我們只用剛剛的方法,那我們就必須取得所有的ip,然後把手上的ip跟取得的ip串列一一比對,以便確定自己有沒有這個ip的主機資料。所以我們的程式也許長的像這樣:

 


my %hash = (
            '168.1.2.1' => 'verdi',
            '192.1.2.2' => 'wagner',
            '168.1.2.3' => 'beethoven',
            );
my $ip = '192.1.2.2';
print "bingo" if ($hash{$ip});


在這裡,我們有一個雜湊,其中三個鍵分別是'168.1.2.1','192.1.2.2','168.1.2.3',而我們希望判定目前手上的一組 ip'192.1.2.2'是不是我們主機所擁有的ip。於是我們利用這個ip作為雜湊鍵,並判斷如果取得的值為真,那麼我們就說這個ip屬於雜湊的其中 一個鍵,這樣的想法似乎暫時解決了我們的需求。不過我們來看看下面的例子:
 


my %hash = (
            'cd' => 2,
            'book' => 10,
            'video' => 0,
            );
my $media = 'video';
print "bingo" if ($hash{$media});


我們假設這是某個社區圖書館目前外借的東西數量,其中的鍵就是代表則可以外借的圖書館資產,其中包含了CD,書跟錄影帶。而所對應到的值則是他們目前被借 出的數量。我們看到,CD被借走了兩套,書被借走了十本,而錄影帶則是原封不動,一卷也沒被借走。是的,大家都不喜歡錄影帶了。
這時候,我們希望知道圖書館是否提供錄影帶外借,也就是要檢查video這個鍵是否存在。於是我們利用剛剛的方式,看看$hash{$media}是否傳 回真值。很遺憾,因為錄影帶這個鍵目前的值是0,因此當我們利用錄影帶當成鍵來取的相對應的值時,Perl會傳回0給我們。而我們知道0其實是個偽值。於 是我們以為'video'這個鍵並不存在於這個雜湊中,也就是說這個圖書館並沒有錄影帶出借,但是這樣的結果跟我們的認知有所不同,因為取得的值為0只是 代表目前沒人借出。所以我們發現這個方法並不正確,至少我們已經知道他會產生錯誤的結果。所以我們必須嘗試其他方法,例如利用keys找到包含所有索引鍵 的串列,然後進行一一的比對。就像這樣:

 


print "exist" if (grep { $_ eq 'video' } keys (%hash));


這樣就可以確定某個鍵是否存在於這個雜湊,可是程式還是有點長,而且我們也許必須經常去判斷某個值是否為雜湊的鍵。所幸Perl提供了簡潔的函式可以使 用,所以利用exists這個函式讓我們有了極佳的判斷方式。有了exist之後,對於剛剛那一行程式,我們只需要這麼改寫:
 


print "exists" if (exists $hash{video});


這樣的寫法顯然輕鬆了許多。

5.6.2 delete
有些時候,我們也會遇到某些鍵值我們不再需要的狀況,這時候如果可以把這些沒有必要的鍵值移除似乎是非常必要的。所以Perl也提供了移除雜湊鍵值的函式,也就是delete。這個函式的使用其實非常容易,你只需要指定想要刪除的某一個雜湊鍵,就像這樣:

 


delete $hash{video};


當然,所謂的移除是指這個鍵將不再存在於這個雜湊,而不是指讓這個鍵對應的雜湊值消失。所以並不是把需要被delete的這對鍵值設為undef。也就是 說,即使有一個鍵所對應的雜湊值為undef,那這個鍵依然被視為存在(exists)的,這在剛剛解釋exists這個函數的例子中就可以了解了。