2015-05-08 28 views
0

我在Perl中有一個散列,如下所示。有:基於密鑰在Perl中讀取散列

%typeMethodsMap = (
    CHECK_REP_EXISTS => "1_abc", 
    CHECK_JDK_VERSION => "2_abc", 
    CHECK_BLOCKS_FAILED => "1_xyz", 
    CHECK_OR_EXISTS => "2_xyz", 
    CHECK_UPG_EXISTS => "3_xyz", 
    CHECK_SSO_EXISTS => "4_xyz" 
); 

當讀取散列時,鍵不按定義讀取,而是隨機讀取。我需要讀取並通過基於鍵即CHECK_BLOCKS_FAILED的升序格式散列循環,隨後CHECK_OR_EXISTS接着CHECK_UPG_EXISTSCHECK_SSO_EXISTS爲值"1_xyz""2_xyz""3_xyz""4_xyz"分別運行。

請讓我知道,如果任何機構可以幫助我在這裏?

+2

可能的重複[如何維護我添加到Perl哈希鍵的順序?](http://stackoverflow.com/questions/1558625/how-can-i-maintain-the-order-of-keys-i-add-to-perl-hash) – Biffen

+0

非常抱歉,我現在編輯了我的問題 –

+0

你能否請重新檢查我改變的問題並提供解決方案? –

回答

4

是的。按照設計,散列鍵是隨機的順序。

有很多原因 - 覆蓋在perlseckeys - 但它的長短不一,如果您需要保留鍵排序,您需要使用sort

還是一個slice

my @order = qw (first second third); 

my %hash = (second => 'a', third => 'b', first => 'c'); 

print "@hash{@order}"; 

或者:

foreach my $key (@order) { 
    print "$key = $hash{$key}\n"; 
} 

陣列明確數字排序。哈希是明確無序的(或隨機順序)。

如果您是自定義排序,那麼您可以使用任何您喜歡的函數,根據比較值返回-1,0或1。

cmp這是爲字符串做的,<=>是爲數字做的。

說明自定義排序,它可能是這樣的:

use strict; 
use warnings; 

use Data::Dumper; 

my %typeMethodsMap = (
    CHECK_REP_EXISTS => "1_abc", 
    CHECK_JDK_VERSION => "2_abc", 
    CHECK_BLOCKS_FAILED => "1_xyz", 
    CHECK_OR_EXISTS => "2_xyz", 
    CHECK_UPG_EXISTS => "3_xyz", 
    CHECK_SSO_EXISTS => "4_xyz", 
); 

my @order = qw(
    CHECK_REP_EXISTS 
    CHECK_JDK_VERSION 
    CHECK_BLOCKS_FAILED 
    CHECK_OR_EXISTS 
    CHECK_UPG_EXISTS 
    CHECK_SSO_EXISTS 
); 

my $count = 0; 
my %magic_order = map { $_ => $count++ } @order; 
print Dumper \%magic_order; 

sub custom_sort { 
    return $magic_order{$a} <=> $magic_order{$b}; 
} 

foreach my $key (sort { custom_sort } keys %typeMethodsMap) { 
    print $key,"\n"; 
} 

雖然筆記 - 這是不是更有效,它只是意在說明「自定義排序」。或者 - 如果你想根據您的「鑰匙」進行排序,排序:

sub custom_sort { 
    my ($a_number, $a_text) = split ('_',$a); 
    my ($b_number, $b_text) = split ('_', $b); 

    if ($a_number == $b_number) { 
     return $a_text cmp $b_text; 
    } 
    else { 
     return $a_number <=> $b_number 
    } 
} 

這將數字排序第一,然後按字母順序排列第二。 (如果你想得到相反的結果,交換<=>cmp)。

+0

我嘗試了'爲我的$ optionsKeys(排序{$ typeMethodsMap {$ a} cmp $ typeMethodsMap {$ b}}鍵%typeMethodsMap)' 但它沒有工作 –

+0

你正在按字母順序排序。如果這不是你想要的,那麼你需要一個定義的順序或自定義排序功能。 – Sobrique

0

如果你知道你可以寫鍵又是什麼只是

for my $key (qw/ 1_CHECK_BLOCKS_FAILED 2_CHECK_OR_EXISTS 3_CHECK_UPG_EXISTS /) { 
    ... 
} 

否則,您必須跟蹤鍵的順序在一個單獨的數組,當你正在構建的哈希值,或使用類似Tie::Hash::Indexed模塊(有幾個類似的),它保持哈希數據的順序