无法在我的perl脚本中对哈希进行排序

时间:2016-04-15 18:17:04

标签: perl sorting hash

sub hashOfUsers
{
    %userAndPass = (); #hash to store the user and passwd, SORT hashes to view     the users of this program
    $userAndPass = {
        USER1 => 'David',
        PASS1 => 'P@ssw0rd',
        USER2 => 'Paul',
        PASS2 => 'P@ssw0rd',
        USER3 => 'Diana',
        PASS3 => 'P@ssw0rd'
      }; #users and pass hashes
}

sub option4
{
    &hashOfUsers();
    foreach $hi(sort {$userAndPass{$a} cmp $userAndPass{$b}} keys %userAndPass)
    {
        print "The users of this programs are: $userAndPass{$hi} $hi  \n";
    }
}

我似乎无法对我的哈希进行排序,我在子例程中使用这个foreach在子例程中尝试对哈希进行排序。我正在尝试对它进行排序,以便它只打印用户,从USER1到USER3而不是PASS1到PASS3。请帮忙。

2 个答案:

答案 0 :(得分:2)

在哈希中使用数字键是个坏主意。如果订购很重要 - 那么它就是一个阵列的工作。如果订购并不重要,并且您已经命名了键值对,那么它就是哈希的工作。

哦,在您的情况下,%userAndPass$userAndPass无关。 use strict; use warnings;会告诉你这个。

我建议您的数据结构会更好:

my @users = (
   {  USER => 'David',
      PASS => 'P@ssw0rd',
   },
   {  USER => 'Paul',
      PASS => 'P@ssw0rd',
   },
   {  USER => 'Diana',
      PASS => 'P@ssw0rd'
   }
);

因为那样你可以:

use Data::Dumper;
print Dumper \@users;
print $users[1]->{USER},"\n";

print $_->{USER},"\n" for @users;  

答案 1 :(得分:1)

问题:

首先,将结构初始化为散列的标量引用,但是sort语句想要使用(当前未初始化的)散列。

use strict;
use warnings;

做吧!

如果你要:

%userAndPass = (
    USER1 => 'David',
    PASS1 => 'P@ssw0rd',
    USER2 => 'Paul',
    PASS2 => 'P@ssw0rd',
    USER3 => 'Diana',
    PASS3 => 'P@ssw0rd'
  );

sort语句中的foreach函数会生成以下列表的某些变体:

  • USER1
  • USER3
  • 随机顺序的PASS*个密钥(它们的关联值都相同)
  • USER2

这种结构问题的核心在于你的用户名和用户名。密码只是偶然的关键选择相互关联。 (如果您要对变量名称或键进行编号,则应停止并重新考虑。这是代码味道。)

重新设计:

可能不那么疯狂的结构包括:

“记录”数组:

@UserAndPass = (
  {USER => 'David', PASS => 'P@ssw0rd'},
  {USER => 'Paul',  PASS => 'P@ssw0rd'},
  {USER => 'Diana', PASS => 'P@ssw0rd'},
);

这可以直接排序。 (如Sobrique的同步解决方案。)

用户名:

键入的密码哈希值
%UserAndPass = (
  'David' => 'P@ssw0rd',
  'Paul'  => 'P@ssw0rd',
  'Diana' => 'P@ssw0rd',
)

这可以用来创建一个排序的键列表,更像你原来的代码似乎想要做的。这种结构的优点是1级浅,但是“缺点”是你不能为同一个用户拥有多个密码(如果你是那种东西= /)。

如果结构的当前代码气味版本对您很重要,请考虑将keys %UserAndPass替换为grep {/^USER/} keys %UserAndPass