NAME
Iterator::Array::Jagged - Quickly permute and iterate through multiple jagged arrays.
SYNOPSIS
use Iterator::Array::Jagged;
# Build up a set of data:
my @data = ();
for my $var ( 1...3 )
{
my @set = ();
for my $val ( 1...2 )
{
push @set, "var_$var=val_$val";
}# end for()
push @data, \@set;
}# end for()
# Iterator in object-oriented mode:
my $iterator = Iterator::Array::Jagged->new( data => \@data );
while( my @set = $iterator->next )
{
print "Next set: '" . join("&", @set) . "'\n";
}# end while()
# Iterator is a subref:
my $itersub = Iterator::Array::Jagged->get_iterator( data );
while( my @set = $itersub->() )
{
print "Next set: '" . join("&", @set) . "'\n";
}# end while()
# Functional callback style:
Iterator::Array::Jagged->permute(sub {
my (@set) = @_;
print "Next set: '" . join("&", @set) . "'\n";
}, @data );
Each example in the code above code prints the following:
Next set: 'var1=val1&var2=val1&var3=val1'
Next set: 'var1=val2&var2=val1&var3=val1'
Next set: 'var1=val1&var2=val2&var3=val1'
Next set: 'var1=val2&var2=val2&var3=val1'
Next set: 'var1=val1&var2=val1&var3=val2'
Next set: 'var1=val2&var2=val1&var3=val2'
Next set: 'var1=val1&var2=val2&var3=val2'
Next set: 'var1=val2&var2=val2&var3=val2'
DESCRIPTION
Iterator::Array::Jagged can permute through sets of "jagged" arrays - arrays of varying lengths.
Iterator::Array::Jagged works much like the odometer in an automobile. Except that each set of "numbers" can have any kind of data you want, and each set can contain 1 or more elements.
METHODS
new( %args )
Constructor. %args
should included the element data
which contains the arrayref of arrayrefs that you wish to iterate through.
next( )
Returns an array representing the next iteration of the permutation of your data set. See the synopsis for an example.
get_iterator( @data )
Returns a coderef that, when called, returns the next set of data until there are no more permutations. See the synopsis for an example.
permute( $subref, @data )
Calls $subref
for each permutation in @data
. This is currently BY FAR THE FASTEST METHOD AVAILABLE.
BENCHMARKS
After the initial release of Iterator::Array::Jagged, some people were wondering if there was any benefit to using I::A::J over another older module Algorithm::Loops and its NestedLoops
method. So I did some benchmarking and found some mixed results.
Rate I::A::J OO A::L::NL func I::A::J iterator A::L::NL iterator I::A::J permute
I::A::J OO 4.19/s -- -3% -19% -29% -45%
A::L::NL func 4.32/s 3% -- -16% -27% -43%
I::A::J iterator 5.15/s 23% 19% -- -12% -32%
A::L::NL iterator 5.88/s 40% 36% 14% -- -22%
I::A::J permute 7.58/s 81% 75% 47% 29% --
Depending on the size and depth of the jagged array data passed in, the results vary slightly. However, the order in which each method finishes is the same. Iterator::Array::Jagged->permute fastest by a signifigant margin over Algorithm::Loops::NestedLoops
. On the opposite end of the spectrum we have the OO method of Iterator::Array::Jagged which comes in at nearly half the speed of the permute
option.
The benchmark script I used is shown in the next section.
The Benchmark Script
#!/usr/bin/perl -w
use strict;
use Time::HiRes qw(gettimeofday);
use Benchmark qw' :all ';
use Algorithm::Loops 'NestedLoops';
use Iterator::Array::Jagged;
my @data = ();
for my $var ( 1...4 )
{
my @set = ();
my $max = $var % 2 ? 10 : 11;
for my $val ( 1...$max )
{
push @set, "var$var=val$val";
}# end for()
push @data, \@set;
}# end for()
cmpthese( 20, {
'I::A::J OO' => sub { do_iterator_array_jagged( @data ) },
'A::L::NL iterator' => sub { do_nestedloops_iterator( @data ) },
'A::L::NL func' => sub { do_nestedloops_func( @data ) },
'I::A::J permute' => sub { do_iaj_permute( @data ) },
'I::A::J iterator' => sub { do_iaj_iterator( @data ) },
});
sub do_iaj_iterator
{
my $iter = Iterator::Array::Jagged->get_iterator( @_ );
while( my @set = $iter->() )
{
}# end while()
}# end do_iaj_iterator()
sub do_iaj_permute
{
Iterator::Array::Jagged->permute( sub { }, @_ );
}# end do_iaj_permute()
sub do_iterator_array_jagged
{
my @data = @_;
my $iter = Iterator::Array::Jagged->new( data => \@data );
while( my $set = $iter->next )
{
}# end while()
}# end do_iterator_array_jagged()
sub do_nestedloops_func
{
NestedLoops( \@_, sub { } );
}# end do_nestedloops_func()
sub do_nestedloops_iterator
{
my @data = @_;
my $iter = NestedLoops( \@data );
while( my @set = $iter->() )
{
}# end while()
}# end do_nestedloops()
BUGS
It's possible that some bugs have found their way into this release.
Use RT http://rt.cpan.org/NoAuth/Bugs.html?Dist=Iterator-Array-Jagged to submit bug reports.
AUTHOR
John Drago mailto:jdrago_999@yahoo.com
COPYRIGHT AND LICENSE
Copyright 2007 John Drago, All rights reserved.
This software is free software. It may be used and distributed under the same terms as Perl itself.