在Perl中查找哈希散列中最大值的关键字

时间:2016-02-15 04:00:49

标签: perl hash

我有一个散列哈希,包含键,值和形式的计数((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";
    }
}

3 个答案:

答案 0 :(得分:5)

sub不需要知道关于外部哈希的任何信息,所以调用sub更有意义如下:

print key_with_highest_val($hash{a});

sub只需要迭代该哈希的所有元素,跟踪所看到的最高值以及看到它的键。

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);
}

两个版本都会在那些并列的平局中返回一个任意关键字。

答案 1 :(得分:0)

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

#!/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 strictuse warnings以捕获错误,以便找到并修复错误。这需要使用my声明变量,例如my $key = 'a';my %hash = ...

此程序打印:

For key: a, max key is b

答案 2 :(得分:0)

此代码做出以下假设:

  1. 嵌套哈希值始终为数字。
  2. 您没有重复的值。
  3. 其他任何东西都留给读者练习。

    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"