Antworten:
Sie können so etwas tun, wie in perlfaq4 gezeigt :
sub uniq {
my %seen;
grep !$seen{$_}++, @_;
}
my @array = qw(one two three two three);
my @filtered = uniq(@array);
print "@filtered\n";
Ausgänge:
one two three
Wenn Sie ein Modul verwenden möchten, probieren Sie die uniq
Funktion von ausList::MoreUtils
my
lexikalische in diesem Bereich, so ist es in Ordnung. Davon abgesehen könnte möglicherweise ein aussagekräftigerer Variablenname gewählt werden.
$::a
und $::b
, nicht wahr ?
sub uniq { my %seen; grep !$seen{$_}++, @_ }
ist eine bessere Implementierung, da die Ordnung kostenlos erhalten bleibt. Oder noch besser, verwenden Sie die von List :: MoreUtils.
Die Perl-Dokumentation enthält eine schöne Sammlung von FAQs. Ihre Frage wird häufig gestellt:
% perldoc -q duplicate
Die Antwort, die aus der Ausgabe des obigen Befehls kopiert und eingefügt wurde, wird unten angezeigt:
Gefunden in /usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod Wie kann ich doppelte Elemente aus einer Liste oder einem Array entfernen? (beigetragen von brian d foy) Verwenden Sie einen Hash. Wenn Sie die Wörter "einzigartig" oder "dupliziert" denken, denken Sie "Hash-Schlüssel". Wenn Sie sich nicht um die Reihenfolge der Elemente kümmern, können Sie einfach Erstellen Sie den Hash und extrahieren Sie die Schlüssel. Es ist nicht wichtig, wie du Erstellen Sie diesen Hash: Nur dass Sie "Schlüssel" verwenden, um die eindeutigen Elemente zu erhalten. mein% hash = map {$ _, 1} @array; # oder ein Hash-Slice: @hash {@array} = (); # oder ein foreach: $ hash {$ _} = 1 foreach (@array); mein @unique = keys% hash; Wenn Sie ein Modul verwenden möchten, versuchen Sie die Funktion "uniq" von "List :: MoreUtils". Im Listenkontext werden die eindeutigen Elemente zurückgegeben. Beibehaltung ihrer Reihenfolge in der Liste. Im skalaren Kontext wird das zurückgegeben Anzahl der eindeutigen Elemente. benutze List :: MoreUtils qw (uniq); my @unique = uniq (1, 2, 3, 4, 4, 5, 6, 5, 7); # 1,2,3,4,5,6,7 mein $ unique = uniq (1, 2, 3, 4, 4, 5, 6, 5, 7); # 7 Sie können auch jedes Element durchgehen und die Elemente überspringen, die Sie gesehen haben Vor. Verwenden Sie einen Hash, um den Überblick zu behalten. Das erste Mal, wenn die Schleife eine sieht Element, dieses Element hat keinen Schlüssel in% Seen. Die "nächste" Anweisung erstellt der Schlüssel und verwendet sofort seinen Wert, der "undef" ist, also die Schleife fährt mit dem "Drücken" fort und erhöht den Wert für diese Taste. Der nächste Wenn die Schleife dasselbe Element sieht, existiert ihr Schlüssel im Hash und Der Wert für diesen Schlüssel ist wahr (da er nicht 0 oder "undef" ist) next überspringt diese Iteration und die Schleife geht zum nächsten Element. mein @unique = (); mein% gesehen = (); foreach mein $ elem (@array) { next if $ found {$ elem} ++; push @unique, $ elem; }} Sie können dies mit einem grep kurz schreiben, was dasselbe tut Ding. mein% gesehen = (); mein @unique = grep {! $ found {$ _} ++} @array;
Installieren Sie List :: MoreUtils von CPAN
Dann in Ihrem 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
sollte innerhalb des uniq
Anrufs sein, nicht@dups
Meine übliche Vorgehensweise ist:
my %unique = ();
foreach my $item (@myarray)
{
$unique{$item} ++;
}
my @myuniquearray = keys %unique;
Wenn Sie einen Hash verwenden und die Elemente zum Hash hinzufügen. Sie haben auch den Bonus zu wissen, wie oft jedes Element in der Liste angezeigt wird.
Kann mit einem einfachen Perl One Liner durchgeführt werden.
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.
Der PFM-Block führt Folgendes aus:
Daten in @in werden in MAP eingespeist. MAP erstellt einen anonymen Hash. Schlüssel werden aus dem Hash extrahiert und in @out eingegeben
Logik: Ein Hash kann nur eindeutige Schlüssel haben. Iterieren Sie also über das Array, weisen Sie jedem Element des Arrays einen beliebigen Wert zu und behalten Sie das Element als Schlüssel für diesen Hash bei. Geben Sie die Schlüssel des Hashs zurück, es ist Ihr einzigartiges Array.
my @unique = keys {map {$_ => 1} @array};
Es ist besser, eine Unterroutine zu erstellen, wenn wir diese Funktionalität in unserem Code mehrmals verwenden sollen.
sub get_unique {
my %seen;
grep !$seen{$_}++, @_;
}
my @unique = get_unique(@array);
List::MoreUtils
use List::MoreUtils qw(uniq);
my @unique = uniq(@array);
Frühere Antworten fassen die möglichen Wege zur Erfüllung dieser Aufgabe ziemlich gut zusammen.
Allerdings schlage ich eine Änderung für diejenigen , die nicht über Pflege zählen die Duplikate, aber nicht kümmern uns um Ordnung.
my @record = qw( yeah I mean uh right right uh yeah so well right I maybe );
my %record;
print grep !$record{$_} && ++$record{$_}, @record;
Beachten Sie, dass die zuvor vorgeschlagenen grep !$seen{$_}++ ...
Inkremente $seen{$_}
vor dem Negieren ausgeführt werden, sodass das Inkrement unabhängig davon erfolgt, ob es bereits vorhanden war %seen
oder nicht. Das oben Gesagte schließt jedoch kurz, wenn $record{$_}
es wahr ist, und lässt das, was einmal gehört wurde, "aus %record
".
Sie könnten sich auch für diese Lächerlichkeit entscheiden, die die Autovivifizierung und das Vorhandensein von Hash-Schlüsseln ausnutzt:
...
grep !(exists $record{$_} || undef $record{$_}), @record;
Dies könnte jedoch zu Verwirrung führen.
Und wenn Sie sich weder für die Reihenfolge noch für die doppelte Anzahl interessieren, können Sie für einen weiteren Hack Hash-Slices und den Trick verwenden, den ich gerade erwähnt habe:
...
undef @record{@record};
keys %record; # your record, now probably scrambled but at least deduped
sub uniq{ my %seen; undef @seen{@_}; keys %seen; }
Ordentlich.
Versuchen Sie dies, anscheinend benötigt die Uniq-Funktion eine sortierte Liste, um ordnungsgemäß zu funktionieren.
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";
Verwenden des Konzepts eindeutiger Hash-Schlüssel:
my @array = ("a","b","c","b","a","d","c","a","d");
my %hash = map { $_ => 1 } @array;
my @unique = keys %hash;
print "@unique","\n";
Ausgabe: acbd