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

I am trying to loop through an array were the first element is either a 3, 4, or 7 the second value is any number between 1 and 2048.
The number of rows in the array is random.
example of array:
3 200
4 50
3 100
3 100
3 100
4 50
4 25
The first rows where [element 0 = 3] need to have [element 1] added together and then set equal to a variable.
The first set of rows where [element 0 = 4] need to have [element1] added together and set equal to a variable.
Using the example array the value of the variables should be ele3 = 200 and ele4 = 50.
Then I need to call another subroutine that process those variables
. Here is where I get stuck
I need to go back to that loop and start at the next row in the array and find all the [element 0 = 3] add up the [element 1] set them equal to same variable as the before ele3.
Find all the [element 0] = 4 and add up the [elements 1] and set it equal to the same varable ele4 and pass them to the sub routine.
Using the example array the value of the variables (the second time) should be ele3 = 300 and ele4 = 75.
If the the value of [element 0 = 7] it should just report it as an error and fail.

edited: Tue Sep 10 02:48:38 2002 by jeffa - s/\[/[/g

Replies are listed 'Best First'.
Re: stoping and restarting a loop
by BrowserUk (Patriarch) on Sep 09, 2002 at 22:40 UTC

    Here's one way that you should be able to adapt for your needs.

    #! perl -sw use strict; my @data = <DATA>; my ($type3total, $type4total) = (0,0); my $state = ''; for (@data) { chomp; my ($part1, $part2) = split; if ($state eq "type4" && $part1 eq "3") { process( $type3total, $type4total ); ($type3total, $type4total) = (0,0); } $state = "type$part1"; $type3total += $part2 if ($part1 == 3); $type4total += $part2 if ($part1 == 4); die "array contains a type 7 record\n" if $part1 == 7; } process( $type3total, $type4total ); sub process { my ($type3, $type4) = (shift, shift); print "Processing type 3 total of $type3 and a type 4 total of $ty +pe4\n"; return; } __DATA__ 3 200 4 50 3 100 3 100 3 100 4 50 4 25

    Gives:

    C:\test>196448 3 - 200 4 - 50 3 - 100 Processing type 3 total of 200 and a type 4 total of 50 3 - 100 3 - 100 4 - 50 4 - 25 Processing type 3 total of 300 and a type 4 total of 75

    Well It's better than the Abottoire, but Yorkshire!
      A fine answer, functionally, but what's with this shift, shift action? It would be more concise, I think, to simply express it as this:
      sub process { my ($type3, $type4) = @_; print "Processing type 3 total of $type3 and a type 4 total of $ty +pe4\n"; return; }
      Maybe I'm just overly sensitive about shift. Still, with Perl 6 moving towards a full argument declaration, it will be a lot easier to migrate than shift-riddled code.

        In the original code I used $_[0] and $_[1], I changed that and gave the vars names simply to make it clearer to the OP.

        Why (shift,shift)? Why not? It makes it clear that I am only going to consider using 2 parameters. Admittely that can be derived from the left-hand side of the expression, but what is wrong with shift? The docs don't indicate that it is depreciated or anything.


        Well It's better than the Abottoire, but Yorkshire!