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      |
 -|___|----------------------------------------
    • ... Alexandre Jousset
      • ... Суханов Вадим
        • ... Alexandre Jousset
  • ... Ton Hospel
    • ... Yitzchak Scott-Thoennes
  • ... Yitzchak Scott-Thoennes
    • ... Alexandre Jousset
      • ... Yitzchak Scott-Thoennes
        • ... Alexandre Jousset
  • ... Andrew Pimlott
    • ... Alexandre Jousset
      • ... Andrew Pimlott
        • ... Alexandre Jousset
          • ... Alexandre Jousset
            • ... Andrew Pimlott
  • ... Zhuang Li
    • ... Jeff Yoak
    • ... Markus Laire
    • ... Luke Palmer
  • ... Zhuang Li
  • ... Zhuang Li

Reply via email to