Question

Je suis en train de réduire le nombre de lignes de code que je utilise, mais je suis de se retrouver avec un problème assez simple (même si ça me dessouchage depuis que je suis juste de commencer à envelopper ma tête autour de références)

Je suis en train de concaténer plusieurs valeurs dans un ordre particulier .. Mon code ressemble à ceci ..

my $separator = ":";
my @vals = qw(name last-name first-name phone);
my $return_name;
$return_name = map { 
    $return_name = $return_name . $query->param($_) . $separator 
} @vals;

Ce que je reçois est « 4 », au lieu de concantenating tout en une seule chaîne.

Ce que je suis en train de réaliser est une version plus courte de ...

$return_name = $query->param('name') . 
    $separator . $query->param('last-name') . 
    $separator . $query->param('first_name') . 
    $separator . $query->param('phone');

(je en train d'essayer d'enchaîner 25 $query->params. Je ne donnait quatre par souci de concision)

Était-ce utile?

La solution

Une partie de votre problème est la confusion sur la façon dont fonctionne map.

map prend une liste d'arguments, effectue une opération sur les éléments de la liste et crée une nouvelle liste des résultats. Dans un contexte scalaire, il retourne le nombre de membres dans la nouvelle liste.

Dans la plupart des cas, vous ne voulez pas faire une mission dans l'opération de map.

# no assignment needed to set @foo
my @foo = map $_+2, 1,2,3; 
# @foo = (3,4,5);

Le seul endroit où l'affectation logique est si vous avez besoin d'utiliser une opération qui devrait normalement changer la valeur de $_, mais vous devez conserver les arguments à la carte sans changement.

Cette explication est pas très claire. Consultez ces exemples, ils devraient aider à clarifier ce que je dis. La première montre que vous carte peut modifier les valeurs qu'il traite:

my @foo = qw( fee fie foe fum );
my @bar = map { s/e/-/g } @foo;
# @foo = ( 'f--', 'fi-', 'fo-', 'fum' ); 
# @bar = ( 2, 1, 1, '' );

Pour éviter de modifier @foo que vous pouvez faire:

my @foo = qw( fee fie foe fum );
my @bar = map { my $val = $_; $val =~ s/e/-/g } @foo;
# @foo = ( 'fee', 'fie', 'foe', 'fum' ); 
# @bar = ( 'f--', 'fi-', 'fo-', 'fum' ); 

Ou vous pouvez faire:

utiliser Liste :: moreutils QW (appliquer);

my @foo = qw( fee fie foe fum );
my @bar = apply { s/e/-/g } @foo;
# @foo = ( 'fee', 'fie', 'foe', 'fum' ); 
# @bar = ( 'f--', 'fi-', 'fo-', 'fum' );

Lors de sa plus map de base fonctionne comme une forme spécialisée d'une boucle de for. Les deux morceaux de code produisent exactement le même résultat:

my @foo = map {$_ * 2} 1..5;

my @bar;
for (1..5) {
     my $val = $_ * 2;
     push @bar, $val;
}

J'espère que vous avez donné un peu d'aide pour apprendre à penser à map. Une fois que vous avez appris à l'utiliser (et des constructions connexes comme grep et apply) vous serez en mesure d'exprimer de manière concise des idées qui peuvent incroyablement verbeux quand construit en utilisant le code normal looping.

Autres conseils

$return_name = map { $return_name = $return_name . $query->param($_) . $separator } @vals;

C'est une affectation scalaire, ce qui donne l'opération carte contexte scalaire. carte dans un contexte scalaire renvoie un nombre des éléments qui auraient été produits.

Bien que cette ligne de code particulier crie pour l'utilisation de join () , si vous venez d'un arrière-plan de la programmation fonctionnelle, vous pouvez être plus à l'aise avec réduction:

use List::Util 'reduce';
$return_name = reduce { $a . $query->param($b) . $separator } "", @vals;

map retourne une liste, pas une chaîne. Essayez ceci:

$return_name = join $separator, map { $query->param($_) } @vals;

Ou si vous voulez vraiment réduire le nombre de lignes, essayez ceci:

my $return_name = join ':', 
    map { $query->param($_) } 
    qw(name last-name first-name phone);

(La version d'une ligne a été inspirée par la réponse de dsm.)

Essayez ceci:

join $separator, 
     map { $query->param($_) } 
     ("name", "last-name", "first-name", "phone");

Pour répondre à la raison pour laquelle vous obtenez « 4 », c'est parce que vous assignez les tableaux résultant de la cardinalité à un scalaire.

En plus de toutes les bonnes réponses que vous avez reçues, notez que

$return_name = $return_name . $query->param($_) . $separator;

peut être écrit comme

$return_name .= $query->param($_) . $separator;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top