Reputation: 7443
Got this:
my @list = <one two three>;
my %hash;
my $item1 = @list.shift;
%hash{$item1} = {$item1 => 1};
my $item2 = @list.shift;
%hash{$item1} = {$item2 => 1};
my $item3 = @list.shift;
%hash{$item1}{$item2} = {$item3 => 1};
say %hash;
Outputs this desired data structure:
{one => {two => {three => 1}}}
Obviously, this would be better if it were recursive, so I wrote this:
sub get-hash(%parent-hash, $last-item, *@list) {
my $item = @list.shift;
%parent-hash{$last-item} = { $item => 1 };
get-hash(%parent-hash{$last-item}, $item, @list) if @list;
return %parent-hash<root>;
}
%hash = get-hash({}, 'root', @list2);
Output:
{one => {two => {three => 1}}}
Though it works, it feels inelegant, especially having to pass in a root
argument to the sub and then removing it. Any suggestions?
Upvotes: 4
Views: 170
Reputation: 4465
If you want ’key-value’ structure Pair
my @list = <one two three>;
say [=>] |@list, 1
If you really need Hash
<one two three>
andthen |$_, 1
andthen .reduce: sub ($x,$y) is assoc<right> { %( $x => $y ) }\
andthen .say
or
<one two three>
andthen 1, |.reverse
andthen .reduce: { %( $^y => $^x ) }\
andthen .say
Upvotes: 2
Reputation: 29454
In the upcoming Raku version, there's a neat way to do this:
use v6.e.PREVIEW;
my @list = <one two three>;
my %hash;
%hash{||@list} = 1;
say %hash;
The ||
indicates that you want to use the list as multi-dimensional hash keys.
If you want to stick to things in the current released language versions, you can still call the operator directly, since it's only the syntax sugar that is missing:
my @list = <one two three>;
my %hash;
postcircumfix:<{; }>(%hash, @list) = 1;
say %hash
The output in either case is as you wish:
{one => {two => {three => 1}}}
Upvotes: 9
Reputation: 7443
OK, playing around with the order of the arguments helped simplify things a bit:
sub get-hash(@list, %parent-hash = {}, $last-item = 'root') {
my $item = @list.shift;
%parent-hash{$last-item} = { $item => 1 };
get-hash(@list, %parent-hash{$last-item}, $item) if @list;
return %parent-hash<root>;
}
my @list2 = <one two three>;
%hash = get-hash(@list2);
Upvotes: 2