如何使用map()将操作应用于Perl中哈希的每个元素?

时间:2009-10-22 05:14:32

标签: perl hash functional-programming map

我有一段工作正常的代码。它基本上使用foreach()循环遍历散列的每个元素,并使用正则表达式对其应用变换,如下所示:

foreach my $key ( keys( %{$results} ) ) {
   $results->{$key}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi;
}

$ results是DBI的fetchall_hashref()函数返回的hashref。

出于好奇,我想看看我是否可以使用map()重写它,如下所示:

map {
   $results{$_}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi
} keys %{$results};

不幸的是,这不起作用。我尝试了各种各样的东西,但到目前为止还没有成功。谁知道怎么做?感谢。

更新

已更正的代码,由ysth回答:

map {
   $results->{$_}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi
} keys %{$results};

以及Sinan Ünür

建议使用倾斜牙签的改进版本
map {
   $results->{$_}{uri} =~ s{".*/(.*\.*(gif|jpe?g|png))"}{/resources/uploads/$1}gi
} keys %{$results};

3 个答案:

答案 0 :(得分:10)

值得一提的是,你可以逃脱

$_->{uri} =~ s/foo/bar/ for values %$results;

在这种情况下。在数据结构中进行调整不会干扰构成数据结构的引用。

答案 1 :(得分:8)

在地图版本中,您错误地将$results->{更改为$results{。把 - >回来,它应该工作。

答案 2 :(得分:5)

第二段代码使用散列,但第一段使用散列引用。以下似乎有效:

use warnings;
use strict;

my $results = {
    a => {uri => "\"c/x.png\"" },
    b => {uri => "\"d/y.jpeg\""}
};

map {
   $results->{$_}{uri} =~ 
       s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi
} keys %{$results};

for my $k (keys %$results) {
    print "$k $results->{$k}{uri}\n";
}