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

In continue with my question from yesterday (creating hash tree form an array), I want to expand this.
I need to create the hash tree from many arrays as follows (with demerphq's solution):
my %hash; for (@bigArray) { @tmp = split(\\+/); # split by '+' $node = 'value'; $node = {$_=>$node} foreach reverse @keys; .... }
I miss the continue (the ... in the loop) in order to insert the pointer to one big hash, in order to get for the following array:
my @bigArray = qw(brown red+green blue+yellow black red+white purple+o +range+gray);
this hash:
%hash = ( brown => 1, red => ( green => 1, white => 1, ), blue => ( yellow => 1, ), black => 1, purple => ( orange => ( gray => 1, ), ), );
Anyone can help me with that?
Thanks

Hotshot

Replies are listed 'Best First'.
Re: hash tree
by Aristotle (Chancellor) on Sep 10, 2002 at 13:46 UTC
    Almost no change:
    #!/usr/bin/perl -w use strict; use Data::Dumper; my @bigArray = qw(brown red+green blue+yellow black red+white purple+o +range+gray); my %hash; for (@bigArray) { my @keys = split /\+/; my $ptr = \%hash; $ptr = $ptr->{$_} ||= {} for @keys[0..$#keys-1]; # work done here $ptr->{$keys[-1]} = 1; } print Dumper(\%hash); __END__
    Output:
    $VAR1 = { 'blue' => { 'yellow' => 1 }, 'purple' => { 'orange' => { 'gray' => 1 } }, 'brown' => 1, 'black' => 1, 'red' => { 'green' => 1, 'white' => 1 } };
    Key change vs the code I posted in your previous node is use of ||= vs = so that a key is only assigned an anonymous hashref when it doesn't already have a value. (Which isn't quite right; it's only assigned a hashref when it doesn't have a true value, but that will work so long as any value a key can ever have is true. Here they can only be either hashrefs or the value 1, both of which are indeed true.)

    Makeshifts last the longest.

Re: hash tree
by japhy (Canon) on Sep 10, 2002 at 15:07 UTC
    Demerphq said that his solution didn't work for making many modifications to one hash, because it creates a single chain of keys. This is why I use my solution:
    for (@bigArray) { my $node = \\%hash; $node = \$$node->{$_} for split /\+/; $$node = 1; }
    Ta da.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;