【问题标题】:How can I sort a Perl hash on values and order the keys correspondingly (in two arrays maybe)?如何对 Perl 哈希值进行排序并相应地对键进行排序(可能在两个数组中)?
【发布时间】:2012-06-09 16:38:56
【问题描述】:

在 Perl 中,我想按数值对哈希的键进行排序:

{
  five => 5
  ten => 10
  one => 1
  four => 4
}

产生两个数组:

(1,4,5,10) and (one, four, five, ten)

然后我想规范化 values 数组,使数字是连续的:

(1,2,3,4)

我该怎么做?

【问题讨论】:

    标签: perl sorting hash perl-hash


    【解决方案1】:

    首先按关联的值对键进行排序。然后获取值(例如通过使用哈希切片)。

    my @keys = sort { $h{$a} <=> $h{$b} } keys(%h);
    my @vals = @h{@keys};
    

    或者,如果您有哈希引用。

    my @keys = sort { $h->{$a} <=> $h->{$b} } keys(%$h);
    my @vals = @{$h}{@keys};
    

    【讨论】:

    • 这很容易。有时很难想出那些漂亮的捷径。谢谢池上。
    • 您可以在sort function in Perl查看更多信息
    【解决方案2】:

    如何对散列进行排序(可选择按值而不是键)?

    要对哈希进行排序,请从键开始。在此示例中,我们将键列表提供给排序函数,然后按 ASCII 顺序比较它们(这可能会受到您的语言环境设置的影响)。输出列表具有按 ASCII 顺序排列的键。一旦我们有了密钥,我们就可以通过它们来创建一个按 ASCII 顺序列出密钥的报告。

    my @keys = sort { $a cmp $b } keys %hash;
    
    foreach my $key ( @keys ) {
        printf "%-20s %6d\n", $key, $hash{$key};
    }
    

    不过,我们可以在 sort() 块中获得更多花哨。我们可以用它们计算一个值并将该值用作比较,而不是比较键。

    例如,为了使我们的报告顺序不区分大小写,我们在比较之前使用 lc 将键小写:

    my @keys = sort { lc $a cmp lc $b } keys %hash;
    

    注意:如果计算量很大或哈希有很多元素,您可能需要查看 Schwartzian 变换来缓存计算结果。

    如果我们想按哈希值排序,我们使用哈希键来查找它。我们仍然会得到一个键列表,但这次它们是按值排序的。

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

    从那里我们可以变得更复杂。如果哈希值相同,我们可以对哈希键进行二次排序。

    my @keys = sort {
    $hash{$a} <=> $hash{$b}
    or
    "\L$a" cmp "\L$b"
    } keys %hash;
    

    【讨论】:

    • Nit: lc($a) cmp lc($b),你也写成 "\L$a" cmp "\L$b",不会总是做正确的事。你想要fc($a) cmp fc($b) ("\F$a" cmp "\F$b")。从 5.16 开始提供。
    【解决方案3】:

    请参阅标题为“How do I sort a hash (optionally by value instead of key)”的 Perl 常见问题解答条目。

    您也可以使用perldoc -q 在您的计算机上本地搜索常见问题解答,如perldoc -q sort,这是我找到您的答案的方式。

    【讨论】:

      【解决方案4】:
      my ( @nums, @words );
      do { push @nums,  shift @$_; 
           push @words, shift @$_; 
         }
          foreach sort { $a->[0] <=> $b->[0] } 
                  map  { [ $h->{ $_ }, $_ ] } keys %$h
         ;
      

      【讨论】:

      • @Moni,它工作得很好,按原样编写。如果您需要%h,那么地图中只有keys %h 和$h{ $_ }。
      • 解释一下。例如,想法是什么?
      猜你喜欢
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      相关资源
      最近更新 更多