Description: |
Just an example of building an iterator with a closure to walk
through multiple arrays in parallel (maybe you have a table (2d
array) and want to walk the columns). This is just a simple one that
runs through the arrays and then resets so it can be used again:
|
sub parallel_it {
my @arr_refs = @_;
my $iter = 0;
return sub {
my @return = map{$_->[$iter]}@arr_refs;
$iter++;
return @return if grep{defined $_}@return;
$iter = 0;
return;
};
};
my @one = (0, 1, 2, 3, 4, 5, 6);
my @two = qw/Sun Mon Tue Wed Thu Fri Sat/;
my @three = qw/Zeroday Oneday Twoday Threeday
Fourday Fiveday Sixday/;
my $triples = parallel_it( \(@one,@two,@three) );
while( my($a, $b, $c) = $triples->() ){
print "$a:$b:$c\n";
}
# update @one and go again
@one = qw/A B C D E F G/;
while( my($a, $b, $c) = $triples->() ){
print "$a:$b:$c\n";
}
my @table = ( [ 1, undef, 3, 4],
[ 6, 7,],
[qw/a b c d e f/],
);
my $columns = parallel_it(@table);
while( my @col = $columns->() ){
print join(',', map{ $_ ? $_ : ' ' } @col),"\n";
}
Re: looping over multiple arrays
by chipmunk (Parson) on Jan 06, 2001 at 03:08 UTC
|
Very nice. There is one addition that I would suggest; allowing for parallel undefs in the arrays. Otherwise the iterator will reset if all the arrays happen to contain undef at the same index, even if there are more elements later in the arrays. Here's one possible solution:
sub parallel_it {
my @arr_refs = @_;
my $iter = 0;
return sub {
if (not grep $iter < @$_, @arr_refs) {
$iter = 0;
return;
}
my @return = map { $_->[$iter] } @arr_refs;
$iter++;
return @return;
};
}
| [reply] [d/l] |
|
Oops, I had that taken care of in an alternate version (that worked
on copies of the arrays and thus couldn't be reused if arrays were
updated), but a few cells back in the visual cortex must have
malfunctioned and I didn't see it here. Thanks for pointing it out.
| [reply] |
|