2014-11-03 73 views
0

我有一些数据,看起来像这样:匹配元素被Perl

G1 G2 G3 G4 
Pf1 NO B1 NO D1 
Pf2 NO NO C1 D1 
Pf3 A1 B1 NO D1 
Pf4 A1 NO C1 D2 
Pf5 A3 B2 C2 D3 
Pf6 NO B3 NO D3 

我的目的是在各列中,以检查是否一个元素(从“否”的情况下不同)被显示两次(例如第2列中的A1),并且只有两次(如果它显示三次或更多,我不希望它在输出中),并且如果是这样,则将其写为与第一列的元素相对应。当然,我会有更多的列元素对应于第一列的元素。所以,期望的输出如下所示:

Pf1 B1 
Pf2 C1 
Pf3 A1 B1 
Pf4 A1 C1 
Pf5 D3 
Pf6 D3 

我有一个代码,工作方向相反。它列出了第一列的元素,它们对应于在其他列中显示两次并且只显示两次的元素。此代码如下所示:

use Data::Dumper; 

my %hash; 
while (<DATA>) { 

    next if $.==1; 
    chomp; 
    my ($first,@others) = (split /\s+/); 
    for (@others){ 
     $hash{$_}.=' '.$first; 
    } 
} 

print Dumper \%hash; 

我需要推送它以适应我的新目的。任何帮助或建议是完全受欢迎的!

+0

你串连值到您的哈希值。尝试改为:'$ hash {$ _} ++;' 这将对元素进行计数,然后可以打印计数。 – Sobrique 2014-11-03 11:51:44

回答

1
my %hash; 
my @r; 
while (<DATA>) { 

    next if $.==1; 
    chomp; 
    my @t = grep $_ ne "NO", split; 
    push @r, \@t; 
    $hash{$_}++ for @t[1 .. $#t]; 
} 

for my $l (@r) { 
    my $k = shift @$l; 
    my @t = grep { $hash{$_} ==2 } @$l; 
    print "$k @t\n"; 
} 

__DATA__ 
    G1 G2 G3 G4 
Pf1 NO B1 NO D1 
Pf2 NO NO C1 D1 
Pf3 A1 B1 NO D1 
Pf4 A1 NO C1 D2 
Pf5 A3 B2 C2 D3 
Pf6 NO B3 NO D3 

输出

Pf1 B1 
Pf2 C1 
Pf3 A1 B1 
Pf4 A1 C1 
Pf5 D3 
Pf6 D3 
+0

谢谢!它完美的作品! – Gabelins 2014-11-03 12:39:36