繁体   English   中英

在Perl中的哈希哈希中找到最大价值的键

[英]Find key for greatest value in hash of hashes in Perl

我有一个哈希散列,其中包含键,值和形式的计数((k1,v1),c1)。 我正在尝试编写一个子例程,该例程返回作为最大数量的参数传递的键的值。 例如,如果我有:

%hash = (
    "a" => {
        "b" => 2,
        "c" => 1,
    },
    "d" => {
        "e" => 4,
    },
);

并拨打了电话:

print &function("a");

它应该打印“ b”,因为键“ a”的计数最高为2,且其值为“ b”。 这是我到目前为止的代码:

sub function() {
    $key = $_[0];
    if(exists($hash{$key})) {
        while (my ($value, $count) = each %{$hash{$key}}) {
            #logic goes here
        }

    } else {
        return "$key does not exist";
    }
}

该子程序不需要了解有关外部哈希的任何信息,因此按以下方式调用子程序更为有意义:

print key_with_highest_val($hash{a});

子类仅需要遍历该哈希的所有元素,跟踪所看到的最高值以及所看到的密钥。

sub key_with_highest_val {
   my ($h) = @_;
   my $hi_v;
   my $hi_k;
   for my $k (keys(%$h)) {
      my $v = $h->{$k};
      if (!defined($hi_v) || $v > $hi_v) {
         $hi_v = $v;
         $hi_k = $k;
      }
   }

   return $hi_k;
}

正如Chris Charley指出的那样,List :: Util的reduce可以简单地实现此功能。 通过我上面推荐的调用约定, reduce解决方案变为:

use List::Util qw( reduce );

sub key_with_highest_val {
   my ($h) = @_;
   return reduce { $h->{$a} >= $h->{$b} ? $a : $b } keys(%$h);
}

这两个版本都会在有领带的情况下返回任意键。

使用List :: Util(它是perl核心的一部分)中的reduce函数。

#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw/reduce/;

my %hash = (
    "a" => {
        "b" => 2,
        "c" => 1,
    },
    "d" => {
        "e" => 4,
    },
);


my $key = 'a';
print  "For key: $key, max key is ", max_key($key, %hash), "\n";


sub max_key {
    my ($key, %hash) = @_;
    return "$key does not exist" unless exists $hash{$key};

    my $href = $hash{$key};
    return reduce { $href->{$a} > $href->{$b} ? $a : $b } keys %$href;
}

您应该始终在程序顶部包含“ use strict和“ use warnings ”以捕获错误,以便您可以查找并修复它们。 这需要使用my声明变量,例如my $key = 'a'; ,例如, my %hash = ...

该程序打印:

For key: a, max key is b

此代码进行以下假设:

  1. 嵌套哈希的值始终是数字。
  2. 您没有重复的值。

剩下的任何事情都留给读者练习。

use strict;
use warnings;

use Data::Dump;
use List::Util qw(max);

my %hash = (
    a => {
        b => 2,
        c => 1,
    },
    d => {
        e => 4,
    },
);

dd(max_hash_value(\%hash, $_)) for 'a' .. 'd';

sub max_hash_value {
    my ($hash_ref, $search_key) = @_;
    return unless $hash_ref->{$search_key};

    my %lookup;

    while (my ($key, $value) = each(%{$hash_ref->{$search_key}})) {
        $lookup{$value} = $key;
    }

    return $lookup{max(keys(%lookup))};
}

输出:

"b"
()
()
"e"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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