如何删除重复值并创建一个新的perl哈希?

时间:2013-10-30 08:33:49

标签: perl hash perl-data-structures

my %hash1 = ( 
               a=>192.168.0.1,
               b=>192.168.0.1,
               c=>192.168.2.2,
               d=>192.168.2.3,
               e=>192.168.3.4,
               f=>192.168.3.4
            );

我有一个像上面给出的perl哈希。密钥是设备名称,值是IP地址。如何使用%hash1创建没有重复IP地址(如%hash2)的哈希? (删除了具有相同ips的设备)

my %hash2 = ( c=>192.168.2.2, d=>192.168.2.3 );

3 个答案:

答案 0 :(得分:6)

首先,您需要引用您的IP地址,因为192.168.0.1是perl中的V-String,表示chr(192).chr(168).chr(0).chr(1)
我的变体是:

my %t;
$t{$_}++ for values %hash1; #count values
my @keys = grep
               { $t{ $hash1{ $_ } } == 1 }
           keys %hash1; #find keys for slice
my %hash2;
@hash2{ @keys } = @hash1{ @keys }; #hash slice

答案 1 :(得分:3)

怎么样:

my %hash1 = (
   a=>'192.168.0.1',
   b=>'192.168.0.1',
   c=>'192.168.2.2',
   d=>'192.168.2.3',
   e=>'192.168.3.4',
   f=>'192.168.3.4',
);
my (%seen, %out);

while( my ($k,$v) = each %hash1) {
    if ($seen{$v}) {
        delete $out{$seen{$v}};
    } else {
        $seen{$v} = $k;
        $out{$k} = $v;
    }
}
say Dumper\%out;

<强>输出:

$VAR1 = {
          'c' => '192.168.2.2',
          'd' => '192.168.2.3'
        };

答案 2 :(得分:1)

使用CPAN模块的解决方案List::Pairwise

use strict;
use warnings;
use List::Pairwise qw( grep_pairwise );
use Data::Dumper;
my %hash1 = (
    a => '192.168.0.1',
    b => '192.168.0.1',
    c => '192.168.2.2',
    d => '192.168.2.3',
    e => '192.168.3.4',
    f => '192.168.3.4'
);  
my %count;
for my $ip ( values %hash1 ) { $count{ $ip }++ }
my %hash2 = grep_pairwise { $count{ $b } == 1 ? ( $a => $b ) : () } %hash1;
print Dumper \%hash2;

这很简单。首先,计算辅助哈希中的IP。然后,您只使用grep_pairwise中的List::Pairwise选择计数为1的IP。 grep_pairwise的语法类似于grep

my @result = grep_pairwise { ... } @list;

grep_pairwise的想法是逐个选择@list的元素,其中$a表示该对的第一个元素,$b表示第二个元素(在这种情况下的IP)。 (请记住,哈希计算为列表上下文中的($ key1,$ value1,$ key2,$ value2,...)对的列表。)