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

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

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

3 回答 3

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
于 2013-10-30T09:03:06.077 回答
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'
        };
于 2013-10-30T08:44:10.517 回答
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_pairwisefromList::Pairwise。的语法grep_pairwise如下grep

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

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

于 2013-10-30T14:47:59.830 回答