我有一个包含与数据库下标对应的键的哈希,但数据库可以有多维记录,因此键可以是单个下标,也可以是下标列表.
我需要找到一种方法来对这些记录进行排序,以便我可以按逻辑顺序打印它们.
例:
my $data = { '1,1,1' => 'data1','1,2' => 'data2',3' => 'stuff','2,1' => 'data3',2' => 'data4',3' => 'data blah',2,2' => 'datawk2n','3,2' => 'more',}; # Should print the keys in the properly sorted order print join "\n",sort some_function keys %$data; sub some_function { # Do some sorting magikz }
我希望它首先按最左边的下标排序.如果最左边的值相同,我想移动到下一个值并进行比较.如果那些是相同的,我想继续下一个…依此类推……直到所有可能性都用完为止.
这很可能涉及一些递归,但我无法弄清楚如何使用那些花哨的$a和$b变量进行递归.
我可以在some_function中放入什么来获得以下输出?
1,1 1,3 1,2 2,1 2,3 2,2 3,2
解决方法
以下是最快的解决方案(到目前为止!):
my @sorted_keys = map { join ',',unpack 'N*',$_ } sort map { pack 'N*',split /,/,$_ } keys(%$data);
如果你想要更简单,更快速的东西,你可以使用“自然排序”.
use Sort::Key::Natural qw( natsort ); my @sorted_keys = natsort(keys(%$data));
use Sort::Naturally qw( nsort ); my @sorted_keys = nsort(keys(%$data));
基准:
Rate SN SKN grt SN 3769/s -- -40% -88% SKN 6300/s 67% -- -79% grt 30362/s 705% 382% --
基准代码:
use strict; use warnings; use Benchmark qw( cmpthese ); use List::Util qw( shuffle ); use Sort::Key::Natural qw( ); use Sort::Naturally qw( ); my @keys = shuffle split ' ','1 1,0 1,1 1,3 1,2 2,1 2,3 2,2 3,2 10,1'; sub grt { my @sorted_keys = map { join ',$_ } sort map { pack 'N*',$_ } @keys; } sub SKN { my @sorted_keys = Sort::Key::Natural::natsort(@keys); } sub SN { my @sorted_keys = Sort::Naturally::nsort(@keys); } cmpthese(-3,{ grt => \&grt,SKN => \&SKN,SN => \&SN,});