Iterator::Array::Jagged - Quickly permute and iterate through multiple jagged arrays.
use Iterator::Array::Jagged; # Build up a set of data: my @data = ( [qw/ a b /], [qw/ c d /], [qw/ e f g /] ); # 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: b&c&e' Next set: a&d&e' Next set: b&d&e' Next set: a&c&f' Next set: b&c&f' Next set: a&d&f' Next set: b&d&f' Next set: a&c&g' Next set: b&c&g' Next set: a&d&g' Next set: b&d&g'
Iterator::Array::Jagged can permute through sets of "jagged" arrays - arrays of varying lengths.
Iterator::Array::Jagged
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.
Iterator::Array::Jagged is stable and ready for production use as of version 0.05.
0.05
Constructor. %args should included the element data which contains the arrayref of arrayrefs that you wish to iterate through.
%args
data
Returns an array representing the next iteration of the permutation of your data set. See the synopsis for an example.
Returns a coderef that, when called, returns the next set of data until there are no more permutations. See the synopsis for an example.
Calls $subref for each permutation in @data. This is currently BY FAR THE FASTEST METHOD AVAILABLE.
$subref
@data
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.
NestedLoops
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 is 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.
Algorithm::Loops::NestedLoops
permute
The benchmark script that was used is shown in the next section.
Benchmarks were done on a server with the following specs:
Intel(R) Core(TM)2 CPU 6400 @ 2.13GHz stepping 02
2Gb
#!/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()
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.
John Drago mailto:jdrago_999@yahoo.com
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.
To install Iterator::Array::Jagged, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Iterator::Array::Jagged
CPAN shell
perl -MCPAN -e shell install Iterator::Array::Jagged
For more information on module installation, please visit the detailed CPAN module installation guide.