Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 10 sur 10
  1. #1
    Invité de passage
    Inscrit en
    novembre 2012
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : novembre 2012
    Messages : 9
    Points : 4
    Points
    4

    Par défaut Déclarer une table hash par itération

    Bonjour,
    Je souhaiterai déclarer une nouvelle table hash par tour de boucle.
    Je pensais mettre un compteur de type :

    $i=$i+1

    Je voulais ensuite inclure ce compteur dans le nom de mon hash :

    my %h$i

    Je voudrai obtenir %h1, %h2... jusqu'à la fin de ma boucle.

    Auriez vous une idée de la façon dont il faille l'écrire?
    D'avance merci !

  2. #2
    Expert Confirmé

    Homme Profil pro Laurent R.
    Conseil - Consultant en systèmes d'information
    Inscrit en
    mai 2012
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Nom : Homme Laurent R.
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : mai 2012
    Messages : 1 320
    Points : 2 913
    Points
    2 913

    Par défaut

    Les références symboliques permettent de faire cela, mais leur utilisation est dépréciée avec les versions actuelles de Perl (et ce depuis au moins une douzaine d'années).

    Il est préférable d'utiliser un hash de hashes (ou éventiellement un taleau de hashes, si tes valeurs sont toutes numérique), ave par exempole une syntaxe de e style:

    Code :
    $hash[$i]{'toto'} = "titi";
    Mes articles sur La programmation fonctionnelle en Perl publiés sur ce site:

    ________
    Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.

  3. #3
    Invité de passage
    Inscrit en
    novembre 2012
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : novembre 2012
    Messages : 9
    Points : 4
    Points
    4

    Par défaut

    Merci pour votre réponse !
    J'ai donc essayé comme vous me l'avez conseillé, le tableau de hashes (car je n'ai que des valeurs numériques).

    Cependant quand je lui demande d'imprimer ce tableau, j'obtiens :
    HASH<0x48de10>HASH<0x4dbc10>HASH<0x4fe4f0> etc.

    Je vais essayer d'en apprendre plus sur les tableaux/hashes de hashes.

  4. #4
    Expert Confirmé

    Homme Profil pro Laurent R.
    Conseil - Consultant en systèmes d'information
    Inscrit en
    mai 2012
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Nom : Homme Laurent R.
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : mai 2012
    Messages : 1 320
    Points : 2 913
    Points
    2 913

    Par défaut

    Montre ton code, que l'on puisse t'aider à corriger ce qui ne va pas.

    Mon exemple précédent était un peu inconsistant. Il aurait fallu écrire soit un hash de hashes::

    Code :
    $hash{$i}{'toto'} = "titi";
    soit un tableau de hashes (en supposant $i toujours numérique):

    Code :
    $tableau[$i]{'toto'} = "titi";
    sachant que je donne à mes variables les noms "hash" et "tableau" uniquement pour mieux clarifier leur nature dans l'exemple; dans ton vrai cas, utilise plutôt un nom spécifiant leur contenu.
    Mes articles sur La programmation fonctionnelle en Perl publiés sur ce site:

    ________
    Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.

  5. #5
    Invité de passage
    Inscrit en
    novembre 2012
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : novembre 2012
    Messages : 9
    Points : 4
    Points
    4

    Par défaut

    Voici mon code pour le moment :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    open fichier, ">>c:/data.txt";
    my $rep = "C:/Donne";
    $i=0;
    my %f;
    opendir(REP,$rep) or die "Dossier introuvable";
    	while(defined(my $fic=readdir REP)){ 
    	$i=$i+1;
    	my $f="${rep}/$fic";
    	open FIC, "$f" or warn "$f fichier introuvable";
    		while (<FIC>){
    		chomp($_);
    		my @Tab=split("\t", $_);
    		$a=@Tab[0];
    		$b=@Tab[1];
    		$h[$i]{$a} = $b;
    		}
    	}
    Le but (dans un premier temps) est de contenir les valeurs de chaque fichier présent dans le répertoire, dans une hash.

  6. #6
    Expert Confirmé

    Homme Profil pro Laurent R.
    Conseil - Consultant en systèmes d'information
    Inscrit en
    mai 2012
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Nom : Homme Laurent R.
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : mai 2012
    Messages : 1 320
    Points : 2 913
    Points
    2 913

    Par défaut

    Bonjour,

    premier conseil: utilise toujours les pragmas suivants:

    Code :
    1
    2
    use strict;
    use warnings;
    Cela t'aider à détecter des erreurs qui tu risques de ne pas voir autrement. Par exemple, le tableau de hashes @h n'est pas déclaré (alors que tu déclares le hash %f que tu n'utilises pas).

    Deuxième point, cette syntaxe n'est pas correcte:

    Code :
    1
    2
    		$a=@Tab[0];
    		$b=@Tab[1];
    Il faut écrire:

    Code :
    1
    2
    		$a=$Tab[0];
    		$b=$Tab[1];
    Mais il y a plus simple:

    Code :
    1
    2
    		my ($a, $b) = split("\t", $_);
    		$h[$i]{$a} = $b;
    Je réécrirais aussi les lignes 5 à 9 comme suit:

    Code :
    1
    2
    3
    4
    5
    my @liste_fic = glob ("$rep/*.*");
    foreach my $fichier(@liste_fic) {
         $i ++;
         open my $FIC, "<", "$fichier" or warn "impossible ouvrir $fichier $!";
         while (<$FIC>) { # ...
    Pour l'impression, tu de donnes pas la ligne de code qui t'a donné une erreur, mais il suffit en principe d'une instruction comme celle-ci:

    Mes articles sur La programmation fonctionnelle en Perl publiés sur ce site:

    ________
    Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.

  7. #7
    Invité de passage
    Inscrit en
    novembre 2012
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : novembre 2012
    Messages : 9
    Points : 4
    Points
    4

    Par défaut

    Merci de l'aide, j'essaye ça demain et je te donne mes résultats !

  8. #8
    Invité de passage
    Inscrit en
    novembre 2012
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : novembre 2012
    Messages : 9
    Points : 4
    Points
    4

    Par défaut

    Bonjour,
    j'ai apporté les modifications que tu m'as recommandé, voici donc le code :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    use strict;
    use warnings;
    open fichier, ">>c:/data.txt";
    my $rep = "C:/Donne";
    $i=0;
    my %h;
    my @liste_fic = glob ("$rep/*.*");
    foreach my $fichier(@liste_fic) {
         $i ++;
         open my $FIC, "<", "$fichier" or warn "impossible ouvrir $fichier $!";
    		while (<FIC>){
    		chomp($_);
    		my ($a,$b)=split("\t", $_);
    		$h[$i]{$a} = $b;
    		}
    	}
    print $h[1]{350};
    En exécutant ce script, j'obtiens le message d'erreur suivant :

    Global symbol "$i" requires explicit package name at c:\tr.pl line 5.
    BEGIN not safe after errors--compilation aborted at c:\tr.pl line 7.

  9. #9
    Expert Confirmé

    Homme Profil pro Laurent R.
    Conseil - Consultant en systèmes d'information
    Inscrit en
    mai 2012
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Nom : Homme Laurent R.
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : mai 2012
    Messages : 1 320
    Points : 2 913
    Points
    2 913

    Par défaut

    Ta variable $i n'est pas déclarée (ce qui est nécessaire avec le pragma 'use strict' que je t'ai conseillé. Change simplement la ligne 5 de ton code ci-dessus comme suit:

    Tant que j'y suis, je vois au moins une seconde erreur entre les lignes 10 et 11:
    - tu ouvres le descripteur de fichier $FIC en ligne 10
    - tu utilises le descripteur de fichier FIC en ligne 11. Change la ligne 11 comme suit:

    Tu auras sans doute un problème analogue avec %h, car h est un tableau de hashes (plus exactement un tableau de références vers des hash anonymes, mais, bon, ça veut dire la même chose), donc d'abord un tableau, et devrait donc être déclaré comme: "my @h;".

    Le reste paraît correct à vue de nez, mais je te conseillerais d'utiliser des noms de variables plus parlants. Par exemple:

    Code :
    my ($a,$b)=split("\t", $_);
    n'est pas très explicite. Ton code serait bien mieux auto-documenté si tu remplaçais $a et $b par des noms de variables décrivant le contenu de ces variables (comme je l'ai fait dans le code que j'ai proposé: "$fichier(@liste_fic)...", c'est bien plus clair que l'on examine chaque fichier d'une liste de fichiers). Idem pour "@h".
    Mes articles sur La programmation fonctionnelle en Perl publiés sur ce site:

    ________
    Sauf mention contraire explicite, les bouts de code que je poste en réponse à une question n'ont pas forcément été testés.

  10. #10
    Invité de passage
    Inscrit en
    novembre 2012
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : novembre 2012
    Messages : 9
    Points : 4
    Points
    4

    Par défaut

    Alors, déjà merci beaucoup pour ton aide, ça m'a permis de finir mon petit script, tout marche comme je le voulais !
    Je vais changer les noms de mes variables histoires de m'y retrouver, comme tu me le conseil, et je pourrai passer à autre chose

    Un grand merci !

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •