使用 sort 对 Perl 中的哈希列表进行排序

Sorting list of hashes in Perl with sort

   use Data::Dumper;
   
   sub byage {
           $age{$a} <=> $age{$b};  # presuming numeric
       }
          
  my @class = ( { student => "student1", age => 33, },
{ student => "student2", age => 66, }, 
{ student => "student3", age => 44, }, );
  my @sortedclass = sort byage @class;
  
  print Dumper(@class);
  print Dumper(@sortedclass);

我正在尝试遵循 perldoc 排序示例。 我想至少在 perldoc 示例中基于年龄键的值对哈希列表进行排序。 不确定我做错了什么。 以上似乎没有排序。

您应该做的第一件事是将 use warnings; use strict; 放在代码的顶部,这样您就可以得到没有散列 %age.

的警告

您想要比较 $a$b 中的 age 值。

sub byage {
    $a->{age} <=> $b->{age};  # presuming numeric
}

my @class = (
    { student => "student1", age => 33, },
    { student => "student2", age => 66, },
    { student => "student3", age => 44, },
);
my @sortedclass = sort byage @class;

来自评论:

What data structure are perldocs referencing with regards to $age{b}

我想您一直在查看 Perl 常见问题解答中的这个条目 - How do I sort a hash (optionally by value instead of key)? 它包含这个示例:

my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;

排序表达式引用的数据结构是名为 %hash 的散列。

当您为自己的代码借用该示例时,您将其更改为:

sub byage {
  $age{$a} <=> $age{$b};  # presuming numeric
}

这是在寻找一个名为 %age 的散列。但是在您的代码中没有任何地方有一个名为 %hash 的散列。您有一个名为 @class.

的数组

这里有一些误解,但我认为最重要的是这个。您正在查看的常见问题解答是关于对散列进行排序的 [*](“我如何对散列进行排序...?”),但您想对列表进行排序[**](“对...的排序列表”)。列表(或数组)和散列是相当不同的数据结构,因此在尝试对数组进行排序时尝试使用用于散列的排序技术将无济于事。

sort() 函数对列表进行排序。你给它一个列表,它 return 是另一个。在 FAQ 示例中,输入列表是散列的键(使用 keys %hash 生成),输出列表是按不同顺序排序的相同键。在您的实际问题中,输入是哈希引用数组,输出是这些哈希引用的不同顺序列表。

当您编写排序表达式(或者,在您的情况下,排序子例程)时,您会在 $a$b 中获得输入列表的两个元素,并且您 return一个值,指示应如何对这两个值进行排序。在 FAQ 示例中,$a$b 将是键,您可以使用这些键查看散列($hash{$a}$hash{$b})并获取关联值。在您的问题中, $a$b 将是您输入数组中的两个散列引用。您可以查找那些($a->{age}$b->{age})范围内的“年龄”键,以获取您想要比较的值。

正如其他人指出的那样。在您的代码中添加 use strictuse warnings 总是一个好主意。解决他们向您展示的问题更好。

[*] 迂腐地说,您不能对哈希进行排序。 FAQ 代码实际做的是生成一个排序的哈希键列表。
[**] 虽然你实际上有一个数组,而不是一个列表。