散列中键的字母数字或自然排序

时间:2015-10-27 11:44:48

标签: perl sorting data-structures hash perl-data-structures

我在哈希中有键如下:AB3, AB1, AB2等等。我想通过键对哈希进行排序。我怎么在perl中这样做?

相关问题是如何对键进行排序,以便字母和数字以正确的顺序显示?

3 个答案:

答案 0 :(得分:4)

您需要sort功能:

foreach my $key ( sort keys %hash ) {
    print "$key => $hash{$key}\n"; 
}

您不能轻易地将哈希维护为已排序的结构,因为它们不会以这种方式工作。有关哈希如何工作的更多信息,请参阅:perldata

编辑:perl中sort的一个细节,就是它允许你指定一个函数。此功能应该$a$b并返回-10+1,具体取决于他们是在之前还是之后。

cmp按字母顺序排列。 <=>在数字上做到这一点。最重要的是,当与||结合使用时,您可以菊花链标准,因为-11是真实的&#39;但0是假的。

例如这样的东西(借用另一篇文章中的密钥列表来说明):

#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;

my @keys = qw/ AB3 AB1 AB4
    CD5 CD107 CB8
    AC1 AC5 AC33
    BA84 CB11 CA233/;


sub lex_num {
    #split the keys into "word" and "digit" elements. 
    my @a_keys = $a =~ m/([A-Z]+)(\d+)/i;
    my @b_keys = $b =~ m/([A-Z]+)(\d+)/i;

    return ( $a_keys[0] cmp $b_keys[0] 
          || $a_keys[1] <=> $b_keys[1] );
}

print join( "\n", sort lex_num @keys );

这将在词汇上对第一位进行排序,在数字上对第二位进行排序。如果你有更多的字母和数字组合,那么这不会起作用,但你可以做到,例如一个split和一个for循环。

答案 1 :(得分:1)

如果您的密钥由非数字后跟数字定义,您可以执行以下操作:

my %h = (
  CD45 => 4,
  AB1 => 1,
  AB22 => 3,
  AB5 => 2,
);
sub mySort {
  my ($xa,$ya) = $a =~ /^(\D+)(\d+)$/;
  my ($xb,$yb) = $b =~ /^(\D+)(\d+)$/;
  return -1 if $xa lt $xb;
  return +1 if $xa gt $xb;
  return $ya <=> $yb;
}
for (sort { mySort } keys %h) {
  say "$_ => $h{$_}";
}

<强>输出:

AB1 => 1
AB5 => 2
AB22 => 3
CD45 => 4

答案 2 :(得分:0)

以下是如何通过使用CPAN模块将两种方法结合起来并缩短代码的方法 - 在这种情况下Sort::Naturally(为了说明目的,我使哈希键更复杂一些):< / p>

use Sort::Naturally ;

my @keys = qw/ AB3 AB1 AB4 
               CD5 CD107 CB8 
               AC1 AC5 AC33 
               BA84 CB11 CA233/ ;

# make a hash from the keys with "whatever" as value:
my %hash;
%hash = map { $_ => $hash{$_} = 'whatever' } @keys ; 

# Auto-magically naturally sort alphanumerically
# A module based approach to @Toto's solution:
for ( nsort keys %hash ) { print "$_ => $hash{$_} \n" };

@Sobrique已经使用基本的perl方法来响应按键排序哈希,而@Toto已经显示了如何使用您自己的子例程作为参数在指定的顺序中对这些键进行排序。阻止内置{ }功能后的sort()

<强>参考

相关问题