【问题标题】:Find values of nested hash matching a specific key查找匹配特定键的嵌套哈希值
【发布时间】:2017-08-02 00:43:28
【问题描述】:

我在 perl 中创建了一个哈希哈希,这是哈希最终看起来的示例:

my %grades;
$grades{"Foo Bar"}{Mathematics}   = 97;
$grades{"Foo Bar"}{Literature}    = 67;
$grades{"Peti Bar"}{Literature}   = 88;
$grades{"Peti Bar"}{Mathematics}  = 82;
$grades{"Peti Bar"}{Art}          = 99;

并打印整个哈希,我正在使用:

foreach my $name (sort keys %grades) {
    foreach my $subject (keys %{ $grades{$name} }) {
        print "$name, $subject: $grades{$name}{$subject}\n";
    }
}

我只需要打印引用“Peti Bar”的内部哈希并找到最高值,所以理论上我应该通过 Peti Bar,literature 进行解析; Peti Bar,数学;和 Peti Bar, Art 并最终返回 Art,因为它具有最高的价值。 有没有办法做到这一点,还是我需要解析整个 2d 哈希?

【问题讨论】:

    标签: perl hash hashmap


    【解决方案1】:

    如果您知道您感兴趣的密钥,则无需解析第一级。只需省略第一个循环并直接访问它。要获得最高值,您必须查看每个主题一次。

    跟踪最大值和与之相关的键,然后打印。

    my $max_value = 0;
    my $max_key;
    foreach my $subject (keys %{ $grades{'Peti Bar'} }) {
        if ($grades{'Peti Bar'}{$subject} > $max_value){
            $max_value = $grades{'Peti Bar'}{$subject};
            $max_key = $subject;
        }
    }
    print $max_key;
    

    这将输出

    Art
    

    sort 的替代实现如下所示:

    print +(
        sort { $grades{'Peti Bar'}{$b} <=> $grades{'Peti Bar'}{$a} }
            keys %{ $grades{'Peti Bar'} }
    )[0];
    

    +( ... ) 中的 + 告诉 Perl,括号 () 不是用于对 print 的函数调用,而是用于构造一个列表。 sort 对键进行降序排序,因为它首先具有 $b。它返回一个列表,我们取第一个值(索引0)。

    请注意,这比第一个实现更昂贵,而且不一定更简洁。除非您正在构建单线或您的 ; 坏了,否则我不会推荐第二种解决方案。

    【讨论】:

      【解决方案2】:

      使用List::UtilsBy 模块很简单

      通过提取对我们感兴趣的内部哈希的引用,代码变得更加清晰。调用max_by 以返回具有最大值的哈希的键

      use strict;
      use warnings 'all';
      use feature 'say';
      
      use List::UtilsBy 'max_by';
      
      my %grades = (
          'Foo Bar'  => { Literature => 67, Mathematics => 97 },
          'Peti Bar' => { Literature => 88, Mathematics => 82, Art => 99 },
      );
      
      my $pb_grades = $grades{'Peti Bar'};
      
      say max_by { $pb_grades->{$_} } keys %$pb_grades;
      

      输出

      Art
      

      【讨论】:

      • 我确定存在类似的东西,但不知道名称。 :)
      【解决方案3】:

      作为 Perl 初学者,我会使用 List::Util 核心模块:

      use 5.014;
      use List::Util 'reduce';
      my $k='Peti Bar';
      say reduce { $grades{$k}{$a} > $grades{$k}{$b} ? $a : $b } keys %{$grades{$k}};
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-30
        • 2021-11-28
        • 1970-01-01
        相关资源
        最近更新 更多