IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Utilisation de la fonction map() ?


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Ingénieur d'études
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Par défaut Utilisation de la fonction map() ?
    Bonjour,

    ayant actuellement de grands tableaux à manipuler (listes, tables de hashage) ainsi qu'un ou deux scripts écrits par ma chef, j'ai découvert récemment la fonction map() en Perl. Cette fonction semble puissante, seulement je ne la comprends que globalement, et ce malgré l'avoir étudiée en consultant la perldoc ainsi qu'en analysant les scripts dont je dispose. J'ai également effectué une recherche sur le site, la FAQ Perl, et le forum Perl, je n'ai trouvé aucune réponse relative à mes interrogations.

    L'un de vous serait-il en mesure de m'expliquer plus clairement le fonctionnement de cette fonction afin que je sois à même de l'exploiter correctement et non plus par tâtonnement ?

    En vous remerciant d'avance.
    Cordialement, Norore.

  2. #2
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Par défaut
    La fonction map() permet d'appliquer un traitement à tous les éléments d'une liste.
    Elle prend en paramètre le bloc d'instructions à appliquer à chaque élément et la liste concernée. Elle va renvoyée la liste des valeurs résultant du traitement.

    L'élément que nous sommes en train d'analyser est représenté par la variable $_.

    Un exemple simple : multiplier par deux tous les éléments d'une liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    my @l = ( 1,2,3,4,5,6 );
    my @l2 = map ( {$_*2} @l ); # pas de virgule entre le bloc et la liste
    En fait, cette fonction permet souvent d'éviter d'écrire une boucle pour analyser tous les éléments d'une liste.
    Par exemple, pour compter le nombre de valeurs paires dans une liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    my @l = ( 1,2,3,4,5,6 );
    my ( $nbPair,$i ) =( 0,0 );
    while ( $i<scalar(@l) ) {
      ++$nbPair if ( $l[$i] % 2 == 0 );
      ++$i;
    }
    Et avec map :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    my @l = ( 1,2,3,4,5,6 );
    my $nbPair =0;
    map ( {++$nbPair if ( $_ % 2 == 0 )} @l )

  3. #3
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    map est effectivement l'un des piliers de la programmation en perl, avec grep et sort.

    Cette fonction permet de traiter une liste, et retourne une autre liste qui dépend d'un traitement effectué pour chaque élément de la liste fournie en paramètre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my $multiplie_par_2 = map $_ * 2, @valeurs; # avec expression
    my @multiplie_par_2 = map { $_ * 2 } @valeurs; # avec code
    Dans l'exemple ci dessus (qui s'écrit des deux manières : dans le doute, utilise la deuxième manière, qui est plus universelle), chaque élément de @valeurs est passé individuellement à map. C'est élément de tableau est affecté à la variable $_, et le code (ou l'expression) est exécuté. Pour cet élément, map va alors retourner la dernière valeur évaluée dans le code ou l'expression (ici, $_ * 2, soit l'élément multiplié par deux). Ainsi, @multiplie_par_2 contiendra autant d'éléments que @valeurs, et ses valeurs seront le double de celles de @valeurs.

    Maintenant, imaginons que @valeurs contiennent des nombres, mais aussi des éléments d'un autre type (des textes). Dans ce cas, on peut vouloir faire un traitement différent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @multiplie_par_2 = map { /^[\d\-\.]+$/ ? $_ * 2 : $_ x 2 } @valeurs;
    Mais on peut aussi imaginer un traitement bien plus complexe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my @info_valeurs = map { my $valeur = $_;
      { valeur => $valeur,
        valeur_double => $valeur * 2,
        valeur_carre => $valeur * $valeur }; # on retourne un hash en forme de structure de données
    } @valeurs;
    Dans le dernier exemple, @info_valeurs contiendra autant d'élément que @valeurs, mais chaque élément sera une référence à un hash anonyme contenant les clés valeur, valeur_double et valeur_carre.

    Il est aussi possible de sérialiser plusieurs map à la suite, le premier map de l'expression étant exécuté en dernier (puisqu'il dépend de la liste retournée par le map qui le suit).

    Si tu souhaites d'autres détails, ou si tu as des questions plus précises, n'hésite pas.

  4. #4
    Membre averti
    Femme Profil pro
    Ingénieur d'études
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Par défaut
    Merci beaucoup, c'est déjà moins flou et plus clair dans ma tête ! Il va sûrement me falloir plus d'expérience dans son utilisation, mais je vois mieux comment ça se manipule.

    Merci à vous deux pour ces explications claires et précises !

  5. #5
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Vu qu'il y a beaucoup d'usages possibles, tu auras de quoi t'entrainer. N'hésite pas à poser d'autres questions dans ce fil.

  6. #6
    Membre averti
    Femme Profil pro
    Ingénieur d'études
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Par défaut
    Bonjour,

    j'ai une autre question sur l'utilisation de la fonction map() !
    Prenons le cas concret d'une table de hachage. Je lis un fichier contenant des identifiants. Chaque identifiant peut renseigner sur plusieurs autres identifiants. Ces identifiants sont en fait des clés issues de bases de données. Ainsi un identifiant unique peut pointer sur plusieurs clés, clés que l'on peut réunir dans une liste.
    Peut-on utiliser la fonction map() pour remplir la table de hachage au fur et à mesure de la lecture du fichier ou doit-on procéder bêtement en écrivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    foreach my $cle (@cles){
        $hash{$identifiant} = $cle;
    }
    J'ai essayé en écrivant ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my %hash = map { ( $identifiant => $_) @cles };
    mais Perl m'envoie bouler en me renvoyant une erreur d'Array.

    J'ai sûrement dû faire une erreur quelque part, mais où ?

    Cordialement, Norore.

  7. #7
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    D'où sort ton $identifiant ? Car dans ta première écriture, il est défini à l'extérieur du foreach, mais il l'affectation faite ne modifie qu'un élément du hash $hash. Alors que dans la deuxième écriture, tout le hash $hash est mis à jour... et avec l'unique clé $identifiant.
    Il me semble donc que ton algorithme n'est pas complet.

    D'autre part, d'après ce que je vois, tu cherches à associer une liste de clés à un identifiant. Or, un hash est une association d'une clé et d'une valeur scalaires (et non tableau).
    Pour obtenir ce que tu veux, il faut que la liste de clés à mettre dans la valeur de $hash{$identifiant} soit un scalaire, donc une référence à un tableau.

    Les deux écritures possible sont alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach my $cle (@cles){
        push @{$hash{$identifiant}}, $cle;
    }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my %hash = ($identifiant => [ @cles ]);
    Mais je suppose que tu souhaites plutôt faire quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my %hash = map {
      my ($identifiant, @cle) = split /\s*/;
      $identifiant => [ @cle ];
    } <STDIN>;

  8. #8
    Membre averti
    Femme Profil pro
    Ingénieur d'études
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Par défaut
    Effectivement, il s'agissait plus de la seconde méthode.
    En fait l'identifiant et la liste de clés sont définis à chaque tour de boucle à la lecture du fichier. Sachant qu'une ligne du fichier contient un identifiant et au moins une clé.
    Il semblerait que j'avais en plus de cela mal compris le fonctionnement des tables de hachage, comme quoi après la théorie il y a la pratique ...

    Je prends donc note pour la référence à la liste, l'idée est loin d'être mauvaise !
    Encore merci pour les explications !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [LG]Utilisation de la fonction time
    Par kmitz dans le forum Langage
    Réponses: 4
    Dernier message: 08/04/2005, 13h05
  2. Utilisation de la fonction de déploiement
    Par mchicoix dans le forum XMLRAD
    Réponses: 4
    Dernier message: 01/03/2005, 14h35
  3. [LG]Utilisation de la fonction Random
    Par chloe95 dans le forum Langage
    Réponses: 1
    Dernier message: 01/03/2005, 14h20
  4. Utilisation de la fonction qsort
    Par Jsmeline dans le forum C
    Réponses: 8
    Dernier message: 28/01/2005, 12h40
  5. [LG]librairies : utiliser seulement quelques fonctions
    Par wwwroom dans le forum Langage
    Réponses: 13
    Dernier message: 14/05/2004, 22h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo