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

Hello Folks,
I wonder if you can help me? its probably really easy but my head is not working. Assuming I have a : delimited file such as
EQUIPMENT: BASEBALL: ACCESSORI EQUIPMENT: BASEBALL: BALLS EQUIPMENT: CYCLING EQUIPMENT: GOLF: BAGS EQUIPMENT: GOLF: BALLS EQUIPMENT: OTHER BALL SPORTS: EQUIPMENT: OTHER BALL SPORTS: EQUIPMENT: RACQUET SPORTS: BAL EQUIPMENT: RACQUET SPORTS: RAQ
I want to create a nice data structure such as
my %hash = ('EQUIPMENT' => { 'BASEBALL' => { 'ACCESSORI' => 1, 'BALLS' => 1, }, 'CYCLING' => 1, 'GOLF' => { 'BAGS' => 1, 'BALLS' => 1, }, 'OTHER BALL SPORTS' => 1, 'RACQUET SPORTS' => { 'RAQ' => 1, 'BAL' => 1} });
What would the algorithm be to convert it ? Reading in the file and splitting is done so I have an array for each line - but I cant think of how to create the array?

Replies are listed 'Best First'.
Re: Array to Hash of Hashes
by jethro (Monsignor) on Aug 27, 2009 at 11:39 UTC

    Untested:

    my $p= \%hash; my $last= pop @splittedline; foreach @splittedline { $p->{$_}={} if (not exists $p->{$_}); $p= $p->{$_}; } $p->{$last}= 1;

    I'm sure someone else will find a more elegant solution ;-). (though I don't consider the obvious solution with eval elegant)

Re: Array to Hash of Hashes
by Anonymous Monk on Aug 27, 2009 at 11:26 UTC
    Update: Last line should be how to create the HASH not ARRAY!
Re: Array to Hash of Hashes
by bichonfrise74 (Vicar) on Aug 27, 2009 at 21:54 UTC
    This should do the trick for you.
    #!/usr/bin/perl use strict; use Data::Dumper; my %record; while(<DATA>) { chomp; my ($key, $sub_key, $val) = split ":"; $record{$key}->{$sub_key}->{$val} = 1; } print Dumper \%record; __DATA__ EQUIPMENT: BASEBALL: ACCESSORI EQUIPMENT: BASEBALL: BALLS EQUIPMENT: CYCLING EQUIPMENT: GOLF: BAGS EQUIPMENT: GOLF: BALLS EQUIPMENT: OTHER BALL SPORTS: EQUIPMENT: OTHER BALL SPORTS: EQUIPMENT: RACQUET SPORTS: BAL EQUIPMENT: RACQUET SPORTS: RAQ