I have a CSV file that I use split to parse into an array of N items, where N is a multiple of 3.
Is there a way i can do this
foreach my ( $a, $b, $c ) ( @d ) {}
similar to Python?
I addressed this issue in my module List::Gen on CPAN.
use List::Gen qw/by/;
for my $items (by 3 => @list) {
# do something with @$items which will contain 3 element slices of @list
# unlike natatime or other common solutions, the elements in @$items are
# aliased to @list, just like in a normal foreach loop
}
You could also import the mapn function, which is used by List::Gen to implement by:
use List::Gen qw/mapn/;
mapn {
# do something with the slices in @_
} 3 => @list;
my variable in a Perl foreach loop is never a copy, it is always an alias. A lexically scoped alias, but an alias none the less.You can use List::MoreUtils::natatime. From the docs:
my @x = ('a' .. 'g');
my $it = natatime 3, @x;
while (my @vals = $it->()) {
print "@vals\n";
}
natatime is implemented in XS so you should prefer it for efficiency. Just for illustration purposes, here is how one might implement a three element iterator generator in Perl:
#!/usr/bin/perl
use strict; use warnings;
my @v = ('a' .. 'z' );
my $it = make_3it(\@v);
while ( my @tuple = $it->() ) {
print "@tuple\n";
}
sub make_3it {
my ($arr) = @_;
{
my $lower = 0;
return sub {
return unless $lower < @$arr;
my $upper = $lower + 2;
@$arr > $upper or $upper = $#$arr;
my @ret = @$arr[$lower .. $upper];
$lower = $upper + 1;
return @ret;
}
}
}
List::MoreUtils are implemented in XS (that is, C) to provide the maximum possible efficiency. The use of splice introduces a lot of memory overhead and moving pointers around etc which one might notice if N is large enough.@z=(1,2,3,4,5,6,7,8,9,0);
for( @tuple=splice(@z,0,3); @tuple; @tuple=splice(@z,0,3) )
{
print "$tuple[0] $tuple[1] $tuple[2]\n";
}
produces:
1 2 3
4 5 6
7 8 9
0
@z array and is probably better written as a while loop
$aand$bfor variable names. Their are specially packaged scope variables for use withsort.$aor$bwithmy, and then later callsortin the same scope,sortwill blow up, complaining that it can't localize a lexical variable