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

I have some code that works great. It basically goes through each element of the hash with foreach()

and applies a transform to it using a regex like:

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

      

$ results is a hashref returnd with the DBI function fetchall_hashref()

.

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 this doesn't work. I've tried all sorts of things but no success so far. Does anyone know how to do this? Thank.

UPDATE

Corrected code that ysth answers for :

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

      

and an improved version with less prone toothpicks suggested by Sinan Ünür

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

      

+2


source to share


3 answers


In the map version, you mistakenly changed $results->{

to $results{

. Place -> back and it should work.



+8


source


It's worth noting that you can get away with

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

      



in this case. A concussion in the data structure does not break the links that make it up.

+10


source


The second part of the code uses a hash, but the first 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";
}

      

+5


source







All Articles