【问题标题】:How to extract data from an array that contains only one occurrence of an element and only one occurrence of a corresponding element in Perl如何从仅包含一次出现的元素和仅出现一次的Perl中对应元素的数组中提取数据
【发布时间】:2020-10-03 14:03:28
【问题描述】:

我试图弄清楚如何从一个只包含一次训练员和一次骑师的文件中提取记录。

从本质上讲,该记录意味着骑师当天只有一次骑行,并且是针对当天只有一名跑步者的练马师 X。

以下是一些“样本数据”:

ALLAN DENHAM,MUSWELLBROOK,RACE 5,MOPITTS (10),JEFF PENZA,B,5
ALLAN KEHOE,MUSWELLBROOK,RACE 3,FOXY FIVE (5),KOBY JENNINGS,C,3
ALLAN KEHOE,MUSWELLBROOK,RACE 4,BANGALLEY LAD (3),KOBY JENNINGS,BBB,4
ANDREW ROBINSON,MUSWELLBROOK,RACE 6,TROPHIES GALORE (4),DARRYL MCLELLAN,AAA,6
BEN HILL,MUSWELLBROOK,RACE 4,WHALER BILL (10),GRANT BUCKLEY,BB,4
BEN HILL,MUSWELLBROOK,RACE 5,MR BILL (5),GRANT BUCKLEY,BB,4
BJORN BAKER,MUSWELLBROOK,RACE 3,MISS JAY FOX (9),ALYSHA COLLETT,BB,3
BRETT CAVANOUGH,MUSWELLBROOK,RACE 3,OFFICE AFFAIR (10),RACHAEL MURRAY,B,3
BRETT THOMPSON,MUSWELLBROOK,RACE 7,COSTAS (2),RONALD SIMPSON,BB,7
CODY MORGAN,MUSWELLBROOK,RACE 6,BAJAN GOLD (5),JEFF PENZA,BB,6
CODY MORGAN,MUSWELLBROOK,RACE 7,RAPID EAGLE (9),DARRYL MCLELLAN,B,7

在示例数据中,符合我条件的第一条记录如下:

BJORN BAKER,MUSWELLBROOK,RACE 3,MISS JAY FOX (9),ALYSHA COLLETT,BB,3

注意:BJORN BAKER 只出现一次,ALYSHA COLLETT 只出现一次。

在示例数据中,练马师 ALLAN DENHAM 当天只有一名跑步者,但骑师 JEFF PENZA 有 2 次骑行,一次给练马师 ALLAN DENHAM,一次给练马师 CODY MORGAN,所以这不符合我的标准。

符合我标准的另一条记录是以下记录:

BRETT CAVANOUGH,MUSWELLBROOK,RACE 3,OFFICE AFFAIR (10),RACHAEL MURRAY,B,3

注意:BRETT CAVANOUGH 只出现一次,而 RACHAEL MURRAY 只出现一次。

BRETT THOMPSON,MUSWELLBROOK,RACE 7,COSTAS (2),RONALD SIMPSON,BB,7

注意:BRETT THOMPSON 只出现一次,RONALD SIMPSON 只出现一次。

等等……

我已将“示例数据”(页面顶部)加载到 Perl 中的数组中,并研究了如何使用哈希等来提取唯一记录,但我不知道如何提取所需的记录基于两个元素组合的唯一性(即一名教练+一名对应骑师)

use Data::Dumper;

$infile = "TRAINER-JOCKEY-SAMPLE.txt";

open my $infile, "<:encoding(utf8)", $infile or die "$infile: $!";
my @recs = <$infile>;
close $infile;

my %uniques;
for my $rec (@recs) 
{
    my ($trainer, $racecourse, $racenum, $hnameandnum, $jockey, $TDRating, $rnum) = split(",", $rec);
    ++$uniques{$trainer}{$jockey};
}

print Dumper(\%uniques);

for my $trainer (sort keys %uniques) 
{
    my $answer = join ',', sort keys %{ $uniques{$trainer} };
    print "$trainer has unique values $answer\n";
}

注意:成功后我需要打印整条记录(见下文):

BJORN BAKER,MUSWELLBROOK,RACE 3,MISS JAY FOX (9),ALYSHA COLLETT,BB,3

非常感谢您的帮助。

【问题讨论】:

    标签: arrays perl hash unique combinations


    【解决方案1】:

    训练师和骑师都必须在列表中出现一次(除非输入有重复的行)。

    所以,让我们只计算培训师的出现次数。为了能够将他们与骑师相匹配,我们会将骑师存储到训练师的哈希值中。

    一旦我们建立了这两个结构,只需选择只有一名相关教练的骑师,并检查教练是否只出现过一次,并且必须与他们关联的骑师。

    #!/usr/bin/perl
    use warnings;
    use strict;
    use feature qw{ say };
    
    my (%jockeys, %trainers);
    while (<>) {
        my ($jockey, $trainer) = (split /,/)[0, 4];
        ++$trainers{$trainer};
        undef $jockeys{$jockey}{$trainer};
    }
    
    for my $jockey (keys %jockeys) {
        next if 1 < keys %{ $jockeys{$jockey} };
    
        my $trainer = (keys %{ $jockeys{$jockey} })[0];
        say "$jockey,$trainer" if 1 == $trainers{$trainer};
    }
    

    更新:要打印整行,我们也需要将它们存储在某个地方。我们可以通过记住另一个哈希中的整行来稍微修改程序;我们可以使用教练或骑师作为关键。

    #!/usr/bin/perl
    use warnings;
    use strict;
    
    my (%jockeys, %trainers, %full);
    while (<>) {
        my ($jockey, $trainer) = (split /,/)[0, 4];
        ++$trainers{$trainer};
        undef $jockeys{$jockey}{$trainer};
        $full{$jockey} = $_;
    }
    
    for my $jockey (keys %jockeys) {
        next if 1 < keys %{ $jockeys{$jockey} };
    
        my $trainer = (keys %{ $jockeys{$jockey} })[0];
    
        print $full{$jockey} if 1 == $trainers{$trainer};
    }
    

    【讨论】:

    • 这很好用。非常感谢,@choroba 还有一个问题,我在哪里/如何打印每个匹配的骑师和相关培训师的其余记录(即 $racecourse、$racenum、$hnameandnum、$TDRating)?
    • 太棒了。我有一种感觉,这是必需的,但我只是不知道该怎么做。再次感谢您的所有帮助,@choroba 非常感谢。
    猜你喜欢
    • 2014-04-26
    • 2013-06-24
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 1970-01-01
    相关资源
    最近更新 更多