Функционально, как это?
my %orig = ( 1 => 'a', 2 => 'b', 3 => 'c', 65 => 'a' );
my $new_hash = List::Util::reduce { push @{ $a->{$orig{$b}} }, $b; $a } {}, keys %orig;
По какой-то причине завершение вызова приведения в разыменование хеша, похоже, нарушает магию & -prototype, но вы можете избежать новой переменной:
%orig = %{ List::Util::reduce sub { push @{ $a->{$orig{$b}} }, $b; $a }, {}, keys %orig };
Если вы хотите избежать внутренней ссылки на% orig, скажите, если исходный хеш-результат является результатом какого-то другого выражения, притвориться, что perl имеет pairlists:
%orig = %{ List::Util::reduce sub { push @{ $a->{ $b->[0] } }, $b->[1]; $a }, {},
@{ List::Util::reduce sub { ! @$a || $#{ $a->[-1] } ? push @$a, [ $b ] : push @{ $a->[-1] }, $b; $a }, [],
reverse %orig
}
};
красивее с некоторыми полезными функциями:
sub flatten_hashref { %{$_[0]} }
sub flatten_arrayref { @{$_[0]} }
sub pairlist { reduce { ! @$a || $#{ $a->[-1] } ? push @$a, [ $b ] : push @{ $a->[-1] }, $b; $a } [], @_ }
%orig =
flatten_hashref
reduce { push @{ $a->{ $b->[0] } }, $b->[1]; $a } {},
flatten_arrayref
pairlist
reverse
%orig;