IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Table de hachage avec comme clé une date et comme valeur un tableau


Sujet :

Langage Perl

  1. #1
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut Table de hachage avec comme clé une date et comme valeur un tableau
    Bonjour,

    Je parts d'un tableau contenant des données de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ["24/11/2007", "a", 1, 2, 3, 4];
    ["24/11/2007", "b", 5, 6, 7, 8];
    ["24/11/2007", "c", 9, 10, 11, 12];
    ["25/11/2007", "d", 10, 20, 30, 40];
    ["25/11/2007", "e", 50, 60, 70, 60];
    Je souhaite obtenir une table de hachage qui pour une date donnée lui associerait comme valeur un tableau dont les valeurs sont des références vers d'autres tableaux.
    Et donc, en partant des données que j'ai pris comme exemple, j'obtiendrais comme affichage en sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    24/11/2007 : a 1 2 3 4
    b 5 6 7 8
    c 9 10 11 12
    25/11/2007 : d 10 20 30 40
    e 50 60 70 60
    Voici le code que j'ai écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #!usr/bin/perl -w
    use strict;
     
    my $ref1 = ["24/11/2007", "a", 1, 2, 3, 4];
    my $ref2 = ["24/11/2007", "b", 5, 6, 7, 8];
    my $ref3 = ["24/11/2007", "c", 9, 10, 11, 12];
    my $ref4 = ["25/11/2007", "d", 10, 20, 30, 40];
    my $ref5 = ["25/11/2007", "e", 50, 60, 70, 60];
     
    #insertion des données dans le tableau
    my @tab = ();
    push(@tab, $ref1);
    push(@tab, $ref2);
    push(@tab, $ref3);
    push(@tab, $ref4);
    push(@tab, $ref5);
     
     
    #table de hachage avec comme clé une date et comme valeur une référence vers un tableau
    my %date_tab = ();
     
    #reference vers un tableau
    my $ref;
     
    #parcours du tableau pour récupérer les infos à ajouter dans la table de hachage
    foreach my $datas(@tab){
    	$ref = [$$datas[1], $$datas[2], $$datas[3], $$datas[4], $$datas[5]];
    	$date_tab{$$datas[0]} = [$ref];
    }
     
    while(my ($cle,$valeur) = each(%date_tab)){
       print "$cle : ";
       foreach my $data(@$valeur){
    		print "$$data[0] $$data[1] $$data[2] $$data[3] $$data[4]\n";
       }
    }
    Le soucis que j'ai, c'est que je n'arrive pas à savoir comment faire pour ne pas écrasé les données pour obtenir ce que je souhaite.

    En sortie, j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    25/11/2007 : e 50 60 70 60
    24/11/2007 : c 9 10 11 12
    Merci

  2. #2
    Membre chevronné
    Avatar de Woufeil
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 1 076
    Points : 2 004
    Points
    2 004
    Par défaut
    Bonjour,

    A une clé, tu associes un tableau contenant un autre tableau. L'astuce va être la suivante : je te propose d'associer à une clé un tableau contenant autant de tableau que tu as de ligne par date. Pour cela, il faut agir sur le premier foreach. Tu testes l'existence de la clé à chaque tour de boucle. Si elle existe n'existe pas, on se retrouve dans le cas que tu as programmé. Si elle existe, il te suffit de rajouter $ref dans ton tableau déjà présent. Voilà comment tu pourrais modifier ton foreach :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    foreach my $datas(@tab){
    	$ref = [$$datas[1], $$datas[2], $$datas[3], $$datas[4], $$datas[5]];
    	if ((exists $date_tab{$$datas[0]})) {
    		push (@{$date_tab{$$datas[0]}}, $ref);
    	}		
    	else { 
    		$date_tab{$$datas[0]} = [$ref];
    	}
    }
    Je te conseille de vérifier le résultat à l'aide du module Data:: Dumper par print Dumper( %date_tab);

    Dis nous si ça te convient
    "En essayant continuellement, on finit par réussir. Donc : plus ça rate, plus on a de chances que ça marche" (devise Shadock)
    Application :

    ainsi qu'à regarder la avant de poser une question.

    La rubrique Perl recrute, contactez-moi.

  3. #3
    Membre confirmé
    Avatar de Schmorgluck
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    371
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2006
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    Étant donné que la clé d'un hachage est unique, que la même date peut apparaître plusieurs fois dans les données, et que tes données sont sous forme de tableaux, tu dois utiliser, pour ce que tu veux faire, un hachage contenant des références à des tableaux de références à des tableaux. Ou, pour dire les choses plus simplement (hum), un hachage de tableaux de tableaux. Ce n'est pas exagérément compliqué à faire, mais c'est un brin délicat et demande un peu de concentration (comme toujours en info dès qu'on travaille avec des références ou des pointeurs).

    Voici comment je procéderais pour remplir ce hachage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    my %date_tab;
     
    foreach my $entry(@tab)
    {
    # on récupère les données, séparant au passage la date du reste
            my ($date,@data)= @$entry;
    # Si elle n'existe pas encore, on initialise l'entrée du hash correspondant à la date
    # avec une référence anonyme à une liste vide.
            $date_tab{$date}=[] unless(exists $date_tab{$date});
    # on AJOUTE une référence vers @data au tableau référencé par $date_tab{$date}
            push @{$date_tab{$date}}, \@data;
    }
    J'ai mis "ajoute" en majuscule dans le dernier commentaire parce que c'est précisément le problème de ta version, notemment cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $date_tab{$$datas[0]} = [$ref];
    où tu remplaces les données préexistantes s'il y en avait déjà.
    There's nothing like $HOME!

  4. #4
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Citation Envoyé par Woufeil Voir le message
    Bonjour,

    A une clé, tu associes un tableau contenant un autre tableau. L'astuce va être la suivante : je te propose d'associer à une clé un tableau contenant autant de tableau que tu as de ligne par date. Pour cela, il faut agir sur le premier foreach. Tu testes l'existence de la clé à chaque tour de boucle. Si elle existe n'existe pas, on se retrouve dans le cas que tu as programmé. Si elle existe, il te suffit de rajouter $ref dans ton tableau déjà présent. Voilà comment tu pourrais modifier ton foreach :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    foreach my $datas(@tab){
    	$ref = [$$datas[1], $$datas[2], $$datas[3], $$datas[4], $$datas[5]];
    	if ((exists $date_tab{$$datas[0]})) {
    		push (@{$date_tab{$$datas[0]}}, $ref);
    	}		
    	else { 
    		$date_tab{$$datas[0]} = [$ref];
    	}
    }
    Je te conseille de vérifier le résultat à l'aide du module Data:: Dumper par print Dumper( %date_tab);

    Dis nous si ça te convient
    Avec ta proposition de boucle, j'obtiens avec Data:: Dumper, cet affichage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    $VAR1 = '25/11/2007';
    $VAR2 = [
              [
                'd',
                10,
                20,
                30,
                40
              ],
              [
                'e',
                50,
                60,
                70,
                60
              ]
            ];
    $VAR3 = '24/11/2007';
    $VAR4 = [
              [
                'a',
                1,
                2,
                3,
                4
              ],
              [
                'b',
                5,
                6,
                7,
                8
              ],
              [
                'c',
                9,
                10,
                11,
                12
              ]
            ];
    Ca correspond à ce que j'attendais. Merci.

  5. #5
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Citation Envoyé par Schmorgluck Voir le message
    Étant donné que la clé d'un hachage est unique, que la même date peut apparaître plusieurs fois dans les données, et que tes données sont sous forme de tableaux, tu dois utiliser, pour ce que tu veux faire, un hachage contenant des références à des tableaux de références à des tableaux. Ou, pour dire les choses plus simplement (hum), un hachage de tableaux de tableaux. Ce n'est pas exagérément compliqué à faire, mais c'est un brin délicat et demande un peu de concentration (comme toujours en info dès qu'on travaille avec des références ou des pointeurs).

    Voici comment je procéderais pour remplir ce hachage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    my %date_tab;
     
    foreach my $entry(@tab)
    {
    # on récupère les données, séparant au passage la date du reste
            my ($date,@data)= @$entry;
    # Si elle n'existe pas encore, on initialise l'entrée du hash correspondant à la date
    # avec une référence anonyme à une liste vide.
            $date_tab{$date}=[] unless(exists $date_tab{$date});
    # on AJOUTE une référence vers @data au tableau référencé par $date_tab{$date}
            push @{$date_tab{$date}}, \@data;
    }
    J'ai mis "ajoute" en majuscule dans le dernier commentaire parce que c'est précisément le problème de ta version, notemment cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $date_tab{$$datas[0]} = [$ref];
    où tu remplaces les données préexistantes s'il y en avait déjà.
    Je vais aussi tester le code que tu proposes. Merci à vous deux pour vos réponses.

  6. #6
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Les 2 versions fonctionnent parfaitement. Encore merci

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 15/03/2013, 16h18
  2. Réponses: 6
    Dernier message: 17/05/2011, 11h40
  3. Réponses: 4
    Dernier message: 19/03/2007, 10h34
  4. Réponses: 6
    Dernier message: 26/07/2005, 10h20
  5. Requete de suppression avec en condition une date
    Par PrinceMaster77 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 29/04/2004, 09h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo