Nommer un hachage par une variable scalaire
Le
Patrice Karatchentzeff
Salut,
Le titre n'est pas forcément explicite
J'ai un fichier se présentant sous la forme :
Nom Prénom info1 info2 (pour simplifier)
et je désire créer un hachage du genre
%Nom = (
Name => "Nom",
surname => "Prénom",
inf1 => "info1",
inf2 => "info2",
)
Jusqu'à là, pas de soucis
Je ne veux pas entrer à la main tous les hachages : pour cela, je crée
un tableau contenant la liste des noms du fichier et je désire me
servir de ce tableau pour créer les-dit hachages
Voici ce que j'ai (mal) pondu
sub effectif
{
my ($file) = @_; # reçoit le fameux fichier
my (@effectif, @field);
open(EFFECTIF,$file) || die "Impossible d'ouvrir le fichier $file : $!";
while(<EFFECTIF>)
{
@field=split();
push(@effectif, $field[0]); # remplit le fameux tableau
my %$field[0] = ""; # déclaration pour le pragma use
%$field[0] =
(nom => "$effectif[0]",
prenom => "$effectif[1]",
grade => "$effectif[2]",
matricule => "$effectif[3]",
);
};
close(EFFECTIF);
return (@effectif);
};
Bon, cela ne fonctionne pas Comment écrire %Nom en faisant
référence au bon scalaire du tableau ? J'ai essayé plusieurs trucs
sans y arriver
Sinon, un deuxième point : lorsque l'on use le pragma strict, on est
obligé de déclarer les variables J'ai ici un double problème :
comment déclarer ma nouvelle variable de hachage dans ce cas (création
dynamique) et comment la rendre globale (pour cela, encore, je crois
voir : il suffit de la retourner en fin de sous-programme mais cela
sous-entend de les déclarer en en-tête alors que je ne connais pas
encore leur nom).
Merci : je sais, c'est un peu tordu mais c'est pour cela que j'utilise
Perl ;-)
PK
--
|\ _,,,,,_ Patrice KARATCHENTZEFF
ZZZzz /,`.-'`' -. ;-;;,_ mailto:p.karatchentzeff@free.fr
|,4- ) )-,_. ,\ ( `'-' http://p.karatchentzeff.free.fr
'''(_/--' `-'\_)
Le titre n'est pas forcément explicite
J'ai un fichier se présentant sous la forme :
Nom Prénom info1 info2 (pour simplifier)
et je désire créer un hachage du genre
%Nom = (
Name => "Nom",
surname => "Prénom",
inf1 => "info1",
inf2 => "info2",
)
Jusqu'à là, pas de soucis
Je ne veux pas entrer à la main tous les hachages : pour cela, je crée
un tableau contenant la liste des noms du fichier et je désire me
servir de ce tableau pour créer les-dit hachages
Voici ce que j'ai (mal) pondu
sub effectif
{
my ($file) = @_; # reçoit le fameux fichier
my (@effectif, @field);
open(EFFECTIF,$file) || die "Impossible d'ouvrir le fichier $file : $!";
while(<EFFECTIF>)
{
@field=split();
push(@effectif, $field[0]); # remplit le fameux tableau
my %$field[0] = ""; # déclaration pour le pragma use
%$field[0] =
(nom => "$effectif[0]",
prenom => "$effectif[1]",
grade => "$effectif[2]",
matricule => "$effectif[3]",
);
};
close(EFFECTIF);
return (@effectif);
};
Bon, cela ne fonctionne pas Comment écrire %Nom en faisant
référence au bon scalaire du tableau ? J'ai essayé plusieurs trucs
sans y arriver
Sinon, un deuxième point : lorsque l'on use le pragma strict, on est
obligé de déclarer les variables J'ai ici un double problème :
comment déclarer ma nouvelle variable de hachage dans ce cas (création
dynamique) et comment la rendre globale (pour cela, encore, je crois
voir : il suffit de la retourner en fin de sous-programme mais cela
sous-entend de les déclarer en en-tête alors que je ne connais pas
encore leur nom).
Merci : je sais, c'est un peu tordu mais c'est pour cela que j'utilise
Perl ;-)
PK
--
|\ _,,,,,_ Patrice KARATCHENTZEFF
ZZZzz /,`.-'`' -. ;-;;,_ mailto:p.karatchentzeff@free.fr
|,4- ) )-,_. ,\ ( `'-' http://p.karatchentzeff.free.fr
'''(_/--' `-'\_)

Poser une question


Pour faire ce que tu semble vouloir faire, je te conseille plutôt un
tableau de hachage :
@effectif = ( {
Name => "Nom1",
surname => "Prénom1",
inf1 => "info11",
inf2 => "info21",
},
{
Name => "Nom2",
surname => "Prénom2",
inf1 => "info12",
inf2 => "info22",
}, .... );
Très simple à réaliser :
#!perl
sub effectif {
my $file = shift; # reçoit le fameux fichier
my (@effectif, @field);
open EFFECTIF, '<:raw', $file
or die "Impossible d'ouvrir le fichier $file : $!n";
while(<EFFECTIF>) {
@field=split;
my %personne = (nom => $field[0],
prenom => $field[1],
grade => $field[2],
matricule => $field[3],
);
push(@effectif, %personne); # remplit le fameux tableau
}
close EFFECTIF;
return @effectif;
}
__END__
Si tu veux un tableau avec juste les noms, il te suffit de faire :
my @noms = grep { $_->{nom} } @effectif;
Voir perlref pour une meilleure explication. :)
--
Jedaï
Tu veux un tableau de références de hash ?
Essaye quelque chose comme ça :
my @field;
while(<EFFECTIF>) {
my @e = split();
push @field, {
nom => shift @e,
prenom => shift @e,
inf1 => shift @e,
inf2 => shift @e,
};
}
Pour lire les noms :
print $_->{nom}, "n" for (@field);
c'est la liste des référence de hash dont l'enregistrement 'nom' est vrai.
s/grep/map/;
[...]
Effectivement, cela résout au moins mon problème...
Merci
Par contre, la question reste toujours posée... au moins pour ma
culture personnelle.
Quid du nommage du scalaire dans le hash ? Et quid du pragma ?
PK
--
| _,,,---,,_ Patrice KARATCHENTZEFF
ZZZzz /,`.-'`' -. ;-;;,_ mailto:
|,4- ) )-,_. , ( `'-' http://p.karatchentzeff.free.fr
'---''(_/--' `-'_)
Oups, j'ai eu un moment d'égarement (après quelques excellentes
bouteilles et à 23h...) ;)
Pour me faire pardonner, voici un code pour trier le tableau obtenu :
#dans l'ordre alphabétique d'abord par nom puis par prénom :
{
use locale; #pour classer 'é' comme 'e'
@effectif = sort { $a->{nom} cmp $b->{nom} or $a->prenom} cmp
$b->{prenom} } @effectif;
}
Par ailleurs je ne suis pas sûr de comprendre ce que veux dire :
Pour déclarer une variable globale, il faut utiliser our au lieu de my,
mais je ne pense pas que ce soit recommandé pour ce genre d'usage, mieux
vaut utiliser les paramêtres et les valeurs de retour. :)
--
Jedaï