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      |
  -|___|----------------------------------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.