Module for getting values from "flattened" hash or "recursed" hash...?

Discussion in 'Perl Misc' started by newsbot@cox.net, Mar 9, 2005.

  1. Guest

    I've search high and low in CPAN for a hash module to do the following,
    as I describe here. With all the MANY hash modules out there, it's
    hard to believe someone hasn't written at least something similar.

    Given the following sample hash (reference(s)):

    $h = {
    'group1' => {
    'green' => 'This is green',
    'blue' => 'This is blue',
    'gray' => {
    'orange' => {
    'pink' => 'This is gray-orange-pink (yuk!)',
    'black' => 'This is gray-orange-black (eh...)'
    },
    'red' => 'This is gray-red',
    'label' => 'This is a gray label',
    'yellow' => 'This is gray-yellow'
    },
    'red' => 'This is red'
    }
    };

    If I say "$rv = giveme( $h, 'green' );" where "giveme()" is some
    hypothetical function, then I want $rv to receive "This is green". If
    I say "($a,$b,$c) = giveme( $h, 'blue', 'pink', 'red' );" then I want
    to receive "This is blue", "This is gray-orange-pink", and "This is
    red" in return.

    Notice that for "red", the {group1}->{red} takes precedence over the
    {group1}->{gray}->{red}. The return context of scalar versus array
    isn't as important -- I merely illustrate this way for sake of brevity
    since "giveme()" is hypothetical -- the subject of my posting. Also,
    the return of {group1}->{gray} is undefined, as is
    {group1}->{gray}->{orange}, etc.

    The Tie::proxy::Hash and Tie::Flatten modules are *close* to what I
    want, but aren't exact. I could use either or both of them to perhaps
    "massage" what I want, but I'd rather just write it myself if it
    doesn't exist as above.

    In the application which requires this functionality, I can virtually
    guarantee that keys in the hash "tree" will be unique -- which lends
    itself to a "flatten" namespace. But not always as in the case of
    "red" above where {group1}->{red} takes precedence.

    If anyone knows of a module to do this, I'd appreciate hearing about
    it. I've searched Google and CPAN high and low...

    -ceo
    , Mar 9, 2005
    #1
    1. Advertising

  2. * wrote:
    >
    > Given the following sample hash (reference(s)):
    >
    > $h = {
    > 'group1' => {
    > 'green' => 'This is green',
    > 'blue' => 'This is blue',
    > 'gray' => {
    > 'orange' => {
    > 'pink' => 'This is gray-orange-pink (yuk!)',
    > 'black' => 'This is gray-orange-black (eh...)'
    > },
    > 'red' => 'This is gray-red',
    > 'label' => 'This is a gray label',
    > 'yellow' => 'This is gray-yellow'
    > },
    > 'red' => 'This is red'
    > }
    > };
    >
    > If I say "$rv = giveme( $h, 'green' );" where "giveme()" is some
    > hypothetical function, then I want $rv to receive "This is green". If
    > I say "($a,$b,$c) = giveme( $h, 'blue', 'pink', 'red' );" then I want
    > to receive "This is blue", "This is gray-orange-pink", and "This is
    > red" in return.
    >
    > Notice that for "red", the {group1}->{red} takes precedence over the
    > {group1}->{gray}->{red}.


    But if your hash looks like

    $h = {
    'green' => { 'blue' => 'this is turquoise' }
    'red' => { 'blue' => 'this is lilac' }
    }

    which 'blue' you're expecting, the greenish or the reddish one? ;-)

    >
    > The return context of scalar versus array
    > isn't as important -- I merely illustrate this way for sake of brevity
    > since "giveme()" is hypothetical -- the subject of my posting. Also,
    > the return of {group1}->{gray} is undefined, as is
    > {group1}->{gray}->{orange}, etc.


    What you really want is a simple postorder traversal for your hash to
    search for the given colors. I haven't looked at CPAN yet if there's
    such a modul for traversing hashes, but with a stack for pushing your
    sub-hashes onto, your sub could look like:


    sub giveme {
    my @stack = shift;
    my %color;

    while ( @stack ) {
    my( $key, $value ) = each %{$stack[0]}
    or shift( @stack ), next;
    ref( $value ) eq 'HASH'
    and push( @stack, $value ), next;
    $color{$key} ||= $value;
    }

    return @color{ @_ };
    }


    regards,
    fabian
    Fabian Pilkowski, Mar 9, 2005
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. rp
    Replies:
    1
    Views:
    478
    red floyd
    Nov 10, 2011
  2. Alex Fenton

    Hash#values and Hash#keys order

    Alex Fenton, Apr 7, 2006, in forum: Ruby
    Replies:
    1
    Views:
    124
    George Ogata
    Apr 15, 2006
  3. Mage

    hash.keys and hash.values

    Mage, Aug 13, 2006, in forum: Ruby
    Replies:
    14
    Views:
    163
  4. Ronald Fischer

    Hash#keys, Hash#values order question

    Ronald Fischer, Aug 23, 2007, in forum: Ruby
    Replies:
    0
    Views:
    140
    Ronald Fischer
    Aug 23, 2007
  5. Tore Aursand
    Replies:
    3
    Views:
    545
    Anno Siegel
    Sep 16, 2003
Loading...

Share This Page