如何在perl哈希中查找和计算重复值

时间:2011-06-10 17:12:54

标签: perl

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

(我可以留下我尝试过的代码样本,但这只会导致大规模的混乱和可能无法控制的笑声,而且我真的希望通过一些自尊心来实现它。)

哈希键/值如下所示:

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

我想要的输出是:

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

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

非常感谢!

4 个答案:

答案 0 :(得分:6)

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

如果要显示密钥和重复值,则第二个哈希不能那么简单,因为对于每个重复的值,您将拥有一组密钥(所有密钥都具有相同的值)。在这种情况下,只需将键累积在一个数组中,然后计算其元素。即,你的第二个哈希就像(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;
};

然后迭代$ count以输出$ count中的元素数量{$ value}> 1

答案 1 :(得分:3)

这就是你要找的东西

#!/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";     

}

答案 2 :(得分:2)

怎么样:

#!/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" }],
)

答案 3 :(得分:1)

嗯,离开我的头顶,你可以做这样的事情:

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

这是一个天真的解决方案(我还没有测试过),而且我确信它有更快更流畅的方式,但这应该可行。