使用map提取匹配指定值的(key,value)哈希集

时间:2011-04-08 15:45:12

标签: perl map extraction

我一直在寻找使用perl函数map执行以下操作的方法: 给定哈希,我想提取值等于或匹配指定参数的对(键,值)。

在我的例子中,我想提取{key,value}对value = failed,但它也可以是一个表达式(即以A开头的字符串或REGEX)。这就是为什么我想要一个哈希值,而不仅仅是一个与值匹配的键表。

my %strings = (
    bla => "success",
    ble => "failed",
    bli => "failed",
    foo => "success",
    blo => "failed",
    bar => "failed",
    blu => "success"
);

my %failed_s = ();

while (my ($k, $v) = each %strings) {
    if ( $v eq 'failed' ) {$failed_s{$k} = $v};
};

我尝试了几种方法,但没有很好的结果,所以我觉得我对引用,矫揉造作,结果等感到困惑。

my %failed_s = 
    map { { $_ => $strings{$_} } 
    if ( $strings{$_}./failed/ ) } 
    keys %strings;
my %failed_s = 
    map { ( $strings{$_} eq 'failed') &&
          ($_, $strings{$_}) } 
    keys %strings;

print "Dumper \%failed_s: \n" . Dumper(\%failed_s);

在这种情况下,使用地图可能无效或无效,但它可以帮助我(可能还有其他人)知道原因。

4 个答案:

答案 0 :(得分:8)

Perl很容易获得散列逻辑,以至于很少有人能够将Key-Value Pair概念与其最常见的实现区分开来:Hash。

因此,当大多数Perlers考虑KVP时,他们会认为是“哈希”。但想想Perl Arrays的方式1)列表,2)队列,3)堆栈,你会发现实现并不完全等同于概念。

我看到需要以哈希之外的方式处理,所以我创建了自己的库,我打算将其上传到CPAN,直到我找到List::Pairwise为止。

(当然它似乎没有我的“哈希拼接”方法......)

无论如何,使用List::Pairwise,您只需

use List::Pairwise qw<grepp>;
my %failed_s = grepp { $b eq 'failed' } %strings;

当我说“看看它是多么简洁!”时,我觉得自己是一个电视购物的人。

答案 1 :(得分:6)

在第一个地图示例中,您将返回单个元素哈希引用,这不是您想要的。

在你的第二个中,&&运算符在其参数上强制使用标量上下文,因此列表($_, $strings{$_})仅返回列表中的最后一项。

您正在寻找的是:

my %failed_s = map {
    $strings{$_} eq 'failed' ? ($_, $strings{$_}) : () 
} keys %strings;

如果条件为真,? :运算符返回列表,如果为假,则返回空列表。

答案 2 :(得分:3)

map FUNC, LIST对LIST中的每个元素进行操作。你的函数可以为一些元素返回一个空列表(正如Eric Strom的答案所示)。另一种方法是使用另一个过滤器,以便map仅对您感兴趣的元素进行操作:

my %failed_s = map { 
    $_ => $strings{$_} 
} grep { $strings{$_} eq 'failed' } keys %strings;

答案 3 :(得分:3)

我认为地图+ grep组合更清晰。

my %failed_s =
   map { $_ => $strings{$_} }
   grep { $strings{$_} eq 'failed' }
   keys(%strings);

但是因为grep可以使用map实现,

my %failed_s =
   map { $_ => $strings{$_} }
   map { $strings{$_} eq 'failed' ? $_ : () }
   keys(%strings);

只需使用地图即可完成。

my %failed_s =
   map { $strings{$_} eq 'failed' ? ($_ => $strings{$_}) : () }
   keys(%strings);

他们遇到的问题是,当你打算不归还任何东西时,你会返回假。