2015-05-08 27 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模块(有几个类似的),它保持哈希数据的顺序