Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

How to flatten hashes?

by hoppfrosch (Scribe)
on Jul 14, 2005 at 07:22 UTC ( #474783=perlquestion: print w/replies, xml ) Need Help??

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

Hi all,

I'm looking for a simple way to "flatten" hashes.
For example I have a hash that looks like this:
accesslevels' => { 'function' => { 'func1' => { 'content' => 'val1' }, 'default' => { 'content' => 'val2' } } }
What's the easiest (most elegant) way to remove the 'function' and the 'content' so that I get something like:
accesslevels' => { 'func1' => 'val1' 'default' => 'val2' }

Thanks

Hoppfrosch

Replies are listed 'Best First'.
Re: How to flatten hashes?
by rev_1318 (Chaplain) on Jul 14, 2005 at 08:09 UTC
    If your hash is all you show us, you can simply say:
    my %newhash = ( accesslevels => { func1 => $oldhash{function}{func1}{content}, default => $oldhash{function}{default}{content} } );
    But if it is more generic (which I'm guessing it is), a possible approach can be:
    my %newhash; foreach my $key1 (keys %oldhash) { foreach my $key2 (keys %{$oldhash{$key1}}) { foreach my $key3 (keys %{$oldhash{$key1}{$key2}}) { $newhash{$key1}{$key3} = $oldhash{$key1}{$key2}{$key3}{con +tent} } } }
    HTH

    Paul

Re: How to flatten hashes?
by dirac (Beadle) on Jul 14, 2005 at 08:03 UTC
    #!/usr/bin/perl -w use strict; use Data::Dumper; my %a = ('accesslevels' => { 'function' => { 'func1' => { 'content' => 'val1' }, 'default' => { 'content' => 'val2' } } } ); my %b = map { $_, { func1 => $a{$_}{function}{func1}{content} , default => $a{$_}{function}{default}{content} } } keys %a; print Dumper(%a); print Dumper(%b);
    Update:
    This works for generic hash with the same structure.
    Try with ...
    my %a = ('accesslevels' => { 'function' => { 'func1' => { 'content' => 'val1' }, 'default' => { 'content' => 'val2' } } } , 'accesslevels1' => { 'function' => { 'func1' => { 'content' => 'val3' }, 'default' => { 'content' => 'val4' } } } , 'accesslevels2' => { 'function' => { 'func1' => { 'content' => 'val5' }, 'default' => { 'content' => 'val6' } } } , 'accesslevels3' => { 'function' => { 'func1' => { 'content' => 'val7' }, 'default' => { 'content' => 'val8' } } } , 'accesslevels4' => { 'function' => { 'func1' => { 'content' => 'val9' }, 'default' => { 'content' => 'val10' } } } , );
Re: How to flatten hashes?
by duelafn (Parson) on Jul 14, 2005 at 12:01 UTC

    Not sure this qualifies as more elegant, or just more obfuscated than rev_1318's solution.

    use YAML; my %h = ( 'accesslevels' => { 'function' => { 'func1' => { 'content' => 'val1' }, 'default' => { 'content' => 'val2' } } }, 'accesslevels2' => { 'function' => { 'func1' => { 'content' => 'val1' }, 'default' => { 'content' => 'val2' } } }); for my $L (values %h) { my (%tmp, $k, $v); for (values %$L) { $tmp{$k} = $$v{content} while ($k,$v) = each %$_; } $L = \%tmp; } print Dump \%h;

    Good Day,
        Dean

Re: How to flatten hashes?
by tlm (Prior) on Jul 14, 2005 at 13:13 UTC

    FWIW,

    use strict; use warnings; my %hash = ( accesslevels => { function => { func1 => { content => 'val1 +' }, default => { content => 'val2 +' } } } ); sub flatten { my $hash = shift; while ( my ( $k, $v ) = each %$hash ) { next unless ref $v eq 'HASH'; flatten( $v ); exists $v->{ $_ } and $hash->{ $k } = $v->{ $_ } for qw( function content ) } } use Dumpvalue; flatten( \%hash ); print Dumpvalue->new->dumpValue( \%hash ); __END__ 'accesslevels' => HASH(0x814cad4) 'default' => 'val2' 'func1' => 'val1'

    the lowliest monk

Re: How to flatten hashes?
by EvanCarroll (Chaplain) on Jul 14, 2005 at 20:50 UTC
    Because you mentioned "easiest":

    EXAMPLE HASH:
    my %foo = ( asdf => { foo => 'jkl' }, bar => { foo => 'func' }, );

    TRANSFORMATION CODE:
    map { $foo{$_} = $foo{$_}->{'foo'} } keys %foo;

    Evan Carroll
    www.evancarroll.com

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2023-04-01 09:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?