我有一个看起来像这样的子程序:
...
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
}
...
在主脚本中使用此子例程,我得到以下输出:
...
$VAR1 = {
'user1' => {
'oldpassword' = 0,
'filesize' => '14360',
'logins' => 1
},
'user2' => {
'oldpassword' = 0,
'filesize' => '1220',
'logins' => 15
},
'user3' => {
'oldpassword' = 1,
'filesize' => '1780',
'logins' => 7
}
}
...
我想知道如何对%loginData
哈希进行排序,以便首先打印具有最大登录次数的用户(在本例中为user2,user3,user1)。
我也尝试过以这种方式对值进行排序:
foreach my $test_sort (sort {$a <=> $b} values %loginData) {
say $test_sort;
}
但是这个功能根本不起作用。
我尝试过的另一件事并没有奏效:
print "$_\n" foreach sort {$loginData{$b}->{logins} <=> $loginData{$a}->{logins}} keys %loginData;
更新
此功能确实有效,但显示错误按摩:
print "$_\n" foreach sort {$userData{$b}->{'logins'} <=> $userData{$a}->{'logins'}} keys %userData;
错误:
Use of uninitialized values in numeric comparison (<=>)
答案 0 :(得分:2)
这是一个规范的解决方案,用于根据值的属性(在本例中为logins
)以某种顺序访问哈希元素:
for (sort { $loginData{$b}->{logins} <=> $loginData{$a}->{logins} } keys %loginData)
{
...
}
请注意$b
和$a
的反转以实现反向排序(大多数登录首先)。
答案 1 :(得分:0)
您无法对哈希进行排序。来自Perl文档:
哈希条目以明显随机的顺序返回。
您可以计算按照您喜欢的顺序索引哈希的键列表。
这样的事情:
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";
}
则...
$ perl foo.pl
$user3 = {
'oldpassword' => 1,
'logins' => 7,
'filesize' => '1780'
};
$user2 = {
'filesize' => '1220',
'logins' => 15,
'oldpassword' => 0
};
$user1 = {
'filesize' => '14360',
'logins' => 1,
'oldpassword' => 0
};