我有这样的哈希
my %hash = (
'2011-49' => 'data1',
'2011-100' => 'data2',
'2009-22' => 'data3',
'2011-11' => 'data4',
'4323' => 'data5',
'2354' => 'data6',
'423532-2' => 'data7'
);
如何对哈希键进行排序,以便根据第一个数字进行排序,然后根据第二个数字进行排序。
my %hash = (
'2009-22' => 'data3',
'2011-11' => 'data4',
'2011-49' => 'data1',
'2011-100' => 'data2',
'2354' => 'data6',
'4323' => 'data5',
'423532-2' => 'data7'
);
我将所有按键推入阵列和放大器使用排序
Sort::Naturally qw(nsort ncmp)
但它不起作用。
答案 0 :(得分:4)
正如我在评论中所说,你不能对哈希进行排序,因为哈希不保留其键的顺序。但是,您可以对其键进行排序,并将其存储在保留顺序的内容中,如数组。为此,我们可以使用Schwartzian transform:
my @sorted_keys = map $_->[0], # 3)
sort { $a->[1] <=> $b->[1] ||
$a->[2] <=> $b->[2] } # 2)
map { [ $_, /(\d+)/g ] } keys %hash; # 1)
从最后,我们1)首先存储原始字符串,加上匿名数组ref中的第一个和第二个数字。结果是一个数组引用列表 - 一个缓存 - 我们2)传递给sort
,它们首先根据第一个数字排序,如果它们是相同的,则在第二个数字上排序。这是通过在||
代码块中使用sort
来实现的。最后我们3)恢复原始字符串并丢弃数组引用。
答案 1 :(得分:1)
你已经得到了一个很好的答案,但我想我会用Sort :: Versions来衡量。这似乎比Sort :: Naturally更好地处理这些类型的操作:
use warnings;
use strict;
use Sort::Versions;
my %hash = (
'2011-49' => 'data1',
'2011-100' => 'data2',
'2009-22' => 'data3',
'2011-11' => 'data4',
'4323' => 'data5',
'2354' => 'data6',
'423532-2' => 'data7'
);
print "$_ => $hash{$_}\n" for ( sort{ versioncmp( $a, $b ) } keys %hash );
这将产生以下输出:
2009-22 => data3
2011-11 => data4
2011-49 => data1
2011-100 => data2
2354 => data6
4323 => data5
423532-2 => data7
当然你可以将排序的值存储在数组中而不是打印它们,但我认为这样输出可能更清楚。