Limo has asked for the wisdom of the Perl Monks concerning the following question:
Well, if this question doesn't get me banned, then I've found a home. I am STILL having the same problem, although, I can probably ask a more specific question. So, here goes:
%hash1
%hash2
%hash3
%hash4
all have identical keys, different values. Each hash is populated in a different subroutine. I would like (need!) to print the contents as shown:
key 1
value key 1, hash 1
value key 1, hash 2
value key 1, hash 3
value key 1, hash 4
key 2
value key 2, hash 1
value key 2, hash 2
value key 2, hash 3
value key 2, hash 4
etc.........
I know that I have referred to this problem in previous posts, but I ask again, because I am pretty desperate at this point, AND I think that I am presenting the question in a more concise manner. Could some kind monk lend a hand?
Re: Hash Nightmare
by swiftone (Curate) on Oct 06, 2000 at 21:10 UTC
|
I'll expound on merlyn's comments.
To use your data structures, you can do this:
#create list of hashes
my @allhashes = ( \%hash1, \%hash2, \%hash3 );
#note the following assumes all keys exist and are the same
#keys are not sorted in this example
foreach my $key (keys %hash1) {
print "key $key\n";
foreach my $hash (@allhashes) {
print "Value: $hash->{$key}\n";
}
}
The better way to do it, as merlyn said, is to create your nested data structure from the top.
Rather than creating (N) different hashes with the same keys, create a list of hash references (just like @allhashes above), and populate that
with whatever method you are populating your hashes with now.
Re-Update: Deleted a bunch of stuff that I thought was relevant, but wasn't.
| [reply] [d/l] |
(tye)Re: Hash Nightmare
by tye (Sage) on Oct 06, 2000 at 21:53 UTC
|
my $devs= hashjoin( {
version=>\%vers, module=>\%mod, memory=>\%mem } );
sub hashjoin {
my( $in )= @_;
my $out= {};
for my $attrib ( keys %$in ) {
for my $item ( keys %{ $in->{$attrib} } ) {
$out->{$item}->{$attrib}= $in->{$attrib}->{$item};
}
}
return $out;
}
I could factor that a little differently but I chose this way because I'm not assuming that all of your hashes actually do have the exact same keys and I didn't feel like checking that assumption.
Here is yet another case where I really want my "dereference an entire list at a time" operators. Then I could replace that middle loop with:
$out->@{ keys $in->{$attrib}->% }-->{$attrib}=
values $in->{$attrib}->%;
and it would make it easier for you to build your hashes this way from the beginning. (And, no, that last bit of code isn't valid Perl -- it is what I wish Perl supported: -->, ->%, ->@, ->@{}, ->@[], ->$, etc.)
I'd love to see an elegant method for generating the data in the format that merlyn suggested from the beginning, if each attribute is gathered from a different subroutine.
-
tye
(but my friends call me "Tye") | [reply] [d/l] [select] |
Re: Hash Nightmare
by elusion (Curate) on Oct 06, 2000 at 21:07 UTC
|
@keys = ("key1","key2,"key3","key4");
foreach $key (@keys) {
print "$key\n";
print "$hash1{$key} , \$hash1\n";
print "$hash2{$key} , \$hash2\n";
print "$hash3{$key} , \$hash3\n";
print "$hash4{$key} , \$hash4\n\n";
}
I think this should work. But no guarentees.
- p u n k k i d
"Reality is merely an illusion,
albeit a very persistent one."
-Albert Einstein | [reply] [d/l] |
|
All the keys in each hash are the same so couldn't you do the following:
foreach (keys %hash1) {
... # here you would use $_ as the variable for the keys
}
This eliminates the creation of the @keys and $key variables. Hope that helps.Zenon Zabinski | zdog | zdog7@hotmail.com
| [reply] [d/l] |
RE: Hash Nightmare
by Limo (Scribe) on Oct 06, 2000 at 21:22 UTC
|
%hash 1
keys = device names
values = software version
%hash 2
keys = device names
values = "module 1\n module 2 \n......."
%hash 3
keys = device names
values = either "$pub" or "$prv", depending upon device
%hash 4
keys = device names
values = amount of memory
For each device, I want to print:
"device name"
"==========="
"software version"
"module 1"
"module 2"
"module 3....."
"public": ($pub, if defined)
"private": ($prv if defined)
"amount of memory"
Does this help?
| [reply] [d/l] [select] |
|
Restructure your data so you have:
%device_info = (
device1 => { version => '1.4', module => [1, 2, 3], memory => '18k'
+},
device2 => { version => '1.4', module => [4,5,6], memory => '25k' },
device3 => { version => '1.2', module => [7,8,9], memory => '18k' },
);
Then it's easy to do operations in parallel. Having upside-down data structures
is nasty.
-- Randal L. Schwartz, Perl hacker | [reply] [d/l] |
|
| [reply] |
|
As I am relatively new to Perl, I have no idea what merlyn was talking about.
| [reply] |
|
|
Re: Hash Nightmare
by merlyn (Sage) on Oct 06, 2000 at 21:01 UTC
|
| [reply] |
|
|