在Perl中如何按键对哈希进行排序?
我想对一个散列进行排序,它实际上有一个散列作为值。例如:在Perl中如何按键对哈希进行排序?,perl,sorting,hash,Perl,Sorting,Hash,我想对一个散列进行排序,它实际上有一个散列作为值。例如: my %hash1=( field1=>"", field2=>"", count=>0, ); my %hash2; $hash2{"asd"}={%hash1}; 我在%hash2中插入了很多散列,它们的计数值不同%hash2 如何根据hash1的计数值对%hash1进行排序 有没有一种方法不需要手动实现快速排序,例如使用Perl的排序函数?my@hash1s=sort{$a->{count}$b
my %hash1=(
field1=>"",
field2=>"",
count=>0,
);
my %hash2;
$hash2{"asd"}={%hash1};
我在%hash2
中插入了很多散列,它们的计数值不同%hash2
如何根据hash1
的计数值对%hash1
进行排序
有没有一种方法不需要手动实现快速排序,例如使用Perl的排序函数?my@hash1s=sort{$a->{count}$b->{count}}值%hash2;
my @hash1s = sort {$a->{count} <=> $b->{count}} values %hash2;
如果您想从hash2中的值中获得按计数排序的哈希列表(如hash1),这可能会有帮助:
@sorted_hash1_list = sort sort_hash_by_count_key($a, $b) (values (%hash2);
# This method can have any logic you want
sub sort_hash_by_count_key {
my ($a, $b) = @_;
return $a->{count} <=> $b->{count};
}
@sorted\u hash1\u list=按\u count\u键($a,$b)(值(%hash2))排序\u hash\u;
#此方法可以具有您想要的任何逻辑
子排序\u哈希\u按\u计数\u键{
我的($a$b)=;
返回$a->{count}$b->{count};
}
有关排序在Perl中如何工作的上下文,请参阅
这里有一个例子,试着让人可读,而不是说英语
#!/usr/bin/perl
# Sort Hash of Hashes by sub-hash's element count.
use warnings;
use strict;
my $hash= {
A=>{C=>"D",0=>"r",T=>"q"}
,B=>{}
,C=>{E=>"F",G=>"H"}
};
sub compareHashKeys {0+(keys %{$hash->{$a}}) <=> 0+(keys %{$hash->{$b}}) }
my @SortedKeys = sort compareHashKeys keys %{$hash};
print join ("," , @SortedKeys) ."\n";
!/usr/bin/perl
#按子哈希的元素计数对哈希进行排序。
使用警告;
严格使用;
我的$hash={
A=>{C=>“D”,0=>“r”,T=>“q”}
,B=>{}
,C=>{E=>“F”,G=>“H”}
};
子比较hashkeys{0+(keys%{$hash->{$a}})0+(keys%{$hash->{$b})}
my@SortedKeys=sort compareHashKeys%{$hash};
打印联接(“,”,@SortedKeys)。“\n”;
从中,对的答案包含了编写代码所需的大部分信息
您可能还想看看学习Perl中有关排序的章节
Chris有一个非常好的答案,尽管我讨厌这样使用值。做同样事情的一个更熟悉的方法是遍历顶级散列的键,但按第二级键排序:
my @sorted_hashes =
sort { $hash2->{$a}{count} <=> $hash2->{$b}{count} }
keys %hash2;
不过,我们可以在sort()块中获得更多的想象力。我们不需要比较键,而是可以用它们计算一个值,并将该值用作比较
例如,为了使报表顺序不区分大小写,我们使用双引号字符串中的\L序列将所有内容都设置为小写。然后,sort()块比较小写值以确定键的放置顺序
my @keys = sort { "\L$a" cmp "\L$b" } keys %hash;
注意:如果计算很昂贵或者散列包含很多元素,您可能需要查看Schwartzian变换来缓存计算结果
如果我们想改为按散列值排序,我们使用散列键来查找它。我们仍然会得到一个键列表,但这次它们是按其值排序的
my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;
my@keys=sort{$hash{$a}$hash{$b}}keys%hash;
如果散列值相同,我们可以对散列键进行二次排序
my @keys = sort {
$hash{$a} <=> $hash{$b}
or
"\L$a" cmp "\L$b"
} keys %hash;
my@keys=sort{
$hash{$a}$hash{$b}
或
\L$a“cmp”\L$b
}密钥%hash;
按数字使用和字符串使用进行排序
# sort by the numeric count field on inner hash
#
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) {
print $key,$hash2{$key}->{'count'},"\n";
}
# sort by the string field1 (or field2) on the inner hash
#
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) {
print $key,$hash2{$key}->{'field1'},"\n";
}
#按内部哈希上的数字计数字段排序
#
foreach my$键(排序{$hash2{$a}->{'count'}$hash2{$b}->{'count'}}}键%hash2){
打印$key,$hash2{$key}->{'count'},“\n”;
}
#按内部哈希上的字符串field1(或field2)排序
#
foreach my$key(排序{$hash2{$a}->{'field1'}cmp$hash2{$b}->{'field1'}}}键%hash2){
打印$key、$hash2{$key}->{'field1'},“\n”;
}
要颠倒顺序,只需交换$a和$b即可:
# sort by the numeric count field on inner hash
#
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) {
print $key,$hash2{$key}->{'count'},"\n";
}
# sort by the string field1 (or field2) on the inner hash
#
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) {
print $key,$hash2{$key}->{'field1'},"\n";
}
#按内部哈希上的数字计数字段排序
#
foreach my$键(排序{$hash2{$a}->{'count'}$hash2{$b}->{'count'}}}键%hash2){
打印$key,$hash2{$key}->{'count'},“\n”;
}
#按内部哈希上的字符串field1(或field2)排序
#
foreach my$key(排序{$hash2{$a}->{'field1'}cmp$hash2{$b}->{'field1'}}}键%hash2){
打印$key、$hash2{$key}->{'field1'},“\n”;
}
你的意思是想从hash2中的值中获得按计数排序的哈希列表(如hash1)?是的,Jagmal这意味着我想根据$hash2{“asd”}{count}进行排序。你的意思是说“sort\&sort\u hash\u by\u count\u key,values%hash2”而不是你当前拥有的值吗?我尝试了这种方法,但得到了以下警告:[警告]:在数字比较()中使用未初始化值。在代码段中,对于我的答案和我对你的答案的注释,在测试时为我工作(即使使用-w和“Use strict”)。你会收到该警告,因为你的一个或多个散列没有“count”键的值。如果你想将它们计为0,你可以执行sort{($a->{count}| | 0)($b->{count}| | 0}值%hash2;否我所有的计数值都有0作为默认值。但在我的生产代码中,键的名称不是count,而是total,而是排序算法按升序排序,我需要按降序排序。@holydiver:使用$b->{count a->{count进行降序排序(即交换a和b)。0+应该强制将值转换为数字,但是,它已经这样做了,因此0+实际上是多余的。:-PWell,从cmp生成的值或已经是数字的值,是-1、0或1。数据是什么并不重要。sort()需要-1、0或1来决定如何排序。正如Chris指出的,我将0+放在那里,以将keys数组强制转换为标量(从而保持数组的长度)。显然已经这样做了。我将继续这样做,因为在重新读取代码时,我会很明显地看到预期会发生什么。YMMD
# sort by the numeric count field on inner hash
#
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) {
print $key,$hash2{$key}->{'count'},"\n";
}
# sort by the string field1 (or field2) on the inner hash
#
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) {
print $key,$hash2{$key}->{'field1'},"\n";
}