Re: hash of lists - hash of hashes
by chromatic (Archbishop) on Jun 13, 2000 at 04:43 UTC
|
I think this does what you want:
%hoh = map { $_, { map { $_, 1 } @{ $hol{$_}} } } keys %hol;
Here's what I used to test:
#!/usr/bin/perl -w
use strict;
my %hol = (
first => [ 1, 2, 3 ],
second => [ 2, 4, 6 ] );
my %hoh;
%hoh = map { $_, { map { $_, 1 } @{ $hol{$_}} } } keys %hol;
walk_hash(\%hoh);
sub walk_hash {
my $h_ref = shift;
my $indent = shift;
$indent ||= 0;
foreach my $key (keys %$h_ref) {
print "\t" x $indent, "$key => ";
my $value = $h_ref->{$key};
if (ref($value) eq 'HASH') {
print "\n";
walk_hash($value, $indent + 1);
} else {
print "\t" x $indent, "$value\n";
}
}
}
And, yes merlyn, you get a bonus hash-walking algorithm for free. It's two posts for the price of one here on Perl Monks (I will use Data::Dumper next time, I will use Data::Dumper next time...) | [reply] [d/l] [select] |
|
|
| [reply] |
Re: hash of lists - hash of hashes
by lhoward (Vicar) on Jun 13, 2000 at 04:03 UTC
|
This is the best that I've managed so far:
while (($k, $lref) = each %HoL){
$HoL{$k}={map {$_,1} @$lref};
}
I tried to get something along the lines of the following bit
of code to work but couldn't:
%HoL=map {map {$_,1} @HoL{$_}} keys %HoL;
I'm sure merlyn could blow this out of the water
(and I hope he does, I'd love to see his solution...
probably something really slick w/ 2 maps) | [reply] [d/l] [select] |
|
|
| [reply] |
clarification...
by visnu (Sexton) on Jun 13, 2000 at 04:26 UTC
|
for merlyn:
%HoL is a hash of lists.
i'd like to change it into a hash of hashes.
each contained, secondary hash would consist of keys from the members of the original list, with corresponding values of just '1'.
not sure if i can be more clear.. probably can; i'm just not good at it.
WAIT! pictures!!
i what to change this:
%HoL = ( fruits => "orange", "banana", "kiwi" ,
vegetables => "carrot", "potato" ,
cheeses => "cheddar", "american"
);
to this:
%HoH = ( fruits => { orange => 1, banana => 1, kiwi => 1 },
vegetables => { carrot => 1, potato => 1 },
cheeses => { cheddar => 1, american => 1}
);
| [reply] |
clarification...
by visnu (Sexton) on Jun 13, 2000 at 04:28 UTC
|
hmm, preview gets rid of my brackets.... to repeat,
i what to change this:
%HoL = ( fruits => [ "orange", "banana", "kiwi" ],
vegetables => [ "carrot", "potato" ],
cheeses => [ "cheddar", "american" ]
);
to this:
%HoH = ( fruits => { orange => 1, banana => 1, kiwi => 1 },
vegetables => { carrot => 1, potato => 1 },
cheeses => { cheddar => 1, american => 1}
);
| [reply] |
|
|
In place, you could do something like this:
for (@HoL{keys %HoL}) {
$_ = {map {$_, 1} @$_};
}
(You can use values in place of the slice in 5.6, but I'm not there yet.)
If you really need a copy, that's a little odder, like this:
%HoH = map { $_ => {map { $_, 1 } @{$HoL{$_}}} } keys %HoL;
Untested, but I think I got my indirections right.
-- Randal L. Schwartz, Perl hacker | [reply] [d/l] [select] |
extended problem
by visnu (Sexton) on Jun 13, 2000 at 05:02 UTC
|
in case anyone wanted something to think about instead of other work, the original (extended) problem i want to solve was to suppose those lists contained other hash keys.. so now the problem is such:
%HoL = ( bob => [ "mary", "ken" ],
aditya => [ "cary", "bob" ],
devil => [ "bob", "aditya" ]
);
and i then finally want:
%HoL = ( bob => { mary => 1, ken => 1 },
aditya => { cary => 1, bob => 1, mary => 1, ken => 1 },
devil => { bob => 1, mary => 1, ken => 1, aditya => 1, cary => 1 }
)
so now everything shows itself readily when we use the hash, or something like that.
and of course, one shouldn't get into a recursive loop, etc, blah blah blah
| [reply] |
|
|
| [reply] |
|
|
this is actually what i finally came up with:
my ($key, $value, $len);
while (($key, $value) = each %HoL)
{
my $href = $HoL{$key} = { map {$_, 1} @$value };
do
{
$len = keys %$href;
for (@HoL{@$value})
{
if (ref eq "HASH" ) { @$href{keys %$_} = (1) x (keys %$
+_) }
elsif (ref eq "ARRAY") { @$href{@$_} = (1) x @$_ }
}
$value = [ keys %$href ];
}
while (@$value > $len);
}
it's iterative no less. any comments? | [reply] [d/l] |
|
|
on second run, this code is crack-headed. it ends up modifying the top level hash that it's iterating over and runs into bad stuff.
| [reply] |
|
|
note: that's me forgetting to login, up there posting..
| [reply] |