Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Processing Multilevel Hash

by beginr (Novice)
on Dec 15, 2006 at 09:54 UTC ( [id://590002]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, I have a tree like data structure which depth will vary.
$hash = 'Country'; $VAR2 = { 'State1' => [ '1', '9.4495', '97.1521', '22.0331' ], 'State2' => [ '1', '98.6315', '55.2082', '40.8162', '47.5309' ] }; $VAR3 = 'Country1'; $VAR4 = { 'State1' => [ '1', '6.4491', '153.8922', '118.5463', '61.8858', ], 'State2' => [ '1', '274.0563', ] };
The depth level will vary ie the state level key may be further drilled down to city.

$hash = 'Country'; $VAR2 = { 'State1' =>{ 'city'=> [ '1', '9.4495', '97.1521', '22.0331' ] } }
I have to get the process the hash and produce all the keys and sum of the array values.

Can anybody help me on this?.

Tnks

Replies are listed 'Best First'.
Re: Processing Multilevel Hash
by jonadab (Parson) on Dec 15, 2006 at 13:24 UTC

    Ah, this makes much more sense than the multilevel-hash question we saw the other day. The data here have obvious meaning. (Well, the keys do. I still don't know what the numbers are, but you said you want to sum them, so that's a clear objective.)

    Your question has one thing in common with that one, though: we don't know ahead of time how deep the structure will go, and it can go deeper in some places than others. So you want to use a recursive solution, checking at each step whether what you've got is an array reference or a hash reference or what. Something like the solution I gave in that thread, only you want to sum the values instead of just printing them. Something along these lines:

    my %country= ( 'United States' => { Ohio => { 'Franklin County' => { Columbus => [1, 3.14159, 2.71828], Delaware => [2, 3, 5, 7, 11, 13], }, 'Crawford County' => { Galion => [419, 468, 1708], }, 'Summit County' => [1.59, 2.78, 3.62], }, Iowa => [1.9999, 3], }, 'Jamaica' => [ 4.512, 1.8, 3], ); recursivelyprintsum(0, World => \%country); sub recursivelyprintsum { my ($level, $label, $data) = @_; if (ref $data eq 'ARRAY') { my $value; $value += $_ for @$data; print "\t" x $level; print "$label:\t$value\n"; return $value; } elsif (ref $data eq 'HASH') { print "\t" x $level; print "$label:\n"; my $subtotal; foreach my $unit (keys %$data) { $subtotal += recursivelyprintsum($level + 1, $unit, $$data{$unit +}); } print "\t" x $level; print "$label total:\t$subtotal\n"; return $subtotal; } else { # $data must actually be $datum. print "\t" x $level; print "$label:\t$data\n"; return $data; } }

    Please note that if this is a homework assignment, and you turn in my code as it stands without understanding it, the prof will know you didn't write it yourself, because I've done some things a beginning programmer would not think to do (not in terms of the overall flow of how it works, but in the details). You should use my code as an example, try to understand how it works, and then try to make your code do the same thing. If it's for work, rather than school, then you can copy my code (your boss is unlikely to care), but you still should try to understand it.


    Sanity? Oh, yeah, I've got all kinds of sanity. In fact, I've developed whole new kinds of sanity. You can just call me "Mister Sanity". Why, I've got so much sanity it's driving me crazy.
Re: Processing Multilevel Hash
by themage (Friar) on Dec 15, 2006 at 10:05 UTC
    hi beginr,

    What result would you expect? If your State have cities, do you want a total for each city or just for the state? Or both?

    Which would you expect as result for your example with State1=>city=>[]?

    TheMage
    Talking Web
      I would like a output like this .
      country=>state1=>city1=>[]; country=>state2=>city2=>[]; . . country2=>state1=>city1=>[]; . .
      Idea is i have to traverse from top to bottom and get all the keys and the array.
Re: Processing Multilevel Hash
by l.frankline (Hermit) on Dec 15, 2006 at 11:58 UTC

    Hi

    Try this...if my guess is right

    %Country= ( 'State1' =>{ 'city'=> [ '1', '9.4495', '97.1521', '22.0331' ] } ); foreach my $state (keys %Country) { foreach my $city (keys %{$Country{$state}}) { for my $c (@{$Country{$state}{$city}}) { print $c; } } }

    bye

    Don't put off till tomorrow, what you can do today.

Re: Processing Multilevel Hash
by leocharre (Priest) on Dec 15, 2006 at 15:22 UTC

    Check out Abigail's Geography::States It's pretty cool

    Yes indeed! It is lacking the cities isn't it? My point/suggestion is.. This seems to be statistical data? Maybe having this be a static thing is not the best idea in the long run. Maybe this data (if it's statistical, could be turned into a living breathing module that mines the data.

    Of course, maybe this is way off your interests.

    Aside from that- This looks to me like an interesting bunch of calculations, if this is not throwaway code (or what it does is not just a hack but a long term need fulfillment)- consider porting some of this into a module, or placing some subroutines aside that you can organize yourself.

    If the data changes- the way of recreating the data is very important.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://590002]
Approved by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-03-28 22:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found