Perl:先按值排序散列,然后按键排序
与这个问题类似: 我想先按值排序,然后按键的子集排序 我的Perl:先按值排序散列,然后按键排序,perl,Perl,与这个问题类似: 我想先按值排序,然后按键的子集排序 我的%hash: cat_02 => 0 cat_04 => 1 cat_03 => 0 cat_01 => 3 输出(可以是按此顺序排列的键数组): 额外好处:关键的二次比较将识别1234_2_C01并小于1234_34_C01(不)。使用: my %hash = ( cat_02 => 0, cat_04 => 1, cat_03 => 0, cat_01 => 3
%hash
:
cat_02 => 0
cat_04 => 1
cat_03 => 0
cat_01 => 3
输出(可以是按此顺序排列的键数组):
额外好处:关键的二次比较将识别1234_2_C01并小于1234_34_C01(不)。使用:
my %hash = (
cat_02 => 0,
cat_04 => 1,
cat_03 => 0,
cat_01 => 3
);
print "$_ => $hash{$_}\n"
for sort { $hash{$a} <=> $hash{$b} or $a cmp $b } keys %hash;
my%hash=(
类别02=>0,
类别04=>1,
cat_03=>0,
cat_01=>3
);
打印“$\=>$hash{$\}\n”
对于排序{$hash{$a}$hash{$b}或$a cmp$b}键%hash;
排序对值进行数字比较,如果它们相等,则执行或
之后的部分,对键进行字符串比较。这将提供您要求的输出
对于包含数字与非数字内容混合的字符串的智能排序,请从中获取alphanum比较函数,并将
$a cmp$b
替换为alphanum($a,$b)
当您具有第二排序首选项时,只需在排序例程中添加另一个级别:
my %hash = (
cat_02 => 0,
cat_04 => 1,
cat_03 => 0,
cat_01 => 3
);
my @sorted = sort { $hash{$a} <=> $hash{$b} || $a cmp $b } keys %hash;
# primary sort method ^^ secondary sort method
for (@sorted) {
print "$_\t=> $hash{$_}\n";
}
在这种特殊情况下可能不值得这样做,但这种技术也可以用于多标准排序。像这样(): 使用Sort::Key::modules可以轻松(快速)完成此操作:
use Sort::Key::Natural qw( );
use Sort::Key::Maker intnatkeysort => qw( integer natural );
my @sorted_keys = intnatkeysort { $hash{$_}, $_ } keys(%hash);
或者,您可以利用数据的属性,只需使用自然排序:
use Sort::Key::Natural qw( natkeysort );
my @sorted_keys = natkeysort { "$hash{$_}-$_" } keys(%hash);
cmp
按字典顺序进行比较,即12 cmp 2
将生成-1
,而12 2
将生成1
。作为一种特殊情况,如果两个数字中的数字数量相同,cmp
和
将产生相同的结果。2
在数字和字符串上都小于34
,因此这是一个坏例子。但我知道你的意思。更新了我的回答没有“级别”、“主要排序方法”或“次要排序方法”,只是布尔表达式首先比较值,如果值相等,则比较键。我的意思是,目前的解释看起来像是“这是一种神奇的语法,可以按x
然后按y
排序”。当然有排序方法,从优先级的角度来看,其中一种是主要的,另一种是次要的。它不是神奇的,不,正如代码中显而易见的那样,它只是使用逻辑OR运算符。
use warnings;
use strict;
my %myhash = (
cat_2 => 0, cat_04 => 1,
cat_03 => 0, dog_02 => 3,
cat_10 => 0, cat_01 => 3,
);
my @sorted =
map { [$_->[0], $myhash{$_->[0]}] }
sort { $a->[1] <=> $b->[1] or $a->[2] <=> $b->[2] }
map { m/([0-9]+)$/ && [$_, $myhash{$_}, $1] }
keys %myhash;
print $_->[0] . ' => ' . $_->[1] . "\n" for @sorted;
map { m/_([0-9]+)_/ && [$_, $myhash{$_}, $1] }
use Sort::Key::Natural qw( );
use Sort::Key::Maker intnatkeysort => qw( integer natural );
my @sorted_keys = intnatkeysort { $hash{$_}, $_ } keys(%hash);
use Sort::Key::Natural qw( natkeysort );
my @sorted_keys = natkeysort { "$hash{$_}-$_" } keys(%hash);