package Iterator::Array::Jagged; use strict; use warnings 'all'; our $VERSION = '0.02'; #============================================================================== sub new { my ($class, %args) = @_; my $s = bless { idx => [ map { 0 } 0...scalar(@{$args{data}}) - 1 ], sizes => [ map { scalar(@$_) - 1 } @{$args{data}} ], data => $args{data}, _max => scalar(@{$args{data}}), _is_finished => 0, }, $class; return $s; }# end new() #============================================================================== sub _increment { my ($s, $index) = @_; if( $s->{idx}->[ $index ] < $s->{sizes}->[ $index ] ) { $s->{idx}->[ $index ]++; } else { $s->{idx}->[ $index ] = 0; if( $index + 1 < $s->{_max} ) { $s->_increment( $index + 1 ); } else { $s->{_is_finished} = 1; }# end if() }# end if() }# end _increment() #============================================================================== sub next { my ($s) = @_; return if $s->{_is_finished}; # Calculate and return the current value: my @parts = (); for( 0...$s->{_max} - 1 ) { my $part_idx = $s->{idx}->[ $_ ]; push @parts, $s->{data}->[ $_ ]->[ $part_idx ]; }# end for() $s->_increment( 0 ); return @parts; }# end next() 1; #return true: __END__ =pod =head1 NAME Iterator::Array::Jagged - Iterate through multiple jagged arrays =head1 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() my $iterator = Iterator::Array::Jagged->new( data => \@data ); while( my @set = $iterator->next ) { print "Next set: '" . join("&", @set) . "'\n"; }# end while() The 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' =head1 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. =head1 METHODS =head2 new( %args ) Constructor. C<%args> should included the element C which contains the arrayref of arrayrefs that you wish to iterate through. =head2 next( ) Returns an array representing the next iteration of the permutation of your data set. See the synopsis for an example. =head1 BUGS It's possible that some bugs have found their way into this release. Use RT L to submit bug reports. =head1 AUTHOR John Drago L =head1 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. =cut