List-Comprehensions
view release on metacpan or search on metacpan
lib/List/Comprehensions.pm view on Meta::CPAN
use strict 'vars';
my ($i, $j, $k);
@res = comp2 { [$i, $j, $k] }
i => [0..4],
j => [0..4],
k => [0..4];
# each being less efficient but equivelant to
@res = ();
for $i ( 0..4 ) {
for $j ( 0..4 ) {
for $k ( 0..4 ) {
push @res, [$i, $j, $k];
}
}
}
=head1 FUNCTIONS
=over 4
=cut
sub min_length_of {
my $min = scalar( @{$_[0]} );
my ($i, $len);
for $i ( 1..$#_ ) {
$len = scalar( @{$_[$i]} );
$min = $len if $len < $min;
}
return $min;
}
sub zipn_flat {
my @ret = ();
my $len = $#_;
my $min = min_length_of @_;
my ($n, $i);
for $n ( 0..($min - 1) ) {
for $i ( 0..$len ) {
push @ret, $_[$i]->[$n];
}
}
return \@ret;
}
=item B<PF($$;@)>
For parallel comprehensions. ( flat zips according to minimal length )
eg: PF( [0..5], ['a'..'z'] )
is: [ 0, 'a', 1,'b' ... 5,'f' ]
=cut
sub PF($$;@) {
return zipn_flat(@_);
}
sub zipn {
my @ret = ();
my $len = $#_;
my $min = min_length_of @_;
my ($n, $i);
for $n ( 0..($min - 1) ) {
$ret[$n] = [];
for $i ( 0..$len ) {
push @{$ret[$n]}, $_[$i]->[$n];
}
}
return \@ret;
}
=item B<P($$;@)>
For parallel comprehensions. ( zips according to minimal length )
eg: P( [0..5], ['a'..'z'] )
is: [ [0,'a'], [1,'b'] ... [5,'f'] ]
=cut
sub P(@) {
return zipn(@_);
}
sub run {
my $i = shift;
my $arg;
if( $i + 1 <= $#sets ) {
for $arg ( @{$sets[$i]} ) {
$args[$i] = $arg;
run($i + 1);
}
} else {
SET:
for $arg ( @{$sets[$i]} ) {
$args[$i] = $arg;
for $guard ( @guards ) {
&$guard(@args) or next SET;
}
push @return, &$code(@args);
}
}
}
=item B<comp1(&@)>
Anonymous comprehensions (slighly faster)
comp1 sub { }, arg, [arg]
arg: array ref | guard subs
=cut
( run in 2.882 seconds using v1.01-cache-2.11-cpan-364913b4093 )