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

Hey Monks,

I've got a bunch of data in the __DATA__ in the following format:

__DATA__

globalkey:key2:key3:key4:ARRAY VALUE

globalkey:key2:key3:key4:key5:ARRAY VALUE

globalkey:key2:key3:key4:key5:any arbitrary number of keys:ARRAY VALUE

So I'd like to build a HofHofH...ARRAY for all this data. The last item is always an array value but I have an arbitrary number of keys. Whats the easiest way to build this? Thanks for any help!!

  • Comment on Need some help building a data structure.

Replies are listed 'Best First'.
Re: Need some help building a data structure.
by lostjimmy (Chaplain) on May 02, 2009 at 05:25 UTC
    So what have you tried? It's usually nice to see some effort on your part first, but since I'm on a business trip with nothing to do, I came up with this heavily C-influenced approach. I also had to make some assumptions because I didn't think you provided enough input data, and you didn't give any output.
    use Data::Dumper; my $base_hash = {}; while (<DATA>) { chomp; my @keys = split ':'; my $val = pop @keys; my $hashp = $base_hash; for my $key (@keys) { unless (exists $hashp->{$key}) { $hashp->{$key} = {}; } $hashp = $hashp->{$key}; } $hashp->{"VAL"} = $val; } print Dumper $base_hash; __DATA__ global:2:3:4:LINE1 global:2:3:4:5:LINE2 ########## Output ########## $VAR1 = { 'global' => { '2' => { '3' => { '4' => { 'VAL' => 'LINE1', '5' => { 'VAL' => 'LINE2' } } } } } };
Re: Need some help building a data structure.
by FunkyMonk (Bishop) on May 02, 2009 at 09:21 UTC
    You need to provide more information. As I understand your problem, you want to create a structure that could be made manually like this

    push @{$hash{globalkey}{key2}{key3}{key4}}, 'ARRAY VALUE'; push @{$hash{globalkey}{key2}{key3}{key4}{key5}}, 'ARRAY VALUE'; #...

    The first line wants the 'key4' entry to be an array, but the second line want that entry to be a hash.

    Show some real data and tell us what output you expect.

      That's exactly what I was thinking and why I had to make the assumptions I did. I figured, if anything the provided code would help the OP to answer those questions, or at the very least provide a starting position for said OP.

      Good catch on pushing the array values. I didn't take that part into my assumptions. So yoda54, got any more details for us?

Re: Need some help building a data structure.
by holli (Abbot) on May 03, 2009 at 13:47 UTC
    The natural way is of course recursion.
    sub build { my $ref = shift; my $keys = shift; my $key = shift @$keys; # only one left in keys. that must be the value. if ( @$keys == 1 ) { $ref{$key} = $keys->[0]; } else { $ref{$key} = {} unless defined $ref{$key}; build($ref{$key}, $keys); } } my $hash = {}; while (<DATA>) { build($hash, split /:/); }


    holli

    When you're up to your ass in alligators, it's difficult to remember that your original purpose was to drain the swamp.
Re: Need some help building a data structure.
by spx2 (Deacon) on May 02, 2009 at 06:38 UTC
    hmm, I wonder why this doesn't work ?
    1 use Data::Dumper; 2 use feature 'say'; 3 4 my $hashref; 5 my $code; 6 while(my $line = <DATA>) { 7 chomp $line; 8 my @pieces = split ':',$line; 9 my $val = pop @pieces; 10 $code .= ('$hashref'.join '',map { "->{'$_'}" }@pieces)."='$va +l';\n"; 11 }; 12 eval $code; 13 14 print Dumper $hashref; 15 16 __DATA__ 17 globalkey:key2:key3:key4:ARRAY VALUE 18 globalkey:key2:key3:key4:key5:ARRAY VALUE 19 globalkey:key2:key3:key4:key5:any arbitrary number of keys:ARRAY V +ALUE $VAR1 = { 'globalkey' => { 'key2' => { 'key3' => { 'key4' => 'ARRAY VA +LUE' } } } };
      Because you're using eval dangerously
      globalkey:'.`rm -rf /`.':fooled:you: now you data is gone
        you're right , but here it should have worked fine
Re: Need some help building a data structure.
by parv (Parson) on May 02, 2009 at 09:41 UTC
    From the description of the problem, (one way) linked list data structure comes to mind. lostjimmy has already provided a solution on the same idea.