Reputation: 113
I have a problem that I solved but in a dirty and non-dynamic way. So i'd like to know if anybody had a better solution.
I have an array, and I want to use each element of an array as keys for a SINGLE value (I don't care about the value actually, I use this method to build a sort of tree, but anyway, that's not the point)
My solution is like this atm :
@array = qw(un deux voila coucou hey whatsup);
$num_elements = scalar(@array);
switch ($num_elements) {
case 1 { $arbre{$array[0]} = 1 }
case 2 { $arbre{$array[0]}{$array[1]} = 2 }
case 3 { $arbre{$array[0]}{$array[1]}{$array[2]} = 3 }
case 4 { $arbre{$array[0]}{$array[1]}{$array[2]}{$array[3]} = 4 }
case 5 { $arbre{$array[0]}{$array[1]}{$array[2]}{$array[3]}{$array[4]} = 5 }
case 6 { $arbre{$array[0]}{$array[1]}{$array[2]}{$array[3]}{$array[4]}{$array[5]} = 6 }
case 7 { $arbre{$array[0]}{$array[1]}{$array[2]}{$array[3]}{$array[4]}{$array[5]}{$array[6]} = 7 }
else { print "previous case not true" }
}
As you can see it only works if I have no more than 7 elements in my array, otherwise I'll have to add another case. And of course it might happen since I'll do this with several arrays.
Anybody has a better solution ? Condisering the fact that I really dont care about the value. I put 1 2 3 4... 7 as ans exemple but it could be 1 or 5 anywhere it wouldn't matter.
Thanks !
Upvotes: 0
Views: 107
Reputation: 385789
Use Data::Diver.
use Data::Diver qw( DiveVal );
my %arbre;
DiveVal(\%arbre, map \$_, @array) = 1;
Without Data::Diver:
sub dive :lvalue {
my $p = \shift;
$p = \($$p->{$_}) for @_;
return $$p;
}
my %arbre;
dive(\%arbre, @array) = 1;
Depending on how you use the hash, you might be able to use the following solution which is much simpler and uses far less memory:
# If you can guarantee that chr(0) won't occur in @array
$arbre{ join "\0", @array } = 1;
# If @array can contain any characters. (5.10+, IIRC)
$arbre{ pack('(N/a*)*', @array } = 1;
PS - I recommend against using the Switch.pm module. It's an experimental module that can result in really hard to diagnose errors, and it doesn't really help you at all.
Upvotes: 1
Reputation: 126722
If the final value doesn't matter then presumably another hash reference will do?
Like this
use strict;
use warnings;
my @keys = qw(un deux voila coucou hey whatsup);
my %arbre;
my $hash = \%arbre;
$hash = ( $hash->{$_} = {} ) for @keys;
use Data::Dump;
dd \%arbre;
output
{
un => { deux => { voila => { coucou => { hey => { whatsup => {} } } } } },
}
Upvotes: 4