开发者

How do I use map() to apply an operation to each element of a hash in Perl?

I've got a piece of code that works fine. It basically loops through each element of a hash using foreach() and applies a transformation to it using a regular expression, like so :

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

$results is a hashref returnd by DBI's fetchall_hashref() function.

Just out of curiosity, I wanted to see if I could rewrite it using map() instead, as shown below :

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

Unfortunately, that doesn't work. I've tried all sorts of things but so far without success. Anybody knows how to do this? Thanks.

UPDATE

The corrected code, as answered by ysth:

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

and the improved version with less leaning toothpicks suggested by Sinan Ünür

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


It's worth mentioning that you could get away with

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

in this case. Poking around in the data structure doesn't disturb the references that make it up.


In the map version, you've mistakenly changed $results->{ to $results{. Put the -> back in and it should work.


The second piece of code uses a hash but the first one uses a hash reference. The following seems to work:

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";
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜