Como faço para usar o mapa () para aplicar uma operação a cada elemento de um hash em Perl?
-
05-07-2019 - |
Pergunta
Eu tenho um pedaço de código que funciona bem. Basicamente, percorre cada elemento de um hash usando foreach()
e aplica uma transformação a ele usando uma expressão regular, assim:
foreach my $key ( keys( %{$results} ) ) {
$results->{$key}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi;
}
$ resultados é um returnd hashref por função fetchall_hashref()
da DBI.
Só por curiosidade, eu queria ver se eu poderia reescrevê-lo usando map()
em vez disso, como mostrado abaixo:
map {
$results{$_}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi
} keys %{$results};
Infelizmente, isso não funciona. Eu tentei todos os tipos de coisas, mas até agora sem sucesso. Alguém sabe como fazer isso? Obrigado.
Atualizar
O código corrigido, como respondida por ysth :
map {
$results->{$_}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi
} keys %{$results};
e a versão melhorada com menos inclinada palitos sugerida por Sinan Ünür
map {
$results->{$_}{uri} =~ s{".*/(.*\.*(gif|jpe?g|png))"}{/resources/uploads/$1}gi
} keys %{$results};
Solução
Na versão do mapa, você erroneamente mudou $results->{
para $results{
. Coloque o -.> De volta e ele deve funcionar
Outras dicas
Vale a pena mencionar que você poderia fugir com
$_->{uri} =~ s/foo/bar/ for values %$results;
neste caso. Bisbilhotando na estrutura de dados não perturba as referências que o compõem.
A segunda parte do código utiliza um hash mas a primeira utiliza uma referência de hash. O seguinte parece funcionar:
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";
}