FAQ PerlConsultez toutes les FAQ
Nombre d'auteurs : 18, nombre de questions : 250, dernière mise à jour : 29 octobre 2015 Ajouter une question
Bienvenue sur la FAQ Perl. Cette FAQ a pour vocation de vous enseigner ou de vous faire revoir les notions élémentaires de ce fantastique langage. Perl est très utilisé dans différents domaines depuis la gestion système, le réseaux, l'administration de bases de données, le web (CGI), la bureautique, la conception d'interfaces graphiques ou des contextes scientifiques telle la bioinformatique. Nous espérons que cette FAQ vous sera d'une grande utilité.
Vous souhaitez participer à l'amélioration de cette FAQ, n'hésitez pas !! Commentez
Bonne lecture !
Il existe différentes méthodes pour supprimer les doublons dans une liste (un tableau) en perl. La première méthode consiste à utiliser un module Perl. C'est bien évidemment la méthode la plus recommandée car les modules disponibles sur le CPAN sont efficaces et bien écrits.
Voici une liste de modules intéressants :
La seconde méthode revient à ne pas utiliser de modules et coder soit même. Voici 3 procédures élégantes qui permettent de supprimer les doublons d'un tableau. Comparons les.
- Technique 1 (hash anonyme)
Cette procédure prend en argument une référence d'un tableau et chaque case du tableau devient une clé d'un hash anonyme. Les clés de la table de hachage sont renvoyées.
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | #!/usr/bin/perl use strict; use warnings; sub doublons_hash_anonyme { my ($ref_tabeau) = @_; return keys %{ { map { $_ => 1 } @{$ref_tabeau} } }; } |
- Technique 2 (tranche)
Cette procédure prend en argument une référence d'un tableau et chaque case du tableau devient la clé d'une tranche de hachage d'un hachage qu'on aura déclaré.
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/usr/bin/perl use strict; use warnings; sub doublons_tranche { my ($ref_tabeau) = @_; my %hash_sans_doublon; # Comme un hash ne peut pas avoir deux clés identiques, # utilser ces clé permet d'avoir un tableau unique @hash_sans_doublon{ @{$ref_tabeau} } = (); # Pas besoin de surcharger le hash avec des valeurs inutiles # et ensuite, on renvoie le tableau des clés uniques return keys %hash_sans_doublon; } |
- Technique 3 (grep)
Cette procédure prend en argument une référence d'un tableau et chaque case est passée au filtre grep qui ne conserve que celles qui n'ont pas déjà été vues.
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | #!/usr/bin/perl use strict; use warnings; sub doublons_grep { my ($ref_tabeau) = @_; my %hash_sans_doublon; return grep { !$hash_sans_doublon{$_}++ } @{$ref_tabeau}; } |
- Avantages et inconvénients
Ces trois techniques sont simples, efficaces et facilement maintenables. Il n'est pas du tout nécessaire d'installer un nouveau module pour cela, bien que List::Util soit dans le CORE de perl depuis sa version 5.8.
Pour de plus amples manipulations de tableaux, je vois recommande biensûr les modules cités ci-dessus.
Sachez maintenant que parmi ces 3 procédures, certaines sont plus rapides que d'autres. la technique 2 (à coup de tranche) est la plus rapide des 3, ensuite vient la technique 3 (à coup de grep), puis vient la dernière (technique 1). Ce n'est qu'une remarque, mais tout dépend de la longueur des listes, du nombre de doublons qu'elles contiennent, etc ... En général, la première place est toujours partagée entre la technique 2 (à coup de tranche) et 3 (à coup de grep).
Autres remarques :
- La technique 2 (tranche) est plus avantageuse que la 1 car elle n'a pas besoin de créer une liste intermédiaire.
- Notez bien que seule la technique 3 ( grep) permet de conserver l'ordre des éléments du tableau après suppression des doublons (important selon vos besoins) ! Sachez que la différence de temps entre la 2 et 3 n'est pas non plus dramatique. Utilisez le module Benchmark pour effectuer vos tests si vous le souhaitez.
- Exemple d'utilisation
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #!/usr/bin/perl use strict; use warnings; my @listing_mots = qw/ moi 2Eurocents Woufeil toi djibril Jedai moi Jedai gldavid etc Jedai Stoyak lui nous tous je tu elle lui perl 10 20 20 30 8 6 9 100 /; my @resultat1 = doublons_hash_ano( \@listing_mots ); my @resultat2 = doublons_tranche( \@listing_mots ); my @resultat3 = doublons_grep( \@listing_mots ); print "Original : @listing_mots\n"; print "HASH anonyme : @resultat1\n"; print "Tranche : @resultat2\n"; print "GREP : @resultat3\n"; sub doublons_hash_anonyme { my ($ref_tabeau) = @_; return keys %{ { map { $_ => 1 } @{$ref_tabeau} } }; } sub doublons_grep { my ($ref_tabeau) = @_; my %hash_sans_doublon; return grep { !$hash_sans_doublon{$_}++ } @{$ref_tabeau}; } sub doublons_tranche { my ($ref_tabeau) = @_; my %hash_sans_doublon; # Comme un hash ne peut pas avoir deux clés identiques, # utilser ces clé permet d'avoir un tableau unique @hash_sans_doublon{ @{$ref_tabeau} } = (); # Pas besoin de surcharger le hash avec des valeurs inutiles # et ensuite, on renvoie le tableau des clés uniques return keys %hash_sans_doublon; } sub doublons_hash_ano { my ($ref_tabeau) = @_; return keys %{ { map { $_ => 1 } @{$ref_tabeau} } }; } |
Code : | Sélectionner tout |
1 2 3 4 | Original : moi 2Eurocents Woufeil toi djibril Jedai moi Jedai gldavid etc Jedai Stoyak lui nous tous je tu elle lui perl 10 20 20 30 8 6 9 100 HASH anonyme : djibril toi je gldavid etc tu Woufeil 30 100 moi 6 Jedai 9 20 8 2Eurocents perl tous lui Stoyak elle 10 nous Tranche : djibril toi je gldavid etc tu Woufeil 30 100 moi 6 Jedai 9 20 8 2Eurocents perl tous lui Stoyak elle 10 nous GREP : moi 2Eurocents Woufeil toi djibril Jedai gldavid etc Stoyak lui nous tous je tu elle perl 10 20 30 8 6 9 100 |
La fonction sort() en Perl est très puissante et permet de faire tous les tris inimaginables.
Elle trie les éléments d'une liste et retourne une liste triée des éléments fournis en paramètre.
Ces deux listes peuvent être distinctes, ou bien la liste d'origine peut être écrasée par le résultat du tri si elle est destinataire de l'affectation.
La fonction sort peut prendre un argument spécial qui est le bloc de comparaison à effectuer entre les éléments de la liste à trier. Il est ainsi possible de trier selon des critères tout à fait personnalisés.
Par défaut, le tri se fait dans l'ordre "lexicographique" (ordre alphabétique, étendu aux nombres dont les chiffres sont traités comme des caractères et non comme des nombres). Le bloc de comparaison personnalisé doit être précisé entre accolades, avant la liste d'éléments à trier, sans être séparé de celle-ci par une virgule. Pour la comparaison, ce bloc utilise deux variables internes de PERL, $a et $b, qui ne sont définies que dans ce bloc et masquent toute variable $a ou $b propre à l'utilisateur. Ce bloc effectue donc un test quelconque, basé sur $a et $b, dont le résultat peut prendre trois valeurs :
- positif si $a est avant $b dans l'ordre de tri souhaité ;
- nul si $a et $b sont équivalents ;
- négatif si $a est après $b dans l'ordre souhaité.
Ces trois valeurs de résultat de test correspondent aux résultats des opérateurs de test et cmp vus précédemment.
Ainsi, pour un tri lexicographique du tableau @t, on peut faire :
Code perl : | Sélectionner tout |
@l = sort ( @t ); ou bien @l = sort ( { $a cmp $b } @t );
Pour un tri lexicographique inversé, on peut aussi bien écrire :
Code perl : | Sélectionner tout |
@l = reverse ( sort ( { $a cmp $b } @t ) );
Code perl : | Sélectionner tout |
@l = sort ( { $b cmp $a } @t );
Pour un tri numérique :
Code perl : | Sélectionner tout |
@l = sort ( { $a <=> $b } @t );
Code perl : | Sélectionner tout |
@l = sort ( { $tableau[$a] <=> $tableau[$b] } @t );
Code perl : | Sélectionner tout |
@l = sort ( { mafonction ($a, $b) } @t );
les mongueurs de Perl (groupe francophone consacré à la promotion de Perl) ont écrit un très bon article.
En voici d'autres :
- L'excellent article de Uri Guttman et Larry Rosler : A Fresh Look at Efficient Perl Sorting,
- La traduction de cet article par votre serviteur les mongeurs est disponible ici.
Il arrive que l'on ait besoin de comparer 2 listes perl entre elles afin d'obtenir les données communes aux deux listes, les données présentes dans une liste mais pas dans l'autre ... Pas besoin de reinventer la roue, il existe un module sur le CPAN qui le fait très bien, c'est List::Compare. Voici un exemple de code :
Code perl : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/usr/bin/perl use strict; use warnings; use List::Compare; my @Llist = qw(abel abel baker camera delta edward fargo golfer); my @Rlist = qw(baker camera delta delta edward fargo golfer hilton); my $lc = List::Compare->new( \@Llist, \@Rlist ); my @intersection = $lc->get_intersection; my @union = $lc->get_union; print "@intersection\n@union\n"; # baker camera delta edward fargo golfer # abel baker camera delta edward fargo golfer hilton |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.