Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

How to flatten hashes?

by hoppfrosch (Scribe)
on Jul 14, 2005 at 07:22 UTC ( [id://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?Last hourOther CB clients
Other Users?
Others about the Monastery: (5)
As of 2024-03-28 15:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found