【问题标题】:How do I find and count duplicate values in a perl hash如何在 perl 哈希中查找和计算重复值
【发布时间】:2011-09-12 16:21:35
【问题描述】:

我需要在 perl 哈希中找到重复值,然后在该计数大于 1 时输出键/值对和相关的重复计数。

(我可以留下我尝试过的代码示例,但这只会导致大量混乱和可能无法控制的笑声,我真的希望在生活中保持一些自尊。)

哈希键/值如下所示:

%hash = qw('FHDJ-124H' => 'hostname1', 'HJDHUR-87878' => 'hostname2', 'HGHDJH-874673' => 'hostname1');

我想要的输出是:

2 duplicates found for hostname1
    FHDJ-124H
    HGHDJH-874673

在 Solaris 10 上使用 perl 5.6。严格控制的生产环境,不允许升级或加载 perl 模块。 (迁移到 5.8 的更改请求大约需要 6 个月)。

非常感谢!

【问题讨论】:

  • Perl 5.6 于 11 年前发布。请与该系统的负责人讨论更新问题。
  • “键/值对和相关的重复计数”?重复计数将与多个键相关联,而不仅仅是一个;请显示示例输入和输出。以及您希望如何对输出进行排序。

标签: perl


【解决方案1】:

您需要遍历您的第一个哈希(键/值)中的哈希键,并累积您在另一个哈希中找到的每个项目的计数(值/计数)。

如果您想将键与重复值一起显示,您的第二个哈希不能这么简单,因为对于每个重复值,您将拥有一组键(它们都具有相同的值)。在这种情况下,只需将键累加到一个数组中,然后计算其元素。即,您的第二个哈希值类似于 (value/[key1,key2,key3...])

my %hash = ( key1 => "one", key2 => "two", key3 => "one", key4 => "two", key5 => "one" );
my %counts = ();
foreach my $key (sort keys %hash) {
    my $value = $hash{$key}; 
    if (not exists $counts{$value}) {
        $counts{$value} = [];
    }
    push $counts{$value}, $key;
};

然后遍历 $counts 以在 $counts{$value} 中的元素计数 > 1 时输出您需要的内容

【讨论】:

  • pre 5.14,需要push @{ $counts{$value} }, $key;,并且不需要=[],因为未定义的哈希值在使用时会自动成为哈希引用。
【解决方案2】:

这就是你要找的东西

#!/usr/bin/perl
use strict;
use warnings;
my %hash = ('FHDJ-124H' => 'hostname1', 'HJDHUR-87878' => 'hostname2', 'HGHDJH-874673' => 'hostname1');
my %reverse;

while (my ($key, $value) = each %hash) {
    push @{$reverse{$value}}, $key;
}

while (my ($key, $value) = each %reverse) {
    next unless @$value > 1;

    print scalar(@$value), " duplicates found \n @$value have the same key $key\n";     

}

【讨论】:

    【解决方案3】:

    怎么样:

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dump qw(dump);
    
    my %h = (a=>'v1', b=>'v2', c=>'v1', d=>'v3', e=>'v3');
    my %r;
    while(my($k,$v)=each%h){
        push @{$r{$v}}, {$k=>$v};
    }
    dump %r;
    

    输出:

    (
      "v1",
      [{ c => "v1" }, { a => "v1" }],
      "v2",
      [{ b => "v2" }],
      "v3",
      [{ e => "v3" }, { d => "v3" }],
    )
    

    【讨论】:

      【解决方案4】:

      好吧,在我的脑海中,你可以做这样的事情:

      my @values=sort(values(%hash));
      my @doubles=();
      my %counts=();
      
      
      
      foreach my $i (0..$#values)
      {
          foreach my $j (($i+1)..$#values)
          {
              if($values[$i] eq $values[$j])
              {
                  push @doubles,$values[$i];
                  $counts{$values[$i]}++;
      
              }
          }
      }
      
      foreach(@doubles)
      {
          print "$hash{$_}, $_, $counts{$_}\n";
      }
      

      这是一个有点幼稚的解决方案(我还没有测试过),我确信有一种更快、更流畅的方法,但这应该可行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-06
        • 2018-04-17
        • 2013-08-04
        • 2016-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多