Re: Unknown level of hash
Alexandre Jousset <[email protected]>
| Newsgroups | gmane.comp.lang.perl.fun |
|---|---|
| Message-ID | <[email protected]> |
Hello,
Andrew Pimlott wrote:
> If you're feeling functional,
>
> ${fold_left(sub { \${$_[0]}->{$_[1]} }, \$hash, @a)} = 1;
>
> To get the value back out:
>
> fold_left { $_[0]->{$_[1]} } $hash, @a;
>
> Here is fold_left:
>
> sub fold_left (&@) {
> my $sub = shift;
> my $acc = shift;
>
> for my $each (@_) {
> $acc = $sub->($acc, $each);
> }
>
> return $acc;
> }
With your help, I found an almost-one-liner with a loop to do that :
use Data::Dumper;
@a = qw/a b c d/;
@b = qw/a 2 3 4/;
%hash = ();
# Preparation
$acc = \%hash;
$last = pop @a;
# Do the assignment
${ $acc = ($acc->{$_} ||= {}) for @a; \$acc }->{$last} = 1;
# Test on another array/value
$acc = \%hash;
$last = pop @b;
${ $acc = ($acc->{$_} ||= {}) for @b; \$acc }->{$last} = 2;
print Dumper(\%hash);
But it could probably be written shorter.
> (You should be able to write the first one as
>
> ${fold_left { \${$_[0]}->{$_[1]} } \$hash, @a} = 1;
>
> but Perl complains for no reason I can see.)
Of course, the '{}' operator is a hash ref generator, not an anonymous
sub declarator as 'sub {}' is...
A+
--
\^/
-/ O \----------------------------------------
| |/ \| Alexandre (Midnite) Jousset |
-|___|----------------------------------------