Insérer tableau dans tableau associatif

blux Messages postés 27166 Date d'inscription   Statut Modérateur Dernière intervention   -  
blux Messages postés 27166 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,

je cherche à insérer un tableau (normal) dans une cellule d'un tableau associatif afin de pouvoir le parcourir plus tard.

Genre :

'boucle sur $i
$TAB{$i}{0} = "toto";
$TAB{$i}{1} = "1";
'boucle de remplissage de tableau
@TABLEAU[$j][0] = "titi"
@TABLEAU[$j][1] = "tata"
'fin boucle remplissage
$TAB{$i}{2} = @TABLEAU
fin boucle $i
....
'boucle sur $i
@TABLEAU = $TAB{$i}{2}
'boucle sur @TABLEAU
...
'fin boucle
'fin boucle

Mon problème est que scalar(@TABLEAU) est égal à 1 quand je veux le récupérér, donc j'ai un peu perdu des infos dans la manip...

Je dois faire une énorme bourde, mais je ne m'y connais pas assez en structures de données pour voir où...

Si quelqu'un peut m'éclairer, merci d'avance !

A+ blux
 "Les cons, ça ose tout.
C'est même à ça qu'on les reconnait"
A voir également:

2 réponses


 
Salut blux,

Il y a plusieurs problèmes.

Tu n'affectes pas correctement les valeurs du tableau.

C'est comme cela que l'on fait :

# déclaration
my @TABLEAU;

# affectation
$TABLEAU[0][0] = "titi";


Ensuite, pour intégrer ton tableau à ton hash, tu dois pouvoir faire :
$TAB{$i}{2} = \@TABLEAU;
si ce que tu veux c'est affecter une référence au tableau créé

La référence fonctionnera comme un "pointeur" dans d'autres langages : tu accèdes à la même structure de données en dé-référençant la référence.

Note que le nommage de "%TAB" pour un hash n'est pas forcément un choix très lisible.

Le code suivant illustre un exemple de mise en oeuvre :
#!/usr/bin/perl

use strict;
use warnings;

my %hash;
$hash{0}{0} = "toto";
$hash{0}{1} = "1";

my @arr;
$arr[0][0] = "titi";
$arr[0][1] = "tata";

# on assigne une référence au tableau
$hash{0}{2} = \@arr;

print "Affichage du contenu du tableau référencé :\n";
# afficher "titi"
print $hash{0}{2}[0][0] . "\n";
# afficher "tata"
print $hash{0}{2}[0][1] . "\n";

# modification d'un élément du tableau
print "modification d'un élément du tableau\n";
$arr[0][0] = "tutu";

print "Affichage après modification\n";
# l'affichage en passant par la référence affiche tutu
print $hash{0}{2}[0][0] . "\n";
# afficher "tata"
print $hash{0}{2}[0][1] . "\n";


cela donne :

Affichage du contenu du tableau référencé :
titi
tata
modification d'un élément du tableau
Affichage après modification
tutu
tata

mais cela a l'air très compliqué ta structure de données.


Dal
0

 
Salut blux,

Avec tes indications plus concrètes de structure de données de matériels d'un parc informatique avec leurs pannes respectives, je comprends mieux qu'avec des toto et des titi :-)

essayes un truc comme cela :

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

# for storing all the park
my %park;

# for adding a new hardware
sub add_hardw {
    my ($serial_num, $name, $type, $date_bought, $ram, $hd) = @_;
    my @failures;

    # adding an entry to the hash using the serial number as the key, cloning the values
    $park{$serial_num} = {
        name => $name,
        type => $type,
        date_bought => $date_bought,
        ram => $ram,
        hd => $hd,
        failures => \@failures
    };
}

print "Création d'une nouvelle entrée pour un matériel\n";
add_hardw("123456", "PC12", "desktop", "2014-02-26", "4GB", "500GB");

print "ajout de quelques pannes\n";
push $park{"123456"}{failures}, "2015-01-05 - panne du ventilateur";
push $park{"123456"}{failures}, "2015-01-06 - câble ethernet sectionné";

print "affectation d'une référence de la liste des pannes d'un matériel à un scalaire \$temp\n";
my $temp = $park{"123456"}{failures};

print "changement du libellé de la première panne en passant par %park\n";
$park{"123456"}{failures}[0] = "2015-01-05 - panne du ventilateur (coincé par un stylo)";

print "changement du libellé de la seconde panne en passant par \$temp\n";
@$temp[1] = "2015-01-06 - câble ethernet sectionné (dévoré par un rongeur)";

print "Création d'une nouvelle entrée pour un autre matériel, avec ajout d'une panne\n";
add_hardw("123457", "Imprimante YH", "imprimante", "2014-05-02", "1GB", "150GB");
$temp = $park{"123457"}{failures};
push @$temp, "2015-01-06 - l'imprimante ne s'allume plus";
                                                                                                                                                                                                                   
print Dumper(%park);

En ligne 16, les accolades à la suite du signe égal dans la création de la nouvelle entrée de hash opèrent une copie des données contenues dans les variables utilisées (locales à la fonction dans ce code) qui sont mises dans le hash (qui est une variable globale, utilisable ailleurs dans le code).

Parmi les éléments clonés, en ligne 22,
failures => \@failures
clone une référence à un tableau.

Lorsqu'une autre entrée de hash est créée en ligne 43, c'est un nouveau hash qui est ajouté, avec des données indépendantes.

On crée donc un hash de hashs, chaque hash contenu incluant une référence à un tableau (pour stocker les anomalies séquentiellement).

Le code illustre comment tu peux accéder au tableau en passant par le hash, ou par une référence au tableau stocké dans une des entrées du hash, et comment déréférencer une référence d'un tableau stockée dans un scalaire ($temp est la référence et @$temp la déréférence comme un tableau).

Cela dit, je trouve personnellement la notation
$park{"123456"}{failures}[0]
suffisamment lisible, et je ne vois pas vraiment l'intérêt de passer par une variable temporaire pour la manipulation indirecte du tableau.

J'ai aussi pris le parti de ce que %park soit un hash dans cet exemple, dont la clef est un numéro unique identifiant le matériel.


Dal
0