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 :

Tri alphanumérique en Perl


Sujet :

Langage Perl

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut Tri alphanumérique en Perl
    Bonjour,

    j'aimerais faire un tri en Perl, j'utilise donc la fonction sort qui fait un tri en suivant l'ordre ASCII.
    Hors j'ai des noms suivit de numéros, ce qui me donne (avec l'utilisation de la fonction sort) :
    nom1 < nom10 < nom2 ...
    Je voudrais un tri qui prenne les numéro en compte, ce qui me donnerait :
    nom1 < nom2 < nom10 ...

    J'imagine qu'il me faut modifier la fonction sort mais je ne comprends pas vraiment comment on fait.

    Merci d'avance,

    Mathilde

  2. #2
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    Bonjour,

    Voici une solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    my @noms = qw/ nom1 nom2 nom3 nom4 nom5 nom10 nom11 nom20 nom6 /;
    print join ',', sort { select_nombre($a) <=> select_nombre($b) } @noms;
    sub select_nombre {
    	my $chaine = shift;
    	$chaine =~ m/nom(\d+)/;
    	return $1;
    }
    Voici des explications : comment trier un tableau.

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Ça marche si j'ai des variables composées de "nom" suivit d'un nombre.

    Je me suis mal exprimée tout à l'heure car les variables dans la liste peuvent être tout et n'importe quoi, je veux juste que les nombres dans ces variables ne soient pas interprétés comme des caractères.
    Pour un exemple, je peux avoir une liste composée de : "1", "truc1", "truc10","machin","chose5""chose6","chose7ab", ...

    Je pense qu'il faut juste modifier la regex dans ce que tu m'as envoyé..

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Points : 406
    Points
    406
    Par défaut
    Citation Envoyé par laine-m Voir le message
    Pour un exemple, je peux avoir une liste composée de : "1", "truc1", "truc10","machin","chose5""chose6","chose7ab", ...

    Je pense qu'il faut juste modifier la regex dans ce que tu m'as envoyé..
    Pour reprendre le code de @djibril:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    my @noms = qw/ nom1 nom2 nom3 nom4 nom5 nom10 nom11 nom20 nom6 /;
    print join ',', sort { select_nombre($a) <=> select_nombre($b) } @noms;
    sub select_nombre {
    	my $chaine = shift;
    	$chaine =~ m/.*(\d+).*/;
    	$1=0 if ( !defined $1 );
    	return $1;
    }
    ça devrait fonctionner mais pas testé
    Attention: si tu as chose88truc9 et chose9truc9, tu auras un tri lexical de "chose88truc" et "chose9truc" et donc pas tout à fait ce que tu souhaites

  5. #5
    Futur Membre du Club
    Femme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Désolé mais ce code ne fonctionne pas.
    D'une part, $1 est une constante et ne peut donc pas être modifiée, j'ai donc effectué la modification suivante.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    sub select_nombre {
    	my $chaine = shift;
    	$chaine =~ m/.*(\d+).*/;
    	defined $1 ? return $1 : return 0;
    }
    Et le résultat est faux.
    Par exemple, pour la liste ("1", "truc1", "truc10","machin","chose5""chose6","chose7ab"), ça me retourne (1,truc1,truc10,machin,chose5,chose6,chose7abFile).

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Points : 406
    Points
    406
    Par défaut
    ben c'est ce que tu voulais faire de trier en fonction des chiffres non?
    tu souhaites faire un tri alphabétique puis numérique?

  7. #7
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    Il va falloir sortir la boule de cristal car sans clarté, difficile d'avoir une solution optimale !

  8. #8
    Futur Membre du Club
    Femme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Oui c'est ça !!

    Je voudrais que ça me retourne "1", "chose5", "chose6", "chose7ab", "machin", "truc1", "truc2", "truc10", ...

    Je ne pensais pas que je galérerais autant sur quelque chose d’aussi basique..

  9. #9
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Essaie ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/perl
     
    use strict;
    use warnings;
     
    my @liste = ("1", "truc10", "truc1","machin","chose15","chose6","chose7ab");
     
    print join " ", 
    	map { /;(\w+)$/}
    	sort 
    	map { my $c =  $_; $c =~ s/(\d+)/sprintf "%03d", $1/e; "$c;$_";}
    	@liste;
    Ce qui imprime:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    1 chose6 chose7ab chose15 machin truc1 truc10
    Cette technique s'appelle la transformation de Guttman Rosler, elle est expliquée en détail dans le premier volet un (consacré aux opérateurs de listes) de mon tutoriel sur la programmation fonctionnelle en Perl (voir le lien ci-dessous). Mais n'hésite pas à demander si tu as besoin d'explications.

  10. #10
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Je n'avais pas trop le temps quand j'ai posté le message précédent.

    Petite explication: le premier map, celui du bas, transforme la liste:

    en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ("truc010;truc10", "truc002;truc2")
    Le nombre est maintenant sur trois chiffres en tête de chaîne, donc le tri se fait correctement avec un sort lexicograpique ordinaire. Le second map (celui du haut) écarte ce qui a été ajouté par le premier map et restitue la chaîne d'origine, dans l'ordre voulu.

  11. #11
    Futur Membre du Club
    Femme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Super, ça fonctionne, merci beaucoup !

    Mathilde

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

Discussions similaires

  1. Tri alphanumérique sql
    Par eddyrigotti dans le forum SQL
    Réponses: 3
    Dernier message: 22/10/2009, 10h20
  2. [Système] Tri alphanumérique en UTF-8
    Par nazoreen dans le forum Langage
    Réponses: 5
    Dernier message: 24/06/2007, 14h15
  3. Réponses: 1
    Dernier message: 22/06/2007, 12h48
  4. Tri multiple (programmeur Perl pas doué inside)
    Par Arioch dans le forum Langage
    Réponses: 5
    Dernier message: 18/07/2006, 12h47
  5. Réponses: 5
    Dernier message: 23/01/2006, 19h13

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