in reply to Massive expansion of a hash of arrays?

Set::CrossProduct provides a solution.
#!/usr/bin/perl use strict; use warnings; use Set::CrossProduct; my %hash=('ID' => { 'key1' => ['key1_val1', 'key1_val2'], 'key2' => ['key2_val1', 'key2_val2'] } ); for my $id (keys %hash) { my @data = values %{ $hash{$id} }; my $cp = Set::CrossProduct->new( \@data ); my $i = 1; while( my $array_ref = $cp->get ) { print join( " ", $id, $i++, @$array_ref ), "\n"; } }
This prints
ID 1 key2_val1 key1_val1 ID 2 key2_val1 key1_val2 ID 3 key2_val2 key1_val1 ID 4 key2_val2 key1_val2
Note that my @data = values %{ $hash{$id} }; does not give values corresponding to 'key1', 'key2' ... 'key15' order. Some change in how the order of values appear would need to be made to get that.

Hope this helps,

Chris

Update: You will get huge amount of combinations for 12 rows with 15 items in each array. 15 ^ 12 = 129,746,337,890,625

Replies are listed 'Best First'.
Re^2: Massive expansion of a hash of arrays?
by Anonymous Monk on Jul 18, 2014 at 00:04 UTC

    Yes i think im over estimating my data set. Its more like 15 keys but each key will have 2-3 values. Only one of them has 12 values.

    how would CrossProduct deal with arrays that you didnt want to expand? One of the end values might be an array. I would want to copy that as is<\p>

      Something like this would prevent one of the arrays from being processed in the cross product.
      #!/usr/bin/perl use strict; use warnings; use Set::CrossProduct; my %hash=('ID' => { 'key1' => ['key1_val1', 'key1_val2'], 'key2' => ['key2_val1', 'key2_val2'], 'key3' => ['one', 'two'] } ); for my $id (keys %hash) { my $key3 = delete $hash{$id}{key3}; my @data = values %{ $hash{$id} }; my $cp = Set::CrossProduct->new( \@data ); my $i = 1; while( my $array_ref = $cp->get ) { print join( " ", $id, $i++, @$array_ref ), "\n"; } print "@$key3\n"; }
      Prints
      ID 1 key2_val1 key1_val1 ID 2 key2_val1 key1_val2 ID 3 key2_val2 key1_val1 ID 4 key2_val2 key1_val2 one two