[精讚] [會員登入]
1227

[PERL] 10- 雜湊

Perl 的hash 指標陣列

此文完整連結 http://n.sfs.tw/10933

複製連結 [PERL] 10- 雜湊@新精讚
(文章歡迎轉載,務必尊重版權註明連結來源)
2019-01-30 13:11:23 最後編修
2017-03-22 10:48:54 By 張○○
 

PERL 除了陣列外,還有另一種雜湊(hash),又名「指標陣列」,未免和陣列混淆,此系列文全以「雜湊」稱之,在PHP裡常用的陣列 $arr['key']=  'value' 對PERL來說就是一種雜湊。

雜湊的基本性質

陣列使用符號 '%'作為開頭,並接上名稱  %hash_name

定義一個空雜湊

  %arr_name=();

移除雜湊

  undef %arr_name;

雜湊的定義

  $hash= (鍵1=>值1, 鍵2=>值2, 鍵3=>值3, 鍵4=>值4, ... );

定義雜湊的內容 

  %coins = ( "Quarter" , 25, "Dime" , 10, "Nickel", 5 );

  %number= ( 1 => 'one', 2 => 'two', 3 => 'three', );

最後的 ',' 可留可不留,不會出錯。

要取得雜湊項目的方法:

print $coins{"Dime"};  # 10
print $number{3};  # three ,直接用數值作key
print $number{"2"};  # two 也可用字串作key
print $coins{"Dollar"}; # '' 不存在為空 

這裡要注意的是取得陣列項目時,他的變數前面是錢號'$'而不是'%',後面的括號是大括號{ }

取得雜湊的大小

$size = keys %coins;

keys是取回%coins雜湊的所有key形成陣列,再用純量方式取得大小,上面相當於:

@keys = keys %coins;
$size = scalar( @keys);

移除及加入項目

加入一個項目

  $number{4}='four';

  $coin{'dime'} = 100;

移除一個項目

  undef $number{1};

  undef $coin{'Dime'};

  delete $coin{'Quarter'};

檢查雜湊值是否存在

錯誤 有可能該值為0

if( $coin{'Dime'} ){ ... }

正確作法,使用函數 exists

if( exists( $coin{'Dime'} ){ ... }

合併雜湊

%coins = ( "Quarter" , 25, "Dime" , 10, "Nickel", 5 );
%number= ( 1 => 'one', 2 => 'two', 3 => 'three', );
%coins = ( %coins, %number);

合併時如果兩個 hash key相同,後壓前

 

傾印雜湊

和陣列不一樣,得使用迴圈的方式,迴圈在後面的章節會再介紹,先看怎麼傾印。

while (($key, $value) = each(%coins))
{
     print $key.", ".$value. "\n";
}

也可以先取出keys的陣列,再用keys來取值

foreach (keys %coins)
{
    print "$_ is ". $coins{$_}. "\n";
}

第3行出現了第2個特殊變數$_(第1個是在陣列時出現的$#),這個變數的意思就是「迴圈的目前這個項目」,在迴圈中是能偷懶的東西,在後面的章節會再介紹。

 

多維雜湊

多維雜湊比較麻煩,可使用參照的方式,詳細可參考後面的文章 [PERL] 17-參照@新精讚

這裡先列舉個範例不作說明

$ref = {
  'tw'=>{'name' => '王小明',  'age' => 33, 'job' => '工程師'},
  'jp'=>{'name' => '李小華',  'age' => 44, 'job' => '業務'},
};

foreach $key (keys $ref) {
     print "$key\n";
     foreach $k (sort keys $ref->{$key}) {
        print "$k=> ". $ref->{$key}{$k} . "\n" ;
     }
}

結果

tw
age=> 33
job=> 工程師
name=> 王小明
jp
age=> 44
job=> 業務
name=> 李小華

 

排序

雜湊的排序基本上是沒什麼意義,但如果你有需要。

由key 值排序

還記得前面在陣列上教過的排序,由keys排序完再依序取回值,要注意這只是依鍵取回值,雜湊本身的順序並不會改變:

foreach $key (sort keys %coins) {
     print "$key: $coins{$key}\n";
}

由值排序

由值排序比較麻煩,作法是先把值排序完取回鍵,再由鍵依序取回雜湊內容:

foreach $key (sort {$coins{$a} cmp $coins{$b} }  keys %coins)
{
    print "$key $coins{$key}\n";
}

第1式(sort {$coins{$a} cmp $coins{$b} } keys %coins)

可以拆成這樣看

  (sort {由值排序} @keys)

還記得這就是前面教過陣列的排序寫法,回傳的就是由值排序完的鍵陣列了。

 

上一篇 09-迴圈
回到目錄 01-撰寫第一隻PERL程式
下一篇 11-雜湊的範例

參考資料

[1] http://www.tizag.com/perlT/perlhashes.php

[2] http://www.cs.mcgill.ca/~abatko/computers/programming/perl/howto/hash/


編修原文 2009-12-09 14:03:33

你可能感興趣的文章

[PERL] 使用CPAN安裝模組 在Linux 上,CPAN 可以用來安裝或管理 perl 的模組,此文教你怎麼做。

Perl 計算經過的時間 Perl 計算程式執行經過的時間

[PERL] 22-日期和時間 Perl 取得日期時間的方法整理,使用 localtime等多種函數

自行撰寫syslog server建立資訊安全控管中心#1 -- 前言及syslog介紹 利用PERL將syslog收攏到資料庫的程式

[PERL] 02-註解、變數和常數 perl的註解、變數和常數

[PERL] 21- 使用資料庫 Perl 連Mysql

自行撰寫syslog server建立資訊安全控管中心#4 -- 過濾條件設定 利用PERL將syslog收攏到資料庫的程式,過濾條件設定

[PERL] 中文字字串拆解 中文字字串拆解是門學問

[PERL] 檢查IP是否在某個網段內:matchcidr 檢查IP是否在某個網段內 matchcidr in perl

[PERL] 19-模組的安裝和維護 模組的安裝和維護

我有話要說


限制:留言最高字數1000字,超過部分會被截掉。請注意:留言不可帶有網址,會被濾掉。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

[Freebsd] 使用 ADSL 撥接上網 Freebsd上要使用 ADSL 撥接上網,該如何設定?

TFTP Server 安裝及使用 讓設備的網路設定檔或是韌體經由TFTP拷備出來,操作的方法

[CodeIgniter3] 解決無法上傳特定檔案(.sb2)的問題 上傳時出現The filetype you are attempting to upload is not allowed,要怎麼解決?

一個邏輯的錯誤刪了全部檔案的經驗 今天本來想做一件很簡單的事,但卻足足浪費我多一倍的時間,再加上刪掉我全部的檔案,原因只是因為我自己的邏輯錯誤。

好用的3+2碼郵遞區號查詢系統推薦 網路上找到用地址輸入判斷3+2碼郵遞區號的辨識率不高,除了這個網站…