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 のような) ハッシュを作成するにはどうすればよいですか? (同じIPを持つデバイスは削除されます)

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

3 に答える 3

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_pairwise次に、 fromを使用してカウントが 1 の IP のみを選択しますList::Pairwise。の構文grep_pairwiseは次のようになりgrepます。

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

の考え方は、ペアの最初の要素と2 番目の要素 (この場合は IP)を表すことで、2 つずつgrep_pairwise要素を選択することです。(ハッシュは、リスト コンテキストで ($key1、$value1、$key2、$value2、...) ペアのリストに評価されることに注意してください)。@list$a$b

于 2013-10-30T14:47:59.830 に答える