Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
If your hash structure is always HoHoHo... -- i.e. no arrays, just hashes -- then the first trick you need to nail down is a way to distinguish between terminal nodes and non-terminal nodes in your tree.

Based on your examples, I'd guess that the easiest way to do this is by using your actual strings only as hash keys, never as values assigned to keys. The value of a hash element would always be a hash ref; non-terminal nodes would contain hash refs with one or more keys, whereas a terminal node would contain an empty hashref. The point here is that hash value is either a simple scalar or else it's a reference -- it can't be both.

Here's a way you could take hyphen-delimited strings to create an abitrarily deep / arbitrarily wide tree structure:

use strict; use warnings; use Data::Dumper; sub load_hash { my ( $href, $path ) = @_; my @path = split /-/, $path; my $key = shift @path; while ( @path and exists( $$href{$key} )) { $href = $$href{$key}; $key = shift @path; } if ( ! exists( $$href{$key} )) { # there's a new key in this path $$href{$key} = {}; # so create a new hashref for it load_hash( $$href{$key}, join( "-", @path )) if ( @path ); # recurse if this key/node is non-terminal } # otherwise, do nothing -- the path already exists in the structure } sub trace_paths # look for paths to a chosen node (hash key) { my ( $href, $aref, $node, $path ) = @_; $path ||= ''; my @keys = keys %$href; if ( grep /^$node$/, @keys ) { push @$aref, ( $path ) ? "$path-$node" : $node; } for my $key ( @keys ) { my $nxt_path = ( $path ) ? "$path-$key" : $key; trace_paths( $$href{$key}, $aref, $node, $nxt_path ) if ( scalar keys %{$$href{$key}} ); } } my @strings = qw/one-foo-bar-baz one-foo-zuz two-fump-zill two-fizz-foo/; my %hash; load_hash( \%hash, $_ ) for ( @strings ); print Dumper( \%hash ); my @found; trace_paths( \%hash, \@found, 'foo' ); print Dumper( \@found );
(updated to fix an annoying initial dash in @found values)

Now, if you really want the structure to hold scalar values as well as hash keys, you'll need to reserve one or more "special keys" that you can use for storing strings or numbers instead of lower-level hash refs. These special keys need to be strings that will never occur as data (nodes in the structure), and the load_hash and/or trace_paths subs would need an extra line or two of code to use them as needed.


In reply to Re: seeking in hash data structure by graff
in thread seeking in hash data structure by Maze

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others rifling through the Monastery: (4)
    As of 2014-09-20 08:49 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      How do you remember the number of days in each month?











      Results (157 votes), past polls