Как я могу зациклить массив из первого вхождения элемента с определенным значением, используя perl? - PullRequest
4 голосов
/ 03 января 2012

У меня есть такой массив («valueA», «valueB», «valueC», «valueD») и т. Д. Я хочу перебрать значения массива, начиная с (например) первого экземпляра «valueC»,Все в массиве до первого экземпляра значения «valueC» следует игнорировать;поэтому в этом случае цикл будет обрабатывать только «valueC» и «valueD».

Я могу просто поместить условное выражение в мой цикл, но есть ли более точный способ выразить идею с помощью perl?

Ответы [ 6 ]

6 голосов
/ 03 января 2012

Я думаю, вам также нужно проверить, существует ли значение "valueC" внутри массива. Надеюсь, это поможет.

use strict;
use warnings;
use List::Util qw(first);

my @array = qw(valueA valueB valueC valueD);

my $starting_element = 'valueC';

# make sure that the starting element exist inside the array
# first search for the first occurrence of the $stating_element
# dies if not found
my $starting_index = first { $array[$_] eq $starting_element } 0 .. $#array
    or die "element \"$starting_element\" does not exist inside the array";

# your loop
for my $index ($starting_index .. $#array) {
    print $array[$index]."\n";
}
6 голосов
/ 03 января 2012
my $seen;
for ( @array ) {

    $seen++ if /valueC/;
    next unless $seen;
    ...
}

Но это $seen немного неловко. Оператор триггер выглядит более аккуратным IMO:

for ( @array ) {

    next unless /^valueC$/ .. /\0/;
           # or /^valueC$/ .. '' !~ /^$;
           # or $_ eq 'valueC' .. /\0/;
    ...
}

Или просто (основываясь на предложении Икегами):

for ( grep { /^valueC$/ .. /(*FAIL)/ } @array ) { ... }
6 голосов
/ 03 января 2012
my $seen;
for ( grep $seen ||= ($_ eq "valueC"), @array ) {
    ...
}
2 голосов
/ 03 января 2012
my $start = 0;
++$start while $start < @array && $array[$start] ne 'valueC';

, за которым следует либо

for (@array[$start..$#array]) {
   say;
}

или

for my $i ($start..$#array) {
   say $array[$i];
}
2 голосов
/ 03 января 2012
use List::MoreUtils qw( first_index );

foreach my $item ( @array[ ( first_index { $_ eq 'ValueC' } @array ) .. $#array ] ){
    # process $item
}
2 голосов
/ 03 января 2012

TIMTOWTDI, но я думаю, что:

foreach my $item (@list) {
      next if !$seen && ($item ne 'valueC');
      $seen++;
      ...
}

и читабельно, правильно и достаточно кратко.Все / valueC / solution будут обрабатывать что угодно после «DooDadvalueCFuBAr», а не того, что запросил OP.И нет, вам не нужен оператор триггера / диапазона, и проверка на существование заранее очень странна, кроме того, что требуется, возможно, неосновный пакет для выполнения довольно тривиальной задачи. Решение grep действительно заставляет мою голову вращаться, помимо создания и бросания временного файламассив как побочный эффект.

Если вы хотите проявить фантазию и избегать '' ifs ':

foreach my $item (@list) {
     $seen || ($item eq 'valueC') || next;
     $seen++;
     ...
}

Просто не пишите об этом домой.: -)

...