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";
}
精彩评论