Description: Takes a list or array of array references and returns a function that will return successive permutations of the referenced arrays. Avoids recursion so will work on abitrarily huge sets of data. Runtime scales linearly with the number of sets. Minimal memory usage.
```my @aoa = (
[('a'..'z')],
[('A'..'Z')],
[(1..26)],
);

my \$iter = make_permutator(@aoa);

while (my @els = \$iter->() ){
print @els,"\n";
}

sub make_permutator{
my @arefs = @_;
my @arrayindexes = ();
foreach (@arefs){
push @arrayindexes,[\$_,0,\$#{\$_}];
}

return sub {
return if \$arrayindexes[0]->[1] > \$arrayindexes[0]->[2];
my @els =  map { \$_->[0]->[ \$_->[1]] } @arrayindexes;
# Check for out of bounds....
\$arrayindexes[\$#arrayindexes]->[1]++;
for (my \$i = \$#arrayindexes; \$i > 0; \$i--){
if (\$arrayindexes[\$i]->[1] > \$arrayindexes[\$i]->[2
+]){
\$arrayindexes[\$i]->[1] = 0;
\$arrayindexes[\$i-1]->[1]++;
}else{
last;
}
}
return @els;

};
}
```
Replies are listed 'Best First'.
Re: Non- recursive permutation of arrays.
by ariels (Curate) on Mar 25, 2002 at 08:08 UTC

Or, you could just count up to the product of the array sizes, and use the count to compute the offsets into the arrays (I think a note described this, but no code). If you have lists of lengths l1,...,lk, think of the numbers 0..(l1*...*lk-1). You want to convert them to a variable-base number system, where the first digit can be 0..l1-1, the second digit can be 0..l2-1,...

```#!/usr/local/bin/perl -w
use strict;

my @aoa = (
[('a'..'f')],
[('A'..'C')],
[(1..2)],
);

my \$iter = make_permutator(@aoa);

while (my @els = \$iter->() ){
print "@els\n";
}

# ariels' code from here
sub make_permutator {
use integer;
return sub {
my @ret;