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

Someone will spend a nanosecond answering this - I on the other hand could spend hours. Therefore, thank you in advance. Using a foreach (a..b) etc. Is there a way of 'stepping' as in Basic ? foreach (a..b) step 5; or similar. Kindest and deserved regards, Richard.

Replies are listed 'Best First'.
Re: foreach .. stepping?
by BrowserUk (Patriarch) on Nov 20, 2002 at 04:15 UTC

    If I want to count from zero in steps I have used.

    print $_,'' for map{$_*5} 0 .. 5 0 5 10 15 20 25

    You could also do

    foreach ( ('a'..'z')[map{$_*5}0..5] ) { print $_,''; } a f k p u z

    or for an array

    @array = (0..50) foreach ( @array[map{$_*5} 0..@array/5] ) { print $_,''; } 0 5 10 15 20 25 30 35 40 45 50

    Or for a hash

    @hash{'a'..'z'} = (1..26); foreach ( (keys %hash)[map{$_*5}0 .. (scalar keys %hash)/5] ) { print "hash{$_} = $hash{$_}\n"; } hash{a} = 1 hash{f} = 6 hash{k} = 11 hash{p} = 16 hash{u} = 21 hash{z} = 26

    Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
    Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
    Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
    Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

Re: foreach .. stepping?
by dreadpiratepeter (Priest) on Nov 20, 2002 at 03:34 UTC
    for stepping you need a c-style for loop. Try this:
    my @list=(a,b,c,...z); // or whatever is in your list for (my $i=0;$i<$#list;$i+=5) { my $val = $list[$i]; ... }


    -pete
    "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."
Re: foreach .. stepping?
by Dr. Mu (Hermit) on Nov 20, 2002 at 08:39 UTC
    For syntax, though not efficiency, try:
    sub step { my $step = shift; return grep {($_ - $_[0]) % $step == 0} @_ } foreach (step 5, 2 .. 100) { print "$_ " }
    which prints:
    2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92 97
      Hi,

      But the fastest solution is using a closure:

      sub step { my $step=shift; my $count=0; my @array=@_; return sub { $return=$array[$count]; $count+=$step; return $return }; }; for ( my $s=step(5,2..100); my $res=&$s ; 1 ) { print "$res "; }
      My benchmark shows 6 times faster than the map, and 10 times faster than the step method.

      The reason is that I transfer an array only once, and than do queries in the array, whilst with map or step, one iterates over more than one array (map/grep and foreach).
      ---------------------------
      Dr. Mark Ceulemans
      Senior Consultant
      IT Masters, Belgium

Re: foreach .. stepping?
by pg (Canon) on Nov 20, 2002 at 05:09 UTC
    As .. is an operator in Perl, called range operator, I was thinking whether we could overload it. I am NOT saying to overload it for this stepping thing, that's too much.

    However it would be nice if you can overload the .. operator for some of your own classes, providing that your class has some sort of order defined.

    But I checked the document for overload, there is a list of overloadable operators, and .. is not one of them. Well..