Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re: How to skip certain values in a foreach loop

by samarzone (Pilgrim)
on Dec 28, 2010 at 12:21 UTC ( #879419=note: print w/replies, xml ) Need Help??

in reply to How to skip certain values in a foreach loop

Your problem is not very clear to me but I am assuming that for each value of AdminTime you want to fetch five values from AdminEndDate.

Is that possible in Perl?

It is more of a logic issue rather than Perl issue

You can pop out five values from AdminEndDate for each iteration of AdminTime. You can also take a counter in AdminTime's loop and use it to get the starting index of AdminEndDate.

I hope that directs to you towards solution. I haven't worked on Template so I won't be able to show you how to code it.

- Samar

Replies are listed 'Best First'.
Re^2: How to skip certain values in a foreach loop
by Frederic_S (Novice) on Dec 28, 2010 at 12:48 UTC
    Hello Samar! Thank you - yes that's exactly what I want to do. With the current code, the output looks somewhat like this:
    date user1 user2 user3 user4 user5 day1 dl1 dl2 dl3 dl4 dl5 day2 dl1 dl2 dl3 dl4 dl5 dl6 dl7..dl10 day3 dl1 dl2 dl3 dl4 dl5 dl6 dl7..dl15
    This is what I want:
    date user1 user2 user3 user4 user5 day1 dl1 dl2 dl3 dl4 dl5 day2 dl6 dl7 dl8 dl9 dl10 day3 dl11 dl12 dl13 dl14 dl15 ....
    What would be the perl code to skip the first 5 iterations of the second loop and first 10 of the third loop? Adapting that code to the template is quite easy, so that wouldn't be the problem. Thank you for your help! :-) Regards Fred
      Maybe I should also elaborate where I get the data from. This is how the data is fetched and proccessed:
      # In the main script: my @ReturnValues; my @AdminValues; my @AdminTime; my @AdminEndDate; Admin(\@ReturnValues, \@AdminValues, \@AdminTime, \@AdminEndDate); # This is the code in sub Admin: my $sql = "SELECT DISTINCT user_id, realname FROM database.time_data W +HERE version='$Version' AND product_id='$ProductID' AND milestone='$M +ileStone'"; my $sth = $dbh->prepare($sql); $sth->execute(); while(my @RowAdmin = $sth->fetchrow_array()) { my %AdminData; $AdminData{"UserID"} = $RowAdmin[0]; $AdminData{"RealName"} = $RowAdmin[1]; # Insert them into hash push (@$AdminValues, \%AdminData); } # Get the stored days $sql = "SELECT DISTINCT day FROM database.time_data WHERE version='$Ve +rsion' AND product_id='$ProductID' AND milestone='$MileStone'"; $sth = $dbh->prepare($sql); $sth->execute(); while(my @RowTime = $sth->fetchrow_array()) { my %AdminTimeData; $AdminTimeData{"Day"} = $RowTime[0]; push (@$AdminTime, \%AdminTimeData); my $sql2 = "SELECT app_end FROM database.time_data WHERE day='$AdminTi +meData{'Day'}' AND version='$Version' AND product_id='$ProductID' AND + milestone='$MileStone'"; my $sth2 = $dbh->prepare($sql2); $sth2->execute(); while(my @RowTime2 = $sth2->fetchrow_array()) { my %AdminAppEnd; $AdminAppEnd{"AppEnd"} = $RowTime2[0]; push (@$AdminEndDate, \%AdminAppEnd); } } $sth->finish(); $dbh->disconnect(); # Back in the main script: # Pass Values to template $vars->{'ReturnValues'} = \@ReturnValues; $vars->{'AdminValues'} = \@AdminValues; $vars->{'AdminTime'} = \@AdminTime; $vars->{'AdminEndDate'} = \@AdminEndDate;
      How the data is then proccessed in the template can be seen in the first Post. I hope this helps a bit. Regards Fred

        I think it would make your life easier if you would massage your date into a more appropriate form on the Perl side, instead of fighting with slices of linear arrays within the template.

        Here's a simplified example showing a possible data structure:

        #!/usr/bin/perl -w use strict; use Template; my $templ = q{ <table> <tr> <td>date</td> [% FOREACH realname IN Users %] <td>[% realname %]</td> [% END %] </tr> [% FOREACH row IN Dates %] <tr> <td>[% row.Day %]</td> [% FOREACH date IN row.EndDates %] <td>[% date %]</td> [% END %] </tr> [% END %] </table> }; my $vars = { Users => [qw(user1 user2 user3 user4 user5)], Dates => [ { Day => 'day1', EndDates => [qw(dl1 dl2 dl3 dl4 dl5)], }, { Day => 'day2', EndDates => [qw(dl6 dl7 dl8 dl9 dl10)], }, { Day => 'day3', EndDates => [qw(dl11 dl12 dl13 dl14 dl15)], }, ], }; my $tt = Template->new(); $tt->process(\$templ, $vars) or die $tt->error();


        date user1 user2 user3 user4 user5
        day1 dl1 dl2 dl3 dl4 dl5
        day2 dl6 dl7 dl8 dl9 dl10
        day3 dl11 dl12 dl13 dl14 dl15

        You should improve the structure of $vars. You have n values in @AdminTime and 5*n values in @AdminEndDate 5 for each value of @AdminTime. Right!!!
        You should keep only 5 values in @AdminEndDate, each an arrayref for all five deadlines of a day in @AdminTime. Now your @AdminEndDate array index will be same as that of @AdminTime.

        For example you have @AdminTime as ('day1', 'day2', 'day3') and @AdminEndDate as

        ({AppEnd => 'dl1'}, {AppEnd => 'dl2'}, {AppEnd => 'dl3'}, {AppEnd => 'dl4'}, {AppEnd => 'dl5'}, {AppEnd => 'dl6'}, {AppEnd => 'dl7'}, {AppEnd => 'dl8'}, {AppEnd => 'dl9'}, {AppEnd => 'dl10'}, {AppEnd => 'dl11'}, {AppEnd => 'dl12'}, {AppEnd => 'dl13'}, {AppEnd => 'dl14'}, {AppEnd => 'dl15'})

        Make your @AdminEndDate array like
        ([{AppEnd => 'dl1'}, {AppEnd => 'dl2'}, {AppEnd => 'dl3'}, {AppEnd => +'dl4'}, {AppEnd => 'dl5'}], [{AppEnd => 'dl6'}, {AppEnd => 'dl7'}, {AppEnd => 'dl8'}, {AppEnd => ' +dl9'}, {AppEnd => 'dl10'}], [{AppEnd => 'dl11'}, {AppEnd => 'dl12'}, {AppEnd => 'dl13'}, {AppEnd = +> 'dl14'}, {AppEnd => 'dl15'}]

        You can now run a loop from index 0 to $#AdminTime and use the index number for both the arrays. You'll, however, have to modify your template code a little to dereference the inner array references of all five values corresponding to each day

        - Samar

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://879419]
[hippo]: That's some Joycean spam.

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (8)
As of 2018-05-22 12:28 GMT
Find Nodes?
    Voting Booth?