Преобразование HoA в HoH с подсчетом

Иметь этот код:

use 5.020;
use warnings;
use Data::Dumper;

my %h = (
    k1 => [qw(aa1 aa2 aa1)],
    k2 => [qw(ab1 ab2 ab3)],
    k3 => [qw(ac1 ac1 ac1)],
);

my %h2;
for my $k (keys %h) {
    $h2{$k}{$_}++ for (@{$h{$k}});
}
say Dumper \%h2;

производит:

$VAR1 = {
          'k1' => {
                    'aa2' => 1,
                    'aa1' => 2
                  },
          'k3' => {
                    'ac1' => 3
                  },
          'k2' => {
                    'ab1' => 1,
                    'ab3' => 1,
                    'ab2' => 1
                  }
        };

Можно ли написать приведенный выше код "другим способом"? (например, проще или компактнее)?

1 ответ

Решение

Честно говоря, я не люблю количество раз $h2{$k} оценивается.

my %h2;
for my $k (keys %h) {
   my $src = $h{$k};
   my $dst = $h2{$k} = {};
   ++$dst->{$_} for @$src;
}

Подпрограмма может помочь сделать намерение более очевидным. Может быть.

sub counts { my %c; ++$c{$_} for @_; \%c }

$h2{$_} = counts(@{ $h{$_} }) for keys %h;

Это может быть упрощено, если вы сделаете изменение на месте.

sub counts { my %c; ++$c{$_} for @_; \%c }

$_ = counts(@$_) for values %h;
Другие вопросы по тегам