根据键

时间:2015-05-08 09:41:54

标签: perl hash

我在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}},"1_xyz""2_xyz""3_xyz"

如果有人可以帮助我,请告诉我吗?

2 个答案:

答案 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

答案 1 :(得分:0)

If you know what the keys are then you can write just

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

Otherwise you must either keep track of the order of the keys in a separate array when you are building the hash, or use something like the Tie::Hash::Indexed module (there are several similar ones) which maintains the order of hash data