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 )