简体   繁体   English

Perl:对多维散列中的值进行排序

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM