Reputation: 1441
I've got the following structure (in reality, it is much bigger):
$param_hash = {
'param1' => [0, 1],
'param2' => [0, 1, 2],
'param3' => 0,
};
And I'd like to print all the possible combinations of different parameters in the line, like this:
param1='0' param2='0' param3='0'
param1='0' param2='1' param3='0'
param1='0' param2='2' param3='0'
...
I understand that an iteration is needed (like this one), but I just cannot get it to work. How should I do this?
Or maybe I just should use another structure for storing parameters values scope?
Upvotes: 0
Views: 3134
Reputation: 119
This solution assumes the parameter ordering doesn't matter provided all cases are covered. I think CPAN has some ordered hashing if it's important to your problem.
use strict;
my %KNOBS = (ARG1=>[1,2,3],
ARG2=>['a','b'],
ARG3=>['41:R']);
my %indicies;
foreach my $keys (keys %KNOBS)
{
$indicies{$keys}=0;
}
my @orderedkeys = (keys %KNOBS);
printknobs();
while(incrimentindicies())
{
printknobs();
}
sub printknobs
{
foreach (@orderedkeys)
{
print "-$_ $KNOBS{$_}[$indicies{$_}] "; #num elements in array $key of %knob
}
print "\n";
}
sub incrimentindicies
{
foreach (@orderedkeys)
{
if( $indicies{$_} + 1 < @{$KNOBS{$_}})
{
$indicies{$_} = $indicies{$_} + 1;
return 1;
}else{
$indicies{$_} = 0;
}
}
return 0;
}
Output:
-ARG2 a -ARG3 41:R -ARG1 1
-ARG2 b -ARG3 41:R -ARG1 1
-ARG2 a -ARG3 41:R -ARG1 2
-ARG2 b -ARG3 41:R -ARG1 2
-ARG2 a -ARG3 41:R -ARG1 3
-ARG2 b -ARG3 41:R -ARG1 3
@orderedkeys
ensures that the changes in the ordering of %indicies
won't matter between calls to incrimentindicies
.
Upvotes: 1
Reputation: 1615
first you would have to find the longest possible array ref in the hash keys, the iterate like this
for my $value (0..$maxValue) {
foreach my $key (sort keys %$param_hash) {
unless (ref($param_hash->{$key}) eq 'ARRAY') {
$param_hash->{$key} = [$param_hash->{$key}];
}
print "$key=", $#{$param_hash->{$key}} >= $value ? $param_hash->{$key}->[$value] : 0;
print ' ';
}
print "\n";
}
where maxValue is the longest possible array ref, in this case 2. That will format it the way you described in your question.
Upvotes: 1
Reputation: 111
foreach my $key (keys %$param_hash){
if(ref $param_hash->{$key} eq 'ARRAY'){
foreach my $value (@{$param_hash->{$key}}){
print "$key = $ value ";
}
}
else {
print "$key = $param_hash->{$key} ";
}
print "\n"
}
Upvotes: 1