http://qs321.pair.com?node_id=918209

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

Hi all, I have a string like this.

my $text = "a.b.c.d";
I would like to get this converted into
my $hash = { a => { b => { c => d } } };

Could any one please help me with some efficient way to achieve this..

Replies are listed 'Best First'.
Re: converting a text into a hash datastructure
by moritz (Cardinal) on Aug 03, 2011 at 09:44 UTC
Re: converting a text into a hash datastructure
by jethro (Monsignor) on Aug 03, 2011 at 09:47 UTC
    my @textsplit= split /\./, $text; my $p= pop @textsplit; foreach (reverse @textsplit) { my $new->{$_}= $p; $p= $new; }

    But this naturally won't work if you want to convert many text lines with common parts (i.e. "a.b.c.d" and "a.b.n.m") and want to get one single data structure out of it

    UPDATE: davido found a bug in my code. Corrected with addition of $new.

Re: converting a text into a hash datastructure
by bart (Canon) on Aug 03, 2011 at 10:28 UTC
    You could do it by hand, or you could use a module: Data::Diver. You can even check the source of the latter to do the former.

    Hint: you have to split the string into a list, and in turn, for each item but the last two, add a new hashref at that level if one didn't already exist. Keep that reference in a variable for the next level.

    $key = 'a.b.c.d'; @list = split /\./, $key; my %hash; my $ref = \%hash; foreach (@list[0..$#list-2]) { $ref = $ref->{$_} ||= {}; } $ref->{$list[-2]} = $list[-1]; use Data::Dumper; print Dumper \%hash;

    BTW I think your API interface is badly designed: you should have a separate value for the keys ("a.b.c") and for the value ("d"). As it is now, I expect trouble.

      BTW I think your API interface is badly designed...

      Homework assignments are sometimes designed to illuminate such common pitfalls :)