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 没有它:

arg 1 到值的类型必须是 script\workbench.pl 第 55 行“@obs ;”附近的哈希(不是映射迭代器)

4

2 回答 2

7

问题是,values真的,真的想要一个散列来操作。那是因为它很特别:它清除了each. 它需要一个实际的对象来清除它。

您可以在这里采取两种方式之一。首先,如果您不喜欢 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要处理一个列表,它将占用该列表的每个第二个元素。所以

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

将会

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

现在,完全可以编写这样的函数,但在这种情况下根本不需要。一个人可以简单地做

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

这简化为

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

一个问题:不使用散列,你不会消除重复。

于 2011-04-07T06:24:22.730 回答