Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Of foreach loops and counting

by Cirollo (Friar)
on Aug 09, 2000 at 19:37 UTC ( #27069=perlquestion: print w/replies, xml ) Need Help??

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

What is the best way to count iterations in a foreach loop? Usually, if I need to count iterations, I'll just increment a variable each time through - something like
$i = 0; foreach (@array) { # do stuff $i++; }
Is there a better way to do this? Maybe through one of Perl's special variables? I thought about searching for the array index containing the current value (like, "what is the index of @array that contains $_"). Also, I'm not necessarily looking for a solution to give me a total end count of iterations, but more for telling me how many iterations I have gone through so I can say things like "print this line every 3rd time through the loop"

Replies are listed 'Best First'.
Re: Of foreach loops and counting
by eak (Monk) on Aug 09, 2000 at 19:42 UTC
    The easiest way I know of is to do something like.
    foreach (0..$#array){ # do stuff, $_ holds iteration num. }


    --eric

      Or if you really want to use one of Perl's special variables, try this:

      for ($[..$#array) { ## Foo }
      since "0" is not necessarily the first element of the array. Of course, nobody should ever, ever change the $[ variable except as part of an obfuscated perl program. :)

      Ok, and then I would just get my array values with $array[$_] instead of having the value be in $_. Sounds good to me. Thanks.
(jeffa) Re: Of foreach loops and counting
by jeffa (Bishop) on Aug 09, 2000 at 19:47 UTC
    Hmm, if you need to keep track of iteration in a loop, then you should use for instead of foreach.
    for (my $i=0; $i < $#array; $i++) { #print every third line print "$array[$i]\n" if (($i % 3)==0); #or even more consise print "$array[$i]\n" unless ($i%3); }
    I know that for is a synonym for foreach, but I simply prefer to use a for construct if I am going to need the current iteration. Guess it's the C inside me. Oh, thanks to KM - I'll be more idiomatic next time. ;)

    /me seeks Priest to exorcise evil C demons.

      I just wanted to comment that this is a very C like way of doing this, and is more idiomatically written as (or something similar as far as the loop construct):

      for (0..$#array) { print $array[$_]; }

      Cheers,
      KM

      for is a synonym of foreach. you make the decision on which one to use based on readabilty, since both behave exactly the same.
      --eric
Re: Of foreach loops and counting
by ferrency (Deacon) on Aug 09, 2000 at 20:18 UTC
    For testing "every third iteration," I do this sometimes:

    my $n = 0; foreach (@array) { next if I_dont_care_about($_); do_something_with ($_); print "." if !($n++ % 3); } print "\n";
    If you aren't necessarily processing every item in the list, but only want to count the number of elements you process, then using a temporary variable as you were doing is a useful alternative to looping over the array indices. It also works when you're doing things like looping over hash keys, where you can't count on having a numeric index implicitly; or processing lines of a file with a while (<>) loop.

    Update: KM, that is definitely true, and a more efficient and succinct way to count lines when you're interested in the total line count. The method I presented is still useful when you want to count the number of lines you processed, not the total line count so far.

    Alan

      or processing lines of a file with a while (<>) loop.

      In that case, you can use $. (perldoc perlvar) to know what line you are in. For example:

      #!/usr/bin/perl while (<DATA>) { print $. . ": $_"; } __DATA__ a b c d e f g h i # Would display when run... $ ./test.pl 1: a 2: b 3: c 4: d 5: e 6: f 7: g 8: h 9: i

      Cheers,
      KM

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://27069]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2022-05-24 10:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (82 votes). Check out past polls.

    Notices?