perl跳过数组中的值

时间:2019-05-21 18:13:30

标签: perl

我有一个文本文件

II : RE: released for CR CHG1001739981 : Urgent for NYK SOD - INC1012082403
CN: RE: futures  - INC1012083269
AP: RE: REQ25116618-1: setups - INC1012084465
DS: RE: access - INC1012084976
LC: RE: options Grid - INC1012085569
II: RE: issues - INC1012085587
VK: RE: FW data - INC1012085827
NW: RE: spread  - INC1012086027
AP: RE: Exception Notification - INC1012087025
VK: RE: Yellow - INC1012087066
DS: RE: Exception Notification - INC1012087664</none>
LC: RE:  - INC1012087915
CN: RE: [Restricted - Internal] - INC1012088249
WJ: FW: issue - INC1012088961
can i get an inc for this pls
you sure can
CN: User Feedback - INC1012089212
thank you
np
CN: benchmark - INC1012089691
DS: NAN Value - INC1012089989
TM:downstream - INC1012090321
re-assigning to myself
II: setup - INC1012090460
LC: size - INC1012090813
BJ - help with filter
**handover mail**
:)

这是在该组中分配票证的方式。大多数团队在早上7点到达,BJ在10:30到达, 移交给美国的时间是11:00。由于BJ刚进入,他经常被转移到队列的最前面-他得到了第一张票。 我要做的是弄清楚其余班次的顺序。通常,我会用手工将英格兰在复活节时间上午11点下班的人转移出去。
然后,我取消了即将来临的美国人民的考验,并将其水平排列。

II AP DS LC II AP DS LC WJ DS AP II LC BJ

然后反转它们

 BJ LC II AP DS WJ LC DS AP II LC DS AP II

然后跳过BJ,在本例中为LC,跳至列表中的[1],然后返回到再次获得“ LC”的位置。

 BJ LC II AP DS WJ 

再次欣赏它-瞧,您将当天的任务分配给了。

WJ DS AP II LC BJ

现在我无法在“ LC”的第一个实例处停止收费

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper ;
my @team = ("AP","II","DS","WJ", "JK","LC","BJ") ;
my @orderdTeam ;
my $begin ;
my $rev ;
my @rev_orderdTeam  ;
my $filename = shift @ARGV ;
open(my $fh, '<', $filename) or die "Could not open file $filename $!";
while (my $line = <$fh> ) {
    foreach my $op (@team) {
        if ($line =~ /$op/) {
        push (@orderdTeam, $op) ;
        }
    }

    }


print "order ---------> " . "@orderdTeam" . "\n"       ;
@rev_orderdTeam = reverse(@orderdTeam)              ;
print "reverse order -> " . "@rev_orderdTeam" . "\n"   ;

print "The last person to get assigned is $begin\n" ;

foreach $rev (@rev_orderdTeam[1 .. $#rev_orderdTeam]) {
    if ("$rev_orderdTeam[0]" eq "BJ") {
           $begin = $rev_orderdTeam[1]
    }
    else {
          $begin = "$rev_orderdTeam[0]" ;
    }

    if ($rev ne "$begin") {
            print "$rev " ;

    }
}

2 个答案:

答案 0 :(得分:2)

开始之前,请注意,您提供的数据的初始顺序为

II AP DS LC II AP DS LC WJ DS II LC BJ

而不是

II AP DS LC II AP DS LC WJ DS AP II LC BJ

如您所言。


为实现您的目标,我建议使用与您描述的方法不同的方法。在我看来,您的实际意图是删除重复项,这就是以下解决方案的作用:

#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say );

use List::Util qw( uniq );

my @team = qw( AP II DS WJ JK LC BJ );
my %team = map { $_ => 1 } @team;

my @order;
while (<>) {
   my ($op) = /^(\w+)/
      or next;

   $team{$op}
      or next;

   push @order, $op;
}

my @filtered = reverse uniq reverse @order;
say "@filtered";

输出:

AP WJ DS II LC BJ

要执行您实际需要的操作,只需遍历数组,直到找到倒数第二个元素的副本,然后提取随后的所有元素。

为此,请替换

my @filtered = reverse uniq reverse @order;

使用

my $i = @order - 3;
--$i while $i >= 0 && $order[$i] ne $order[-2];
my @filtered = @order[$i+1 .. $#order];

输出:

WJ DS II LC BJ

如您所见,输出是不同的。未列出AP,因为它们没有出现在LC的两个实例之间。因此,这不仅是一种更为复杂的方法。它也更加脆弱。

答案 1 :(得分:0)

这是一种使用标志来确定何时从订单团队数组中提取元素的方法:

use strict;
use warnings;

my @team = ("AP","II","DS","WJ", "JK","LC","BJ") ;
my ( $team_regex ) = map {qr /$_/} join "|", map {quotemeta} @team;

my @orderdTeam ;
my $filename = shift @ARGV ;
open(my $fh, '<', $filename) or die "Could not open file $filename $!";
while (my $line = <$fh> ) {
    if ( $line =~ /^($team_regex)/ ) {
        push @orderdTeam, $1;
    }
}
close $fh;

print "Ordered: @orderdTeam\n";
my $extract_flag = 0;
my @result;
my $end_name;
for my $name (reverse @orderdTeam) {
    if ($name eq "BJ") {
        $extract_flag = 1;
    }
    next if $extract_flag == 0; # skip items until we get "BJ"
    if ( $extract_flag == 2 ) {
        $end_name = $name; # save stop name
    }
    last if $extract_flag == 3 && ($name eq $end_name); # second occurrence of $end_name
    push @result, $name;
    $extract_flag = 3 if $extract_flag == 2;
    $extract_flag = 2 if $extract_flag == 1;
}

print "Result: ", (join " ", reverse @result), "\n";

输出

Ordered: II AP DS LC II AP DS LC WJ DS II LC BJ
Result: WJ DS II LC BJ