如何根据键值对多级perl哈希进行排序(和打印)?
%hash = (
a => { k1 => 51, k2 => 52, k3 => 53 },
b => { k1 => 61, k2 => 62, k3 => 63 },
c => { k1 => 71, k2 => 72, k3 => 73 },
)
例如,根据k2
的值以数字方式对上述哈希进行排序?
所以应该打印:
52,62,72
我想知道如何使用
将单级哈希扩展到多级sort { $hash{$b} <=> $hash{$a} } keys %hash`
修改
如果我有另一个哈希
my %property = ( a => 7, b => 6, c => 5 )
我可以根据%hash
的数值对$hash{key}{k2} * $property{key}
进行排序吗?
使用
#!/usr/bin/perl
use strict;
use warnings;
my %hash = (
a => { k1 => 51, k2 => 52, k3 => 53 },
b => { k1 => 61, k2 => 62, k3 => 63 },
c => { k1 => 71, k2 => 72, k3 => 73 },
);
my %property = ( a => 7, b => 6, c => 5 );
foreach (sort { ($hash{$a}{'k2'}*$property{$a}) <=>
($hash{$b}{'k2'}*$property{$b}) } keys %hash)
{
printf("[%d][%d][%d]\n",
$hash{$_}{'k2'},$property{$_},$hash{$_}{'k2'}*$property{$_});
}
结果应该是
72,52,62 as products are (360(72*5),364(52*7),372(62*6))
答案 0 :(得分:3)
sort {$hash{$a}{'k2'} <=> $hash{$b}{'k2'}} keys %hash
宇宙飞船运营商在数字上将左侧与右侧进行比较。它最常见于最简单的情况,
$a <=> $b
但在这种情况下,您希望比较散列中的值,它也可以这样做。
答案 1 :(得分:3)
获取散列中所有值的列表:
values %hash;
将hashrefs列表转换为k2
条目的内容:
map $_->{k2}, @list
哦,如果undef
/不存在,请跳过它:
map $_->{k2} // (), @list
按数字排序列表:
sort { $a <=> $b } @list
连接点:
sort { $a <=> $b } map { $_->{k2} // () } values %hash;
答案 2 :(得分:1)
print join ",", sort { $a <=> $b } map { $_->{k2} } values %hash;
答案 3 :(得分:1)
这个程序就像你问的那样。它首先列出按其值排序的k2
元素的值,然后列出按其产品排序的相同元素以及%property
哈希的相应元素。
请注意,52,72,62
的预期输出是错误的。正如您所说,这些产品是a => 364, b => 372, c => 360
,因此值应按c, a, b
或72, 52, 62
use strict;
use warnings;
my %hash = (
a => { k1 => 51, k2 => 52, k3 => 53 },
b => { k1 => 61, k2 => 62, k3 => 63 },
c => { k1 => 71, k2 => 72, k3 => 73 },
);
my %property = ( a => 7, b => 6, c => 5 );
print join ',', map { $hash{$_}{k2} } sort {
my ($aa, $bb) = map { $hash{$_}{k2} } $a, $b;
$aa <=> $bb;
} keys %hash;
print "\n";
print join ',', map { $hash{$_}{k2} } sort {
my ($aa, $bb) = map { $hash{$_}{k2} * $property{$_} } $a, $b;
$aa <=> $bb;
} keys %hash;
print "\n";
<强>输出强>
52,62,72
72,52,62
答案 4 :(得分:-1)
使用ysth's回答,但这种语法可能会让事情更容易理解:
sort { $hash{$a}->{k2} <=> $hash{$b}->{k2} } keys %hash;
请记住,$a
和$b
是排序随机分配的哈希键。您不知道将哪个密钥分配给$a
或将哪个密钥分配给$b
。一次$a = "k1"
,另一次$b = "k1"
。你甚至不知道比较的次数。您所知道的是,$a
和$b
被分配给哈希中的键值,您的工作就是比较这两个键以获得您想要的结果。
这不起作用:
sort { $hash{$a}->{k2} * $property{$a} <=> $hash{$b}->{k2} * $property{$b} } keys %hash;
因为$a
和$b
将被分配值k1
,k2
或k3
。您的%property
哈希中没有这些密钥。你可能会得到一堆警告。
如果您的排序算法比简单的单行程序更复杂,您会怎么做?您可以指定一个子程序来为您进行排序。
例如,您不想在k2上进行排序,而是要对哈希值中所有值的总和进行排序。那是$hash{a}->{k1} + $hash{a}->{k2} + $hash->{k3}...
与$hash{c}->{k1} + $hash{c}->{k2}...
,我不知道任何键是什么。此子例程将找到%{ hash{$a} }
中的所有键并添加它们并将它们与%{ hash{$b} }
中的所有键进行比较:
sort sort_function keys %hash;
sub sort_function {
# Sum of all the values in the hash %{ $hash{$a} }
my $sum_a = 0;
for my $hash_key ( keys %$hash{$a} ) {
$sum_a += $hash{$a}->{$hash_key};
}
# Sum of all the values in the hash %{ $hash{$b} }
my $sum_b = 0;
for my $hash_key ( keys %$hash{$b} ) {
$sum_b += $hash{$b}->{$hash_key};
}
return $sum_a <=> $sum_b;
}