perlのハッシュでキーと値を入れ替えて新しいハッシュを作成したい。これは、重複する値のキーが配列に入れられるように行われることに注意してください。これはreverse
とは異なります。perlのハッシュでスワッピングキーと値を書き込む最もコンパクトな方法
私は明らかにこのためのループを行うことができます。しかし、私はそれがmap
などを使用してコンパクトな形で行うことができるかどうかはわかりません。
ありがとう。
perlのハッシュでキーと値を入れ替えて新しいハッシュを作成したい。これは、重複する値のキーが配列に入れられるように行われることに注意してください。これはreverse
とは異なります。perlのハッシュでスワッピングキーと値を書き込む最もコンパクトな方法
私は明らかにこのためのループを行うことができます。しかし、私はそれがmap
などを使用してコンパクトな形で行うことができるかどうかはわかりません。
ありがとう。
このような "コンパクト"ループを実行できます。
my %orig = # whatever
my %rev;
push @{$rev{$orig{$_}}}, $_ for keys %orig;
「反転」ハッシュのすべての値は、この配列になります。
ありがとうございます。それは基本的に私がループアプローチで言ったことです。私が尋ねようとしているのは、 '%orig = map {$ orig {$ _} => $ _}のように新しいハッシュを宣言したり、 orig); '? –
私には分かりません。新しいハッシュを宣言することであなたの問題は何ですか? – Mat
機能性?ハッシュデリファレンスで減らすの呼び出しをラップするいくつかの理由
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 = %{ 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
}
};
きれい:いくつかの他の発現からの結果は、Perlをふり元ハッシュpairlistsを有する場合%の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;
「コンパクト」を定義します。なぜこれが賞賛できる目標であるか教えてください。短いと読めない私の評点の本のポイントを失う。 – tchrist
@tchrist:私は、「より機能的な」と言っていました。私は明示的なループを避けることは、matlab、R、python、perlのような言語でいくつかの効率を得ることができると信じています。たぶんすべての場合ではないかもしれませんが、一般的には真です。私は正しい? –
いいえ、正しくはありません。それが効率のためではなく、あなたにとって理にかなったコードを作るなら、それを行います。 – ysth