[英]Perl: Sort values in multidimensional hash
I have a subroutine that looks likes this:我有一个看起来像这样的子程序:
...
sub UserLogins {
my %loginData;
my @logins = qx(last) or die;
foreach my $row (@logins) {
if ( $row=~ /^(\w+)\s+/ and (("$1" ne "reboot") and ("$1" ne "wtmp")) ) {
$loginData{$1}{"logins"}++;
}
}
return \%loginData
}
...
Using this subroutine in main script, I get following output:在主脚本中使用这个子程序,我得到以下输出:
...
$VAR1 = {
'user1' => {
'oldpassword' = 0,
'filesize' => '14360',
'logins' => 1
},
'user2' => {
'oldpassword' = 0,
'filesize' => '1220',
'logins' => 15
},
'user3' => {
'oldpassword' = 1,
'filesize' => '1780',
'logins' => 7
}
}
...
I wonder how I should sort my %loginData
hash so user with largest number of logins gets printed first (in this case user2, user3, user1).我想知道我应该如何对我的%loginData
散列进行排序,以便首先打印登录次数最多的用户(在本例中为 user2、user3、user1)。
I have also tried to sort values in this way:我也尝试以这种方式对值进行排序:
foreach my $test_sort (sort {$a <=> $b} values %loginData) {
say $test_sort;
}
But this function doesn't work at all.但是这个功能根本不起作用。
Another thing I tried and didn't work:我尝试过但没有用的另一件事:
print "$_\n" foreach sort {$loginData{$b}->{logins} <=> $loginData{$a}->{logins}} keys %loginData;
Update更新
This function actually works, but shows errors massages:此功能实际上有效,但显示错误消息:
print "$_\n" foreach sort {$userData{$b}->{'logins'} <=> $userData{$a}->{'logins'}} keys %userData;
Errors:错误:
Use of uninitialized values in numeric comparison (<=>)
Here's a canonical solution for accessing elements of a hash in some order based on an attribute of the value (in this case logins
):这是基于值的属性(在本例中为logins
)以某种顺序访问散列元素的规范解决方案:
for (sort { $loginData{$b}->{logins} <=> $loginData{$a}->{logins} } keys %loginData)
{
...
}
Note reversal of $b
and $a
to achieve a reverse sort (most logins first).注意$b
和$a
的反转以实现反向排序(大多数登录首先)。
You can't sort a hash.您无法对哈希进行排序。 From the Perl docs:从 Perl 文档:
Hash entries are returned in an apparently random order.散列条目以明显随机的顺序返回。
You can, compute a list of keys that index the hash in the order you like.您可以计算按您喜欢的顺序索引散列的键列表。
Something like this:像这样的东西:
use Data::Dumper;
our $hash = {
'user1' => {
'oldpassword' => 0,
'filesize' => '14360',
'logins' => 1
},
'user2' => {
'oldpassword' => 0,
'filesize' => '1220',
'logins' => 15
},
'user3' => {
'oldpassword' => 1,
'filesize' => '1780',
'logins' => 7
}
};
sub KeysByLogins {
my $hash = shift;
map { $_->[1] }
sort { $a->[0] <=> $b->[0] }
map { [ $hash->{$_}->{logins}, $_ ] } keys %$hash;
}
foreach my $key (KeysByLogins($hash)) {
print Data::Dumper->Dump([$hash->{$key}], [$key]) . "\n";
}
Then...然后...
$ perl foo.pl
$user1 = {
'filesize' => '14360',
'oldpassword' => 0,
'logins' => 1
};
$user3 = {
'logins' => 7,
'oldpassword' => 1,
'filesize' => '1780'
};
$user2 = {
'oldpassword' => 0,
'filesize' => '1220',
'logins' => 15
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.