The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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.