http://www.perlmonks.org?node_id=894306

naturalsciences has asked for the wisdom of the Perl Monks concerning the following question:

while (my $in = <IN>){ foreach (@ref){ if ($_=~ m/$in/){ print OUT "$_"; }}}

What if I would like to print out not $_ but the next iteration $_+ so to say. It has became a general problem to me. I regularily want to test an array element for a condition and then according to this retrieve another array element some steps "upstream". (Sorry about my language but I hope these expressions are able to carry my meaning)

Using loop control commands like next or redo seems kind of too brutal for this kind of work, I would like to hear your what methods do you suggest - and if possible a sample using the case above -- only instead of printing out $_ to print out $_ next value.

Replies are listed 'Best First'.
Re: Getting values for next array iteration when matching current
by Anonymous Monk on Mar 20, 2011 at 08:50 UTC
    for( my $ix = 0; $ix < @ref; $ix++ ){ my $it = $ref[$ix]; if( $it =~ m/$in/i ){ print OUT $it,$ref[$ix+1]; } }
      DAMN now im blinded by light!!! Thank you very much - guess it was too obvious solution.

      edit : after euphoria :D On the other hand with the foreach loop gone the code will not check the pattern $in from the filehandle and match it with every individual line in array @ref. It will start checking if the first element in array @ matches the pattern of the first line from filehandle second from second etc. Which doesn't work for me - maybe if I'll load the filehandle <IN> into an array and to a foreach from there.

Re: Getting values for next array iteration when matching current
by wind (Priest) on Mar 20, 2011 at 15:50 UTC
    Anytime you need to look ahead, just loop by indexes instead of by element.
    while (my $in = <IN>) { for my $i (0..$#ref) { if ($ref[$i] =~ m/$in/) { print OUT $ref[$i+1]; } } }
Re: Getting values for next array iteration when matching current
by CountZero (Bishop) on Mar 20, 2011 at 19:38 UTC
    With a sufficiently recent version of Perl, you can do:
    use Modern::Perl; my @ref = qw/aap noot mies wim zus jet teun vuur gijs lam kees bok/; while (my $in = <DATA>){ chomp $in; while (my ($index, $value) = each @ref) { if ($value=~ m/$in/){ say "$in : $value : $ref[$index + 2]"; } } } __DATA__ a e i o u aa ee ie oo uu
    output:
    a : aap : mies a : lam : bok e : mies : zus e : jet : vuur e : teun : gijs e : kees : i : mies : zus i : wim : jet i : gijs : kees o : noot : wim o : bok : u : zus : teun u : teun : gijs u : vuur : lam aa : aap : mies ee : kees : ie : mies : zus oo : noot : wim uu : vuur : lam
    Of course you get a number of Use of uninitialized value in concatenation (.) or string at ... warnings because you access unitialized elements of the array.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Getting values for next array iteration when matching current
by Marshall (Canon) on Mar 21, 2011 at 03:22 UTC
    Your code appears nonsensical and will not compile using "warnings" and "strict". Start over with a problem statement showing some input data and what you desire as output. Then show your code that will run using "warnings" and "strict" and its output and how that deviates from the desired output.

    foreach (@ref)   #@ref is an undefined value, please describe at least in words what you think it means.

Re: Getting values for next array iteration when matching current
by choroba (Cardinal) on Mar 21, 2011 at 20:38 UTC
    Or, you can use a state flag:
    my $print_next; while (my $in = <IN>){ foreach (@ref){ if ($print_next) { print OUT "$_"; undef $print_next; } $print_next = 1 if m/$in/; } } }