Réponses:
Vous pouvez faire quelque chose comme ceci comme démontré dans perlfaq4 :
sub uniq {
my %seen;
grep !$seen{$_}++, @_;
}
my @array = qw(one two three two three);
my @filtered = uniq(@array);
print "@filtered\n";
Les sorties:
one two three
Si vous souhaitez utiliser un module, essayez la uniq
fonction deList::MoreUtils
my
lexical dans ce domaine, donc ça va. Cela étant dit, un nom de variable plus descriptif pourrait être choisi.
$::a
et $::b
, n'est-ce pas?
sub uniq { my %seen; grep !$seen{$_}++, @_ }
est une meilleure implémentation car elle préserve l'ordre sans frais. Ou mieux encore, utilisez celui de List :: MoreUtils.
La documentation Perl est fournie avec une belle collection de FAQ. Votre question est fréquemment posée:
% perldoc -q duplicate
La réponse, copiée et collée à partir de la sortie de la commande ci-dessus, apparaît ci-dessous:
Trouvé dans /usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod Comment puis-je supprimer les éléments en double d'une liste ou d'un tableau? (contribution de brian d foy) Utilisez un hachage. Lorsque vous pensez que les mots "unique" ou "dupliqué", pensez "clés de hachage". Si vous ne vous souciez pas de l'ordre des éléments, vous pouvez simplement créez le hachage puis extrayez les clés. Ce n'est pas important de savoir comment vous créez ce hachage: utilisez simplement des "clés" pour obtenir les éléments uniques. mon% hash = map {$ _, 1} @array; # ou une tranche de hachage: @hash {@array} = (); # ou un foreach: $ hash {$ _} = 1 foreach (@array); mon @unique = clés% hash; Si vous souhaitez utiliser un module, essayez la fonction "uniq" de "Liste :: MoreUtils". Dans le contexte de la liste, il renvoie les éléments uniques, en préservant leur ordre dans la liste. Dans un contexte scalaire, il renvoie le nombre d'éléments uniques. utilisez List :: MoreUtils qw (uniq); mon @unique = uniq (1, 2, 3, 4, 4, 5, 6, 5, 7); # 1,2,3,4,5,6,7 mon $ unique = uniq (1, 2, 3, 4, 4, 5, 6, 5, 7); # 7 Vous pouvez également parcourir chaque élément et ignorer ceux que vous avez vus avant. Utilisez un hachage pour garder une trace. La première fois que la boucle voit un élément, cet élément n'a pas de clé dans% Seen. L'instruction "next" crée la clé et utilise immédiatement sa valeur, qui est "undef", donc la boucle continue à "pousser" et incrémente la valeur de cette clé. Le suivant au moment où la boucle voit ce même élément, sa clé existe dans le hachage et la valeur de cette clé est true (car elle n'est pas 0 ou "undef"), donc le next ignore cette itération et la boucle passe à l'élément suivant. mon @unique = (); mon% vu = (); foreach mon $ elem (@array) { suivant si $ vu {$ elem} ++; push @unique, $ elem; } Vous pouvez écrire ceci plus brièvement en utilisant un grep, qui fait la même chose chose. mon% vu = (); mon @unique = grep {! $ vu {$ _} ++} @array;
Liste d' installation :: MoreUtils du CPAN
Puis dans votre code:
use strict;
use warnings;
use List::MoreUtils qw(uniq);
my @dup_list = qw(1 1 1 2 3 4 4);
my @uniq_list = uniq(@dup_list);
@dup_list
devrait être à l'intérieur de l' uniq
appel, pas@dups
Ma façon habituelle de faire ceci est:
my %unique = ();
foreach my $item (@myarray)
{
$unique{$item} ++;
}
my @myuniquearray = keys %unique;
Si vous utilisez un hachage et ajoutez les éléments au hachage. Vous avez également l'avantage de savoir combien de fois chaque élément apparaît dans la liste.
Peut être fait avec une simple doublure Perl one.
my @in=qw(1 3 4 6 2 4 3 2 6 3 2 3 4 4 3 2 5 5 32 3); #Sample data
my @out=keys %{{ map{$_=>1}@in}}; # Perform PFM
print join ' ', sort{$a<=>$b} @out;# Print data back out sorted and in order.
Le bloc PFM fait ceci:
Les données dans @in sont introduites dans MAP. MAP crée un hachage anonyme. Les clés sont extraites du hachage et alimentées dans @out
Logique: un hachage ne peut avoir que des clés uniques, donc itérer sur un tableau, attribuer une valeur à chaque élément du tableau, en gardant l'élément comme clé de ce hachage. Retournez les clés du hachage, c'est votre tableau unique.
my @unique = keys {map {$_ => 1} @array};
Mieux vaut créer un sous-programme si nous sommes censés utiliser cette fonctionnalité plusieurs fois dans notre code.
sub get_unique {
my %seen;
grep !$seen{$_}++, @_;
}
my @unique = get_unique(@array);
List::MoreUtils
use List::MoreUtils qw(uniq);
my @unique = uniq(@array);
Les réponses précédentes résument assez bien les moyens possibles d'accomplir cette tâche.
Cependant, je suggère une modification pour ceux qui ne se soucient pas de compter les doublons, mais qui se soucient de l'ordre.
my @record = qw( yeah I mean uh right right uh yeah so well right I maybe );
my %record;
print grep !$record{$_} && ++$record{$_}, @record;
Notez que les grep !$seen{$_}++ ...
incrémentations suggérées précédemment $seen{$_}
avant de négocier, l'incrémentation se produit indépendamment du fait qu'il ait déjà été %seen
ou non. Ce qui précède, cependant, court-circuit quand $record{$_}
est vrai, laissant ce qui a été entendu une fois «hors du %record
».
Vous pouvez également opter pour ce ridicule, qui tire parti de l'autovivification et de l'existence de clés de hachage:
...
grep !(exists $record{$_} || undef $record{$_}), @record;
Cela pourrait toutefois prêter à confusion.
Et si vous ne vous souciez ni de l'ordre ni du nombre de doublons, vous pouvez utiliser un autre hack en utilisant des tranches de hachage et l'astuce que je viens de mentionner:
...
undef @record{@record};
keys %record; # your record, now probably scrambled but at least deduped
sub uniq{ my %seen; undef @seen{@_}; keys %seen; }
Neat.
Essayez ceci, il semble que la fonction uniq ait besoin d'une liste triée pour fonctionner correctement.
use strict;
# Helper function to remove duplicates in a list.
sub uniq {
my %seen;
grep !$seen{$_}++, @_;
}
my @teststrings = ("one", "two", "three", "one");
my @filtered = uniq @teststrings;
print "uniq: @filtered\n";
my @sorted = sort @teststrings;
print "sort: @sorted\n";
my @sortedfiltered = uniq sort @teststrings;
print "uniq sort : @sortedfiltered\n";
Utilisation du concept de clés de hachage uniques:
my @array = ("a","b","c","b","a","d","c","a","d");
my %hash = map { $_ => 1 } @array;
my @unique = keys %hash;
print "@unique","\n";
Sortie: acbd