in reply to Re: Building hash tree from a data file
in thread Building hash tree from a data file
Below is the code I have tried..
I am sure it is not great, but I have given a try....
I am able to go to 2 levels but confused as to how to make this more generic. Two issues I have are:-
1)The way I build the data structure doesn't seem to be right, although it produces the result as it is not generic
$linked_dsc{ $main_var }{ $contitent_hash->{ $link_word } }{ $ret_dsc->{ $key1 } } = undef;
2) I have to call the subroutine again for each element in the array @new_actions. I don't how to proceed with that.
Please provide some hints/ tips to move further..
#! /usr/bin/perl use strict; use Data::Dumper; my ( %linked_dsc, $main_var, @actions ); my $maincnt = 0; my $found = 0; my ($t1, $t2); my $contitent_hash = { }; open (FILE, "./Data.txt") or die "Can't find file"; while (<FILE>) { # From start of 1st 'Main' to start of 2nd 'Main', read the lines and # store in appropriate variables # $contitent_hash has abbreviation as key and full name as value # @actions has search patterns to look for in the next pass # for example: 'NA' => 'North America' is in the hash variable and # 'Name = NA' is in the array if ( /^Main$/ ) { $maincnt++; } if ( $maincnt == 1 ) { if ( /^Main/../^End/) { if ( /^\s*(.*)\s=\s(.*)/ ) { if ( $1 eq "Name") { $main_var = $2; #$linked_dsc{ $main_var } = undef; } } } elsif ( /^Sub/../^End/) { if ( /^\s*(.*)\s=\s(.*)/ ) { if ( $1 eq "Action") { ($t1, $t2) = split ( /: /, $2 ); push @actions, ('Name = '. $t2 ); $contitent_hash->{ $t2 } = undef; } elsif ( $1 eq "Text") { $contitent_hash->{ $t2 } = $2; } } } } last if ( $maincnt > 1); } # Self checking... print "---------------------\n"; print "@actions\n"; print "---------------------\n"; foreach my $key ( keys %{ $contitent_hash } ) { print "$key = $contitent_hash->{ $key }\n"; #$linked_dsc{ $main_var }{ $contitent_hash->{ $key } } = undef; } print "---------------------\n"; # End of self check foreach ( @actions ) { print "SEARCH STRING: $_\n"; my (undef, $link_word) = split / = /; my ($ret_dsc, $ret_arr ) = process_next( $_ ); foreach my $key1 ( keys %{ $ret_dsc } ) { # Checking... print "$key1 = $ret_dsc->{ $key1 }\n"; $linked_dsc{ $main_var }{ $contitent_hash->{ $link_word } }{ $ +ret_dsc->{ $key1 } } = undef; } #Checking... #print Dumper ( $ret_dsc ); #print Dumper ( $ret_arr ); } print Dumper ( \%linked_dsc ); # Subroutine to search for the searchstring in the file, start reading + # the subsequent lines and store in appropriate variables until the # next 'Main' is encountered. sub process_next { my $searchstr = shift; my $new_href= { }; my ( @new_actions, $left_val, $right_val); seek ( FILE, 0, 0 ); $found = 0; while ( <FILE> ) { if ( ! $found ) { if ( ! /$searchstr/ ) { next; } else { $found = 1; } } if ( $found ) { if ( /^Sub/../^End/) { if ( /^\s*(.*)\s=\s(.*)/ ) { if ( $1 eq "Action") { ($left_val, $right_val ) = split ( /: /, $2 ); if ( defined $right_val ) { $new_href->{ $right_val } = undef; push @new_actions, ('Name = '. $right_val +); }; #else { print "Not defined\n" }; } elsif ( $1 eq "Text") { if (defined $right_val) { $new_href->{ $right_val } = $2; } else { $new_href->{ $2 } = $2 }; } } } last if ( /Main/ ); } } # Checking... # print "new actions : @new_actions\n"; return $new_href, \@new_actions; }
Output looks as follows:-
--------------------- Name = NA Name = EU --------------------- NA = North America EU = Europe --------------------- SEARCH STRING: Name = NA US = United States CA = Canada MX = Mexico SEARCH STRING: Name = EU Italy = Italy France = France $VAR1 = { 'World' => { 'Europe' => { 'France' => undef, 'Italy' => undef }, 'North America' => { 'Mexico' => undef, 'United States' => undef, 'Canada' => undef } } };
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: Building hash tree from a data file
by graff (Chancellor) on Jul 12, 2006 at 05:11 UTC |