开发者

How can I loop over a list four elements at a time?

This is a slice from an otherwise successful script. What I need it to do is print one <tr> then print <td>$stat_array</td> four times, quit, print a </tr> then print another <tr>, print the next four $stat_arrays in @stat_array, and so on and then a </table>.

What it does is print all eight $start_arrays then a </tr>.

my @table_header = ("Process", "Region_Permission","Region Violation","Message Type");
my @stat_array =("ibfarm102  - localtick" ," Greenwich" ," hibmis100 -  procHKHD2 -     Hongkong" , "PidMonRsp" ," ibfarm102  - localtick", "Greenwich" ,"hibmis100 -      procHKHD2 - Hongkong", "PidMonReq");

print MAIL "<tr>\n";

for ($i = 0 ; $i <$#table_header ; $i = $i + $#table_header) {
    foreach my $stat_array(@stat_array)开发者_运维技巧 {
        print MAIL "<td>$stat_array</td>\n";
    }

    print MAIL "</tr>\n";
}
print MAIL "</table>\n";
print MAIL "<br><br>\n";
print MAIL "</table></center></body></html>";
close MAIL;

what i get:

<tr>
<td>ibfarm102  - localtick </td>
<td> Greenwich</td>
<td> hibmis100 -  procHKHD2 - Hongkong </td>
<td>PidMonRsp</td>
<td>ibfarm102  - localtick </td>
<td> Greenwich</td>
<td> hibmis100 -  procHKHD2 - Hongkong </td>
<td>PidMonReq</td>
</tr>

I need the table to look like :

<tr>
<td>ibfarm102  - localtick </td>
<td> Greenwich</td>
<td> hibmis100 -  procHKHD2 - Hongkong </td>
<td>PidMonRsp</td>
</tr>
<tr>
<td>ibfarm102  - localtick </td>
<td> Greenwich</td>
<td> hibmis100 -  procHKHD2 - Hongkong </td>
<td>PidMonReq</td>
</tr>


Sounds like a good candidate for List::MoreUtils' natatime (n-at-a-time) function:

use strict;
use warnings;
use List::MoreUtils 'natatime';

my $four_at_a_time = natatime 4, @stat_array;
my $string_to_print = "<html><body><center><table>\n";

while ( my @four = $four_at_a_time->() ) {

    $string_to_print .= join "\n", "<tr>",
                                   map { "<td>" . $_ . "</td>" } @four,
                                   "</tr>\n";
}


The every function from my module List::Gen allows you to walk any array with a variable step size:

my @array = 1..10;

for (every 4 => @array) {
    print "@$_\n";
}

which prints:

1 2 3 4
5 6 7 8
9 10

Unlike natatime or splicing a copy of the array, the elements in the for loop are aliased to the elements of @array so you can change them in the loop if you need to.


The simplest solution: Inside your for loop, whenever i has become a multiple of 4 other than 0 and other than the last item in the array, print </tr><tr>.


first of all you don't need the outer loop at all since the condition:

for ($i = 0 ; $i <$#table_header ; $i = $i + $#table_header)

will only ever execute the containing block only once! Now to separate every fourth element in @stat_array with a "<tr>", simply do this:

for ($i = 0; $i < $#stat_array; ++$i) {
        print MAIL "<td>$stat_array[$i]</td>\n";
        print MAIL "<tr>" if ($i % 4 == 0);
}


Another way:

# make a copy of the stats if you need the original array left intact
my @stat_array_rows = @stat_array;
while (my @stat_array_row = splice(@stat_array_rows, 0, 4)) {
    print MAIL "<tr>\n";
    for my $stat (@stat_array_row) {
        print MAIL "<td>$stat</td>\n";
    }
    print MAIL "</tr>\n";
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜