[Phoenix-pm] Multi-level hash - quick key reference?

Metz, Bobby W, WWCS bwmetz at att.com
Wed Jun 7 13:03:16 PDT 2006


Brock,
	May have to give yours a go after all...just dawned on me that
flattening the index will significantly increase storage due to the
duplication of index characters.  Some could have several thousand
values so if it were say six keys deep times a thousand values, it would
add up over time.

Bobby

-----Original Message-----
From: phoenix-pm-bounces+bwmetz=att.com at pm.org
[mailto:phoenix-pm-bounces+bwmetz=att.com at pm.org]On Behalf Of Metz,
Bobby W, WWCS
Sent: Wednesday, June 07, 2006 1:00 PM
To: Brock
Cc: phoenix-pm at pm.org
Subject: Re: [Phoenix-pm] Multi-level hash - quick key reference?


Thanks Brock.  
	After sending that message I thought about flattening it as
well...a big resounding "Duh" escaped my lips I must admit.  I
considered eval but quickly squashed that idea.  I should have thought
of a shift method...so thanks, I like that.  I think I need to study the
data source some more as flattening will likely be the simplest method
since each index will have at most two values.  I oversimplified a bit
on the example.

$hash{.1.2.3.4}{name} & $hash{.1.2.3.4}{value}

And since the names will never change, I'll likely just have one hash
for those and an array of hashes for the values.

Thanks for the quick response...very much appreciated.

Bobby

-----Original Message-----
From: Brock [mailto:awwaiid at thelackthereof.org]
Sent: Wednesday, June 07, 2006 12:52 PM
To: Metz, Bobby W, WWCS
Cc: phoenix-pm at pm.org
Subject: Re: [Phoenix-pm] Multi-level hash - quick key reference?


Heres a couple ideas. One, you could just flatten your hash -- use

  $hash->{1.2.3} = "Hello World";
  $hash->{1.2.3.4.5} = "the quick brown fox";

but, failing that,

use strict;
my $hash = {};
my $str = ".1.2.3\tHello World";
my ($nums,$text) = split /\t/,$str;
my @indexes = split /\./, $nums;
shift @indexes; # Get rid of the first ""
my $cur = $hash;
while(@indexes) {
  my $index = shift @indexes;
  if(!@indexes) { # this is the last one
    $cur->{$index} = $text;
  } else {
    # We might need to vivify
    $cur->{$index} = {} unless defined $cur->{$index};
    $cur = $cur->{$index};
  }
}
use Data::Dumper;
print "Result: " . Dumper($hash) . "\n";

might help. Simplification, anyone? I suppose you could use evil, er,
eval.

--Brock

On 2006.06.07.14.31, Metz, Bobby W, WWCS wrote:
| All,
| 	I'm looking for a quicker method of accessing elements in a
multi-level hash.  For example, the hash will have values like so
| 
| $hash{1}{2}{3} = "Hello World";
| $hash{1}{3}{4}{5} = "the quick brown fox";
| 
| The input to the program comes from another I can't control which will
ouput values like so:
| 
| .1.2.3<tab>Hello World
| .1.3.4.5<tab>the quick brown fox
| 
| Parsing the values is cake, but what I'm looking for is a faster way
to get values in/out of the hash using the ".1.2.3".  Is there some
method that allows for arbitrary hash levels without coding using for
loops?  I mean clearly recursion would solve this but I was hoping there
was something more simple.  Or is recursion the only answer.  I was
hoping for something like this, but I know this example doesn't work.
I've searched for a bit but I must be asking the right questions of
mighty google.
| 
| $index = ".1.2.3";
| $index =~ s/^\.//g;
| $index =~ s/\./}{/g;
| print $hash{$index} . "\n";
| 
| Thoughts?
| 
| Thanks,
| 
| Bobby
| _______________________________________________
| Phoenix-pm mailing list
| Phoenix-pm at pm.org
| http://mail.pm.org/mailman/listinfo/phoenix-pm
_______________________________________________
Phoenix-pm mailing list
Phoenix-pm at pm.org
http://mail.pm.org/mailman/listinfo/phoenix-pm


More information about the Phoenix-pm mailing list