5

私はハッシュの配列を持っています。別のキーの一意性に基づいて、これらのハッシュのキーの値のリストが必要です。

my @obs = ({
   value => 'three',
   id => 3
},{
   value => 'one-2',
   id => 1
},{
   value => 'one',
   id => 1
});
# This works, prints "one\nthree"
say for values %{{ map { $_->{id} => $_->{value} } @obs }};

の周りの参照 + 逆参照ビットを回避できますmapか? values最初は、リターン時に直接呼び出してみましたmapが、Perl にはありません:

script\workbench.pl の 55 行目の "@obs ;" の近くで、引数 1 から値への型はハッシュ (マップ イテレータではない) である必要があります。

4

2 に答える 2

7

問題は、values実際にハッシュを操作したいということです。それは特別だからです: によって使用されるプレースホルダーをクリアしますeach。それをクリアするには、実際のオブジェクトが必要です。

ここでは、2 つの方法のいずれかを実行できます。まず、ref/deref が気に入らない場合は、ワンライナーから一時ハッシュの作成を引き出すことができ%hます (実際のコードよりも適切な名前を選択してください)。

my %h = map { $_->{id} => $_->{value} }  @obs;
say for values %h;

%hぶらぶらしたくない場合は、一時ブロックにドロップしてください。

...code code code...
{
    my %h = map { $_->{id} => $_->{value} }  @obs;
    say for values %h;
}
...code code code...

別のアプローチは、一時的なハッシュの作成と実行をエミュレートすることvaluesです。

my %seen;
for ( reverse @obs ) { say $_->{value} unless $seen{$_->{id}}++ }

本当に重要なのは、このデータをどうするかです。逆ハッシュの値が一度だけ必要な場合は、ワンライナーが最適なソリューションになる可能性があります。後でこのデータ (id と値) が必要な場合は、実際のハッシュを作成して使用します。この変換は、ワンライナーとして保持できるようにするためだけに複数回実行しないでください。

詳細なコンテキストがなければ、どのアプローチを取るべきかについてアドバイスを与えることは困難です。

于 2011-04-06T01:28:28.613 に答える
0

リストで作業する場合values、そのリストの1つおきの要素が必要になります。それで

say for values %{{ map { $_->{id} => $_->{value} } @obs }};

だろう

say for every_odd map { $_->{id} => $_->{value} } @obs;

さて、そのような関数を書くことは完全に可能ですが、この場合は単に必要ありません。簡単にできる

say for map { $_->{value} } @obs;

そしてそれは単純化して

say $_->{value} for @obs;

1つの落とし穴:ハッシュを使用しないことで、重複を排除することはできません。

于 2011-04-07T06:24:22.730 に答える