如何自然地对哈希键进行排序?

时间:2008-12-20 17:47:03

标签: perl sorting hash natural-sort

我有一个Perl哈希,其键以数字开头,或者是数字。

如果我使用,

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

列表可能会出现,

0
0001
1000
203
23

而不是

0
0001
23
203
1000

4 个答案:

答案 0 :(得分:39)

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

排序操作采用可选的比较“子程序”(作为代码块,如我在此处所做的,或者子程序的名称)。我提供了一个在线比较,使用内置的数字比较运算符'&lt; =&gt;'将键视为数字。

答案 1 :(得分:18)

保罗的答案对于数字是正确的,但是如果你想更进一步,并且像人类那样对混合的单词和数字进行排序,cmp<=>都不会。例如......

  9x
  14
  foo
  fooa
  foolio
  Foolio
  foo12
  foo12a
  Foo12a
  foo12z
  foo13a

Sort::Naturally会解决此问题,提供nsortncmp例程。

答案 2 :(得分:1)

$key (sort { $a <=> $b} keys %hash) 

会做的伎俩

$key (sort { $b <=> $a} keys %hash)

降序排序

甚至

$key (sort { $a <=> $b} values %hash)
$key (sort { $b <=> $a} values %hash)

答案 3 :(得分:1)

你的第一个问题是循环体(这里没有其他答案似乎指出)。

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

我们不知道%hash的密钥是什么,我们只知道它们以循环中的词汇顺序以$key的形式传递给您。然后使用密钥访问哈希的内容,打印每个条目。

哈希的不按排序顺序排列,因为您对进行排序。

您是否希望按排序顺序输出,请考虑以下循环:

foreach my $value ( sort values(%hash) ) {
    printf( "%s\n", $value );
}

此循环 按您观察的顺序打印值:

0
0001
1000
203
23

要以数字方式对它们进行排序,请使用

foreach my $value ( sort { $a <=> $b } values(%hash) ) {
    printf( "%s\n", $value );
}

这会产生

0
0001
23
203
1000

这就是你想要的。

有关详细信息和更多示例,请参阅the Perl manual for the sort function