OVH Cloud OVH Cloud

Tri de list en Perl.

10 réponses
Avatar
Chris
Bonjour,

Je travaille habituellement en Tcl mais on m'a demande de faire un script en
perl.
Mon script lit dans un fichier un grand nombre de valeurs (plus de 1600)
Parmis ces valeurs il y a plein de doublons et je dois supprimer tous les
doublons.

Je recupere donc mes valeurs dans une liste mais je ne trouve pas de
fonction existante pour supprimer les doublons.

Existe-t-elle ou dois-je l'ecrire moi-meme.

Merci

Christian

10 réponses

Avatar
Laurent Wacrenier
Chris écrit:
Je recupere donc mes valeurs dans une liste mais je ne trouve pas de
fonction existante pour supprimer les doublons.

Existe-t-elle ou dois-je l'ecrire moi-meme.


Écrivez la vous même, ce n'est pas long. Les deux méthodes ci dessous
le font. La première conserve l'ordre, l'autre non.

my %h;
@liste = grep {!$h{$_}++} @liste;

my %h = map { $_ => 1 } @liste;
@liste = keys %h;

Avatar
Ronan Le Hy
Chris a écrit:
Mon script lit dans un fichier un grand nombre de valeurs (plus de 1600)
Parmis ces valeurs il y a plein de doublons et je dois supprimer tous les
doublons.


Lisez vos valeurs dans un hash, et vous pourrez ensuite les récupérer
avec 'keys', par exemple :

# lecture
my %valeurs_uniques;
while(<>)
{
++$valeurs_uniques{$_};
}

# affichage des valeurs, triées par ordre lexicographique
print "valeur: $_" for sort keys %valeurs_uniques;

Pour la doc de sort et keys :
perldoc -f sort
perldoc -f keys

HTH

--
Ronan

Actually, it has always amazed me why using a dinosaur module like CGI
is considered "good programming" if all you need is parameter parsing.
Abigail

Avatar
Chris
Merci bcp,

Ca me debloque la situation.
Par contre j'ai une question:
Si je fait afficher a l'ecran le resultat, ca marche tres bien.
Si je le stocke dans une liste, il me rajoute un 1 a la fin.
Or je ne veux pas ce 1.

AGPa, BODa, BRUa, Dept, LEIa, LISa, LTNa, MJVa, MUCa, RTMa, VLCa,1

voici ce que je fais:

open (INPUTFILE, "$InputFile") || die "Error: $InputFile - $!n";
while (<INPUTFILE>) {
next if /^#/;
chop;

@Flight = split /,/;
++$unique_value{$Flight[0]};
}
close INPUTFILE;

$DeptDestList = print " $_," for sort keys %unique_value;

print $DeptDestList;

exit;

Le fichier d'entree est au format csv.

Comment ne pas avoir ce 1 en fin de liste ?

Merci

Christian

"Ronan Le Hy" wrote in message
news:3f8ac041$0$20180$
Chris a écrit:
Mon script lit dans un fichier un grand nombre de valeurs (plus de 1600)
Parmis ces valeurs il y a plein de doublons et je dois supprimer tous
les


doublons.


Lisez vos valeurs dans un hash, et vous pourrez ensuite les récupérer
avec 'keys', par exemple :

# lecture
my %valeurs_uniques;
while(<>)
{
++$valeurs_uniques{$_};
}

# affichage des valeurs, triées par ordre lexicographique
print "valeur: $_" for sort keys %valeurs_uniques;

Pour la doc de sort et keys :
perldoc -f sort
perldoc -f keys

HTH

--
Ronan

Actually, it has always amazed me why using a dinosaur module like CGI
is considered "good programming" if all you need is parameter parsing.
Abigail




Avatar
Chris
Merci bcp,

Ca me debloque la situation.
Par contre j'ai une question:
Si je fait afficher a l'ecran le resultat, ca marche tres bien.
Si je le stocke dans une liste, il me rajoute un 1 a la fin.
Or je ne veux pas ce 1.

AGPa, BODa, BRUa, Dept, LEIa, LISa, LTNa, MJVa, MUCa, RTMa, VLCa,1

voici ce que je fais:

open (INPUTFILE, "$InputFile") || die "Error: $InputFile - $!n";
while (<INPUTFILE>) {
next if /^#/;
chop;

@Flight = split /,/;
++$unique_value{$Flight[0]};
}
close INPUTFILE;

$DeptDestList = print " $_," for sort keys %unique_value;

print $DeptDestList;

exit;

Le fichier d'entree est au format csv.

Comment ne pas avoir ce 1 en fin de liste ?

Merci

Christian

"Ronan Le Hy" wrote in message
news:3f8ac041$0$20180$
Chris a écrit:
Mon script lit dans un fichier un grand nombre de valeurs (plus de 1600)
Parmis ces valeurs il y a plein de doublons et je dois supprimer tous
les


doublons.


Lisez vos valeurs dans un hash, et vous pourrez ensuite les récupérer
avec 'keys', par exemple :

# lecture
my %valeurs_uniques;
while(<>)
{
++$valeurs_uniques{$_};
}

# affichage des valeurs, triées par ordre lexicographique
print "valeur: $_" for sort keys %valeurs_uniques;

Pour la doc de sort et keys :
perldoc -f sort
perldoc -f keys

HTH

--
Ronan

Actually, it has always amazed me why using a dinosaur module like CGI
is considered "good programming" if all you need is parameter parsing.
Abigail




Avatar
Paul GABORIT
À (at) Mon, 13 Oct 2003 18:58:42 +0200,
"Chris" écrivait (wrote):
open (INPUTFILE, "$InputFile") || die "Error: $InputFile - $!n";


open (INPUTFILE, "$InputFile") or die "Error: $InputFile - $!n";
# on préfère souvent le 'or' au '||' pour des raisons de priorité
# et de facilité de lecture

while (<INPUTFILE>) {
next if /^#/;
chop;


chomp; # voir 'perldoc -f chomp'

@Flight = split /,/;
++$unique_value{$Flight[0]};


# En résumé (et sans stocker dans un tableau) :
++$unique_value{ (split /,/)[0] ); # (c'est du perl un peu compact ;-)

}
close INPUTFILE;

$DeptDestList = print " $_," for sort keys %unique_value;
print $DeptDestList;


# print affiche " $_," sur STDOUT
# et produit un résultat (1) - cf 'perldoc -f print'
# (Peut-être vouliez-vous utiliser 'sprintf' ?)

# Le mieux ici est d'utiliser 'join' (sauf si il y a bcp bcp de
# 'unique_value')

print join(", ", sort keys %unique_value);


exit;



--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>
Remove '.OOO' from e-mail address - Supprimez '.OOO' de l'adresse e-mail

Avatar
Paul GABORIT
À (at) Tue, 14 Oct 2003 08:57:24 +0200,
Paul GABORIT écrivait (wrote):
++$unique_value{ (split /,/)[0] ); # (c'est du perl un peu compact ;-)


compact... mais avec 'faute de frappe' :-(

++$unique_value{ (split /,/)[0] }; # (c'est du perl un peu compact ;-)

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>
Remove '.OOO' from e-mail address - Supprimez '.OOO' de l'adresse e-mail

Avatar
Ronan Le Hy
Paul GABORIT a écrit:
À (at) Mon, 13 Oct 2003 18:58:42 +0200,
"Chris" écrivait (wrote):
$DeptDestList = print " $_," for sort keys %unique_value;
print $DeptDestList;


# print affiche " $_," sur STDOUT
# et produit un résultat (1) - cf 'perldoc -f print'
# (Peut-être vouliez-vous utiliser 'sprintf' ?)

# Le mieux ici est d'utiliser 'join' (sauf si il y a bcp bcp de
# 'unique_value')

print join(", ", sort keys %unique_value);


Je me permets une suggestion de plus pour être sûr que c'est clair pour
Chris :
my @sorted_values = sort keys %unique_value;
suffit pour mettre la liste triée des valeurs dans @sorted_values (et le
sort() peut être avantageusement supprimé si le tri n'est pas nécessaire).

Et ce que vous avez écrit fait penser à un map:
my @sorted_values = map {" $_,"} sort keys %unique_value;

Ensuite, on peut imprimer ça avec print et (join ou for), ou en faire
autre chose.

HTH

--
Ronan

What are Befunge's strengths?
It's terse and small.


Abigail in clpm


Avatar
Paul GABORIT
Paul GABORIT a écrit:
print join(", ", sort keys %unique_value);



À (at) Tue, 14 Oct 2003 10:20:53 +0200,
Ronan Le Hy écrivait (wrote):
Et ce que vous avez écrit fait penser à un map:
my @sorted_values = map {" $_,"} sort keys %unique_value;


Sauf que 'join' a cette particularité de traiter correctement le problème des
arbres et des espaces entre les arbres :
pour un alignement de n arbres il y a (n - 1) espaces entre les arbres ;-)

Pour les virgules dans une liste, c'est la même chose. Il y a toujours une
virgule de moins que d'éléments. Votre 'map' ne fait donc pas la même chose...

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>
Remove '.OOO' from e-mail address - Supprimez '.OOO' de l'adresse e-mail


Avatar
Ronan Le Hy
Paul GABORIT a écrit:
Paul GABORIT a écrit:
print join(", ", sort keys %unique_value);
À (at) Tue, 14 Oct 2003 10:20:53 +0200,


Ronan Le Hy écrivait (wrote):

Et ce que vous avez écrit fait penser à un map:
my @sorted_values = map {" $_,"} sort keys %unique_value;



Ce "vous", c'est Chris, pas Paul. Je n'ai pas de doutes sur la maîtrise
de Perl de Paul.

Sauf que 'join' a cette particularité de traiter correctement le problème des
arbres et des espaces entre les arbres :
pour un alignement de n arbres il y a (n - 1) espaces entre les arbres ;-)


Sauf que vous avez coupé le bout de code de Chris auquel je faisais
allusion, qui disait:
$DeptDestList = print " $_," for sort keys %unique_value;
et qui, me semble-t-il, montrait l'intention de faire un map.

Bien sûr, ça n'est pas forcément joli d'avoir des virgules au bout des
phrases (et un espace au début), mais ça n'était pas le problème que je
visais,

--
Ronan

Agreed.
Abigail in clpm



Avatar
Chris
Merci a PAul et Ronan,

Mon tri de list foest maintenant correct et je n'ai pas de virgule en trop
en fin de liste.

Merci de votre aide

Cordialement

Christian

"Ronan Le Hy" wrote in message
news:3f8bc4fa$0$13306$
Paul GABORIT a écrit:
Paul GABORIT a écrit:
print join(", ", sort keys %unique_value);
À (at) Tue, 14 Oct 2003 10:20:53 +0200,


Ronan Le Hy écrivait (wrote):

Et ce que vous avez écrit fait penser à un map:
my @sorted_values = map {" $_,"} sort keys %unique_value;



Ce "vous", c'est Chris, pas Paul. Je n'ai pas de doutes sur la maîtrise
de Perl de Paul.

Sauf que 'join' a cette particularité de traiter correctement le
problème des


arbres et des espaces entre les arbres :
pour un alignement de n arbres il y a (n - 1) espaces entre les
arbres ;-)



Sauf que vous avez coupé le bout de code de Chris auquel je faisais
allusion, qui disait:
$DeptDestList = print " $_," for sort keys %unique_value;
et qui, me semble-t-il, montrait l'intention de faire un map.

Bien sûr, ça n'est pas forcément joli d'avoir des virgules au bout des
phrases (et un espace au début), mais ça n'était pas le problème que je
visais,

--
Ronan

Agreed.
Abigail in clpm