【问题标题】:How to compare multiple values with each other for a key with in an hash in perl?如何在perl的哈希中将多个值相互比较?
【发布时间】:2019-01-04 07:45:36
【问题描述】:

我有一个看起来像这样的哈希

my %hash = (key1 => [value1],
           key2 => [value1,value2],
           key3 => [value3,value3,value3],
           key4 => [value2,value2,value2]
           );

现在我想将这些值相互比较并挑选出奇数键。即所有值都不相同的键,在本例中为key2 取出每个键并迭代数组似乎是一种折磨。有没有简单的方法可以做到这一点? 我想使用这个奇怪的键并打印出值/在哈希中给它一个计数 例如。

   my %hash2;
   $hash2{key2}{value1} =2;
   $hash2{key2}{value2} =2;

我该如何做到这一点?

【问题讨论】:

  • key 不也是不匹配吗?你如何确定它们是相同的?我想我会为此使用metacpan.org/pod/Test::Deep::NoTest。也许与bag 比较。这似乎是我能想到的最懒惰的方式,除了请互联网上的陌生人为我做这件事。 ;)
  • @simbabque,本例中的值是字符串,所以我认为我们可以使用eq 运算符更喜欢代码而不是模块
  • 模块就是代码。老实说,这看起来很像一个家庭作业问题。如果是这种情况,请研究该模块的代码。它将帮助您了解您需要做什么。请解释一下你有更好的目标。您的第二个代码块不是很清楚。我不明白你为什么分配这些数字。那么key1呢?
  • 我认为“取出每个键并遍历数组”是唯一的方法。也许grep 可能有用,这是一个也许我没有对此进行任何尝试

标签: perl hash hashmap


【解决方案1】:

为了找到您感兴趣的键,您可以过滤具有多个唯一元素的值。对于uniq,您可以使用List::MoreUtils,或者如果您想避免使用模块,您可以自己定义函数(explanation here

sub uniq {
  my %seen;
  return grep { !$seen{$_}++ } @_;
}

然后您可以像这样过滤键:

# get an array of pairs of "uniq count" and "key"
my @key_counts = map {[uniq(@{$hash{$_}})+0, $_]} keys %hash;
# filter this array for those with "uniq count" greater than 1 and only keep key
my @keys_of_interest = map {$_->[1]} grep {$_->[0] > 1} @key_counts;
# if you know that there is only a single key of interest
my $key = $keys_of_interest[0];

您可以使用此$key 和对应的value 来获取您的%hash2

my %hash2;
$hash2{$key}{$_} = 2 foreach(@{$hash{$key}});

【讨论】:

  • 您好!您是否考虑过参加德国 Perl 研讨会或其他 Perl 会议?
  • 非常感谢您抽出宝贵时间来帮助我。效果很好。
【解决方案2】:
use warnings;
use strict;

my @odd_keys;

my %hash = (key1 => [1],
            key2 => [1,2],
            key3 => [3,3,3],
            key4 => [2,2,2]
           );

foreach my $key (keys(%hash))
{
  #builds an array with every cell equal to first cell 
  my @temp_array = grep {$_ eq $hash{$key}->[0]} @{$hash{$key}};
  #if the size of this array is different than the size of array associated to key, that means that all values are not equal
  if (@temp_array != @{$hash{$key}})
  {
    print "$key\n"; 
    push(@odd_keys, $key);
  }
}

打印奇数键并创建一个@odd_keys 数组

【讨论】:

  • 由于某种原因,它只在数值为数字时有效,当它为字符串时无效(字母和数字的组合)
  • true,这是因为 == 比较数字,要比较字符串你必须使用 eq
  • @sarahJ 编辑:事实上,用eq 替换== 也适用于数值,修复了代码;)
  • 感谢您抽出宝贵时间帮助我
猜你喜欢
  • 2014-02-05
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多