类似于这个问题:使用 Perl 字符串的子集进行排序
我想先按值排序,然后再按键的子集排序。
我的%hash
:
cat_02 => 0
cat_04 => 1
cat_03 => 0
cat_01 => 3
输出结果(可能是按此顺序排列的键的数组):
cat_02 => 0
cat_03 => 0
cat_04 => 1
cat_01 => 3
奖励:关键次要比较将识别1234_2_C01并且比1234_34_C01小(cmp不会这样做)。
类似于这个问题:使用 Perl 字符串的子集进行排序
我想先按值排序,然后再按键的子集排序。
我的%hash
:
cat_02 => 0
cat_04 => 1
cat_03 => 0
cat_01 => 3
cat_02 => 0
cat_03 => 0
cat_04 => 1
cat_01 => 3
奖励:关键次要比较将识别1234_2_C01并且比1234_34_C01小(cmp不会这样做)。
使用:
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;
or
后面的部分,该部分对键进行字符串比较。 这会输出您要求的结果。alphanum($a,$b)
替换$a cmp $b
。cmp
按字典顺序进行比较,即12 cmp 2
将产生-1
,而12 <=> 2
将产生1
。作为一个特殊情况,如果两个数字的位数相同,则cmp
和<=>
将产生相同的结果。 - n0rdmy %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";
}
输出:
cat_02 => 0
cat_03 => 0
cat_04 => 1
cat_01 => 3
x
排序然后按y
排序的魔法语法”。 - n0rduse 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);
在这种特定情况下可能并不值得,但是施瓦兹变换技术也可以用于多标准排序。像这样(codepad):
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;
@sorted
实际上成为了数组的数组(该数组的每个元素都是键值对);2)在此示例中,排序是基于键的数字后缀(使用数字而非字符串比较),但如果需要可以调整任何方向的排序。map
子句更改为: map { m/_([0-9]+)_/ && [$_, $myhash{$_}, $1] }
2_
在数值和字符串上都比34
小,所以这不是一个好的例子。但我知道你的意思。我更新了我的答案。 - user2404501