rsiedl has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm trying to create and array of all possible combinations of entries that are in another array but my logic is not working this morning...
Heres the example:
# First array # This array could contain any number of items my @firstArray = ( "item1", "item2", "item3" );
I'm trying to create the following array of arrays:
# Results array my @results = ( [ "item1" ], [ "item2" ], [ "item3" ], [ "item1", "item2" ], [ "item1", "item3" ], [ "item2", "item3" ], [ "item1", "item2", "item3" ] ); # Note: [ "item1", "item2" ] & [ "item2", "item1" ] # should be considered as the same.
Does anyone know how to do this?
Also, if possible, I would like to keep the order of the arrays in the results array from "smallest" to "largest" (in terms of scalar).

Cheers,
Reagen

Replies are listed 'Best First'.
Re: array logic
by muntfish (Chaplain) on Sep 02, 2004 at 10:46 UTC

    There are probably many ways to do this. Chances are there is some whizzy one-liner using Quantum::Superpositions or some such - but I haven't had time to look.

    There are 2n-1 possibilities (where n is the length of your input array) and that suggested (to me) looking at the binary digits of each number from 1 to 2n-1. That's what this solution does. It probably isn't the most elegant, and I suspect it is not the most efficient either.

    use strict; use Data::Dumper; my @firstArray = ( "item1", "item2", "item3" ); my $n = @firstArray; my @results; for my $i (1..2**$n-1) { my @selection; for my $j (0..$n-1) { if ($i & 2**$j) { push @selection, $firstArray[$j]; } } push @results, \@selection; } print Dumper(\@results);

    s^^unp(;75N=&9I<V@`ack(u,^;s|\(.+\`|"$`$'\"$&\"\)"|ee;/m.+h/&&print$&
      Thanks muntfish. Thats perfect for what i need. Cheers.
Re: array logic
by ysth (Canon) on Sep 02, 2004 at 14:34 UTC
    Rather than use boring names like "item1", "item2", etc., there are traditional metasyntactic variables to use in examples (with several different schools of tradition).

    Just for fun:

    my @firstArray = qw/foo bar baz/; my @results = grep @$_, map [reverse grep length, split /:/], glob join ":", map "{,$_}", reverse @firstArray;
Re: array logic
by rupesh (Hermit) on Sep 02, 2004 at 10:29 UTC
    Reagen,

    Your question is more practical, and depends on what you want as an output.

    Please refer to this link which is from the Categorized Questions and Answers page. Your basic queries should be answered there. Otherwise, come back here and let us know your specific inputs and outputs and we'll provide you with one of many possible solutions.

    Have Fun.