web-dev-qa-db-fra.com

Comment imprimer des éléments uniques dans un tableau Perl?

Je pousse des éléments dans un tableau lors d'une déclaration while. Chaque élément est le nom d'un enseignant. Il y a des noms d’enseignants en double dans le tableau lorsque la boucle se termine. Parfois, ils ne sont pas côte à côte dans le tableau, parfois, ils le sont.

Comment puis-je imprimer uniquement les valeurs uniques dans ce tableau une fois que les valeurs ont été insérées? Sans avoir à analyser le tableau entier à chaque fois que je veux imprimer un élément.

Voici le code après que tout ait été placé dans le tableau:

$faculty_len = @faculty;
$i=0;
while ($i != $faculty_len)
{
        printf $fh '"'.$faculty[$i].'"';
        $i++;
}   
25
CheeseConQueso
use List::MoreUtils qw/ uniq /;
my @unique = uniq @faculty;
foreach ( @unique ) {
    print $_, "\n";
}
42
innaM

Votre meilleur choix serait d'utiliser un outil intégré (en gros), comme uniq ( comme décrit par innaM) .

Si vous ne pouvez pas utiliser uniq et que vous souhaitez conserver l'ordre, vous pouvez utiliser grep pour simuler cela.

my %seen;
my @unique = grep { ! $seen{$_}++ } @faculty;
# printing, etc.

Cette première vous donne un hachage où chaque clé est chaque entrée. Ensuite, vous parcourez chaque élément, en comptant leur nombre et en ajoutant le premier. (Mis à jour avec les commentaires de brian d foy)

33
Robert P

Je suggère de le pousser dans un hash ..__ comme ceci:

my %faculty_hash = ();
foreach my $facs (@faculty) {
  $faculty_hash{$facs} = 1;
}
my @faculty_unique = keys(%faculty_hash);
14
user54650
@array1 = ("abc", "def", "abc", "def", "abc", "def", "abc", "def", "xyz");

@array1 = grep { ! $seen{ $_ }++ } @array1;

print "@array1\n"; 
5
prasad

Cette question répond à plusieurs solutions dans Perldoc. Tapez simplement en ligne de commande:

perldoc -q duplicate
5
Bizmarck

Remarque: certaines réponses contenant un hachage modifieront l'ordre du tableau. Les hachages n'ont pas d'ordre, donc obtenir les clés ou les valeurs fera une liste avec un ordre indéfini.

Ceci ne s'applique pas à grep { ! $seen{$_}++ } @faculty 

4
jmmeier

Il s’agit d’une commande unique pour imprimer des lignes uniques dans l’ordre où elles apparaissent.

Perl -ne '$seen{$_}++ || print $_' fileWithDuplicateValues
3
VJain

Je viens de trouver 3 doublure hackneyed, profitez-en

my %uniq; 
undef @uniq(@non_uniq_array); 
my @uniq_array = keys %uniq; 
2
ryansstack

Juste une autre façon de le faire, utile seulement si vous ne vous souciez pas de l'ordre:

my %hash;
@hash{@faculty}=1;
my @unique=keys %hash;

Si vous souhaitez éviter de déclarer une nouvelle variable, vous pouvez utiliser la variable globale en quelque sorte mal documentée % _

@_{@faculty}=1;
my @unique=keys %_;
2
psxls

Si vous devez traiter la liste des professeurs de quelque manière que ce soit, une carte du tableau convertie en hachage pour la fusion des clés, puis le tri des clés, constituent un autre bon moyen:

my @deduped = sort keys %{{ map { /.*/? ($_,1):() } @faculty }};
print join("\n", @deduped)."\n";

Vous traitez la liste en modifiant la regex /.*/ pour sélectionner ou analyser et capturer en conséquence, et vous pouvez générer une ou plusieurs clés mutées non uniques par passe en rendant ($_,1):() arbitrairement complexe.

Si vous devez modifier les données en vol avec une expression rationnelle de substitution, par exemple, pour supprimer les points des noms (s/\.//g), une substitution conforme au modèle ci-dessus mue le tableau @faculty d'origine en raison de l'aliasing $_. Vous pouvez contourner l'aliasing $_ en créant une copie anonyme du tableau @faculty (voir l'opérateur "panier bébé" ):

my @deduped = sort keys %{{ map {/.*/? do{s/\.//g; ($_,1)}:()} @{[ @faculty ]} }};
print join("\n", @deduped)."\n";
print "Unmolested array:\n".join("\n", @faculty)."\n";

Dans les versions plus récentes de Perl, vous pouvez transmettre à keys un hashref et utiliser la substitution non destructive:

my @deduped = sort keys { map { /.*/? (s/\.//gr,1):() } @faculty };

Sinon, la solution grep ou $seen[$_]++ ailleurs peut être préférable.

0
derekm