2009-10-22 6 views
2

J'ai un morceau de code qui fonctionne bien. Il boucles essentiellement à travers chaque élément d'un hachage en utilisant foreach() et applique une transformation à l'aide d'une expression régulière, comme suit:Comment utiliser map() pour appliquer une opération à chaque élément d'un hachage en Perl?

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

résultats $ est un hashref Returnd par la fonction fetchall_hashref() de DBI.

Juste par curiosité, je voulais voir si je pouvais réécrire en utilisant map() à la place, comme indiqué ci-dessous:

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

Malheureusement, cela ne fonctionne pas. J'ai essayé toutes sortes de choses mais jusqu'ici sans succès. Quelqu'un sait comment faire cela? Merci.

MISE À JOUR

Le code corrigé, comme une réponse par ysth:

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

et la version améliorée avec moins cure-dents penchées suggéré par Sinan Ünür

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

Une chose qui pourrait vous intéresser est d'utiliser différents délimiteurs pour vos regex. Par exemple, s @ @ @ vous épargnerait quelques \ 's. En outre, nitpicking, le '\. *' N'est probablement pas ce que vous vouliez dire, et le \ in \ "n'est pas nécessaire –

+0

Merci pour les conseils regex.Nous allons certainement regarder dans: .-) – GeneQ

+0

@GeneQ' s { ". */(. * \. * (gif | jpe? g | png))"} {/ resources/uploads/$ 1} gi; 'Les cure-dents penchés peuvent jouer à des jeux avec votre vision –

Répondre

8

Dans la version de la carte, vous avez tort changé $results->{ à $results{. Remets le -> dans et ça devrait marcher.

+0

Ah, vous avez raison! Les bugs sont en effet peu profonds avec assez de globes oculaires Stackoverflow. ;-) Merci – GeneQ

5

Le deuxième morceau de code utilise un hachage mais le premier utilise une référence de hachage. Ce qui suit semble fonctionner:

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

Il convient de mentionner que vous pourriez sortir avec

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

dans ce cas. Piquer dans la structure de données ne perturbe pas les références qui le composent.

+0

Cool Une fois de plus cela prouve qu'il y a toujours plus d'une façon (surprenante) de faire les choses en Perl. – GeneQ

Questions connexes