Perl關聯數組用法集錦
本文和大家重點討論一下Perl關聯數組的概念,創建Perl關聯數組,從數組變量復制到Perl關聯數組,元素的增刪,用Perl關聯數組循環等內容,相信通過本文的學習你對Perl關聯數組的用法一定會有深刻的認識。
Perl關聯數組
一、創建Perl關聯數組
可以用單個賦值語句創建Perl關聯數組,如:
%fruit=("apples",17,"bananas",9,"oranges","none");
此語句創建的Perl關聯數組含有下面三個元素:
◆下標為apples的元素,值為17
◆下標為bananas的元素,值為9
◆下標為oranges的元素,值為none
注:用列表給Perl關聯數組賦值時,Perl5允許使用"=>"或","來分隔下標與值,用"=>"可讀性更好些,上面語句等效于:
%fruit=("apples"=>17,"bananas"=>9,"oranges"=>"none");
二、從數組變量復制到Perl關聯數組
與列表一樣,也可以通過數組變量創建Perl關聯數組,當然,其元素數目應該為偶數,如:
@fruit=("apples",17,"bananas",9,"oranges","none");
%fruit=@fruit;
反之,可以把Perl關聯數組賦給數組變量,如:
%fruit=("grapes",11,"lemons",27);
@fruit=%fruit;
注意,此語句中元素次序未定義,那么數組變量@fruit可能為("grapes",11,"lemons",27)或("lemons",27,"grapes",11)。
Perl關聯數組變量之間可以直接賦值,如:%fruit2=%fruit1;還可以把數組變量同時賦給一些簡單變量和一個Perl關聯數組變量,如:
($var1,$var2,%myarray)=@list;
此語句把@list的第一個元素賦給$var1,第二個賦給$var2,其余的賦給%myarray。
最后,Perl關聯數組可以通過返回值為列表的內嵌函數或用戶定義的子程序來創建,下例中把split()函數的返回值--一個列表--賦給一個Perl關聯數組變量。
- 1:#!/usr/local/bin/perl
- 2:
- 3:$inputline=;
- 4:$inputline=~s/^\s+|\s+\n$//g;
- 5:%fruit=split(/\s+/,$inputline);
- 6:print("Numberofbananas:$fruit{\"bananas\"}\n");
運行結果如下:
oranges5apples7bananas11cherries6
Numberofbananas:11
三、元素的增刪
增加元素已經講過,可以通過給一個未出現過的元素賦值來向Perl關聯數組中增加新元素,如$fruit{"lime"}=1;創建下標為lime、值為1的新元素。
刪除元素的方法是用內嵌函數delete,如欲刪除上述元素,則:
delete($fruit{"lime"});
注意:
1、一定要使用delete函數來刪除Perl關聯數組的元素,這是唯一的方法。
2、一定不要對Perl關聯數組使用內嵌函數push、pop、shift及splice,因為其元素位置是隨機的。
四、列出數組的索引和值
上面已經提到,keys()函數返回Perl關聯數組下標的列表,如:
- %fruit=("apples",9,
- "bananas",23,
- "cherries",11);
- @fruitsubs=keys(%fruits);
這里,@fruitsubs被賦給apples、bananas、cherries構成的列表,再次提請注意,此列表沒有次序,若想按字母順序排列,可使用sort()函數。
@fruitindexes=sortkeys(%fruits);
這樣結果為("apples","bananas","cherries")。類似的,內嵌函數values()返回Perl關聯數組值的列表,如:
%fruit=("apples",9,
"bananas",23,
"cherries",11);
@fruitvalues=values(%fruits);
這里,@fruitvalues可能的結果為(9,23.11),次序可能不同。
五、用Perl關聯數組循環
前面已經出現過利用keys()函數的foreach循環語句,這種循環效率比較低,因為每返回一個下標,還得再去尋找其值,如:
foreach$holder(keys(%records)){
$record=$records{$holder};
}
Perl提供一種更有效的循環方式,使用內嵌函數each(),如:
%records=("Maris",61,"Aaron",755,"Young",511);
while(($holder,$record)=each(%records)){
#stuffgoeshere
}
each()函數每次返回一個雙元素的列表,其第一個元素為下標,第二個元素為相應的值,最后返回一個空列表。
注意:千萬不要在each()循環中添加或刪除元素,否則會產生不可預料的后果。
六、用Perl關聯數組創建數據結構
用Perl關聯數組可以模擬在其它高級語言中常見的多種數據結構,本節講述如何用之實現:鏈表、結構和樹。
1、(單)鏈表
鏈表是一種比較簡單的數據結構,可以按一定的次序存貯值。每個元素含有兩個域,一個是值,一個是引用(或稱指針),指向鏈表中下一個元素。一個特殊的頭指針指向鏈表的第一個元素。
在Perl中,鏈表很容易用Perl關聯數組實現,因為一個元素的值可以作為下一個元素的索引。下例為按字母順序排列的單詞鏈表:
- %words=("abel","baker",
- "baker","charlie",
- "charlie","delta",
- "delta","");
- $header="abel";
下標為delta的最后一個元素的值為空串,表示鏈表的結束。在將要處理的數據個數未知或其隨程序運行而增長的情況下,鏈表十分有用。
此程序分為三個部分:
◆主程序:讀取輸入并轉換到相應的格式。
◆子程序:add_word_to_list,建立排序單詞鏈表。
◆子程序:print_list,輸出單詞鏈表
第3~17行為主程序,第4行初始化鏈表,將表頭變量$header設為空串,第5行起的循環每次讀取一行輸入,第7行去掉頭、尾的空格,第8行將句子分割成單詞。9~15行的內循環每次處理一個單詞,如果該單詞的最后一個字符是標點符號,就去掉。第13行把單詞轉換成全小寫形式,第14行傳遞給子程序add_word_to_list。
子程序add_word_to_list先在第24行處檢查鏈表是否為空。如果是,第25行將單詞賦給$header,26行創建鏈表第一個元素,存貯在Perl關聯數組%wordlist中。如果鏈表非空,37行檢查第一個元素是否與該單詞相同,如果相同,就立刻返回。下一步檢查這一新單詞是否應該為鏈表第一個元素,即其按字母順序先于$header。
如果是這樣,則:
1、創建一個新元素,下標為該新單詞,其值為原第一個單詞。
2、該新單詞賦給$header。
如果該新單詞不該為第一個元素,則40~44行利用局域變量$pointer尋找其合適的有效位置,41~44行循環到$wordlist{$pointer}大于或等于$word為止。接下來46行查看該單詞是否已在鏈表中,如果在就返回,否則47~48行將其添加到鏈表中。首先47行創建新元素$wordlist{$word},其值為$wordlist{$pointer},這時$wordlist{$word}和$wordlist{$pointer}指向同一個單詞。然后,48行將$wordlist{$pointer}的值賦為$word,即將$wordlist{$pointer}指向剛創建的新元素$wordlist{$word}。
最后當處理完畢后,子程序print_list()依次輸出鏈表,局域變量$pointer含有正在輸出的值,$wordlist{$pointer}為下一個要輸出的值。
注:一般不需要用鏈表來做這些工作,用sort()和keys()在Perl關聯數組中循環就足夠了,如:
foreach$word(sortkeys(%wordlist)){
#printthesortedlist,orwhatever}
但是,這里涉及的指針的概念在其它數據結構中很有意義。
【編輯推薦】