Insérer tableau dans tableau associatif
Fermé
blux
Messages postés
26450
Date d'inscription
dimanche 26 août 2001
Statut
Modérateur
Dernière intervention
6 novembre 2024
-
Modifié par blux le 2/01/2015 à 18:02
blux Messages postés 26450 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 6 novembre 2024 - 8 janv. 2015 à 17:04
blux Messages postés 26450 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 6 novembre 2024 - 8 janv. 2015 à 17:04
A voir également:
- Insérer tableau dans tableau associatif
- Tableau croisé dynamique - Guide
- Code ascii tableau - Guide
- Tableau word - Guide
- Trier tableau excel - Guide
- Insérer une vidéo dans powerpoint - Guide
2 réponses
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
5 janv. 2015 à 17:38
5 janv. 2015 à 17:38
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 :
Ensuite, pour intégrer ton tableau à ton hash, tu dois pouvoir faire :
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 :
cela donne :
mais cela a l'air très compliqué ta structure de données.
Dal
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
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
Modifié par [Dal] le 6/01/2015 à 12:54
Modifié par [Dal] le 6/01/2015 à 12:54
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 :
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,
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
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
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 => \@failuresclone 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
blux
Messages postés
26450
Date d'inscription
dimanche 26 août 2001
Statut
Modérateur
Dernière intervention
6 novembre 2024
3 312
Modifié par blux le 6/01/2015 à 13:46
Modifié par blux le 6/01/2015 à 13:46
Et comment fais-je pour savoir combien occurrences de failures pour un $park donné ?
Si tu veux vraiment avoir le vrai projet, je peux te le passer en MP...
Si tu veux vraiment avoir le vrai projet, je peux te le passer en MP...
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
Modifié par [Dal] le 6/01/2015 à 14:36
Modifié par [Dal] le 6/01/2015 à 14:36
C'est confus car tu dis "$park".. park est un hash %park qui contient tous les matériels.
Si tu veux avoir la somme de toutes les anomalies pour le parc informatique tous matériels confondus, tu énumères les clefs du hash %park et tu cumules dans une boucle le nombre d'éléments de chaque array @failures contenu dans chaque hash accessible par chaque clef.
Par exemple :
La ligne 4 ci-dessus, utilise le fait qu'en Perl, utiliser un array dans un contexte scalaire, permet d'obtenir le nombre d'éléments de l'array.
Si tu veux juste le nombre d'anomalies pour un matériel donné, tu accèdes directement au bon matériel, et tu n'as pas besoin de boucle : tu utilises juste la référence au array en tant que scalaire, en prenant soin de la déréférencer préalablement comme ci-dessus avec
Dal
Si tu veux avoir la somme de toutes les anomalies pour le parc informatique tous matériels confondus, tu énumères les clefs du hash %park et tu cumules dans une boucle le nombre d'éléments de chaque array @failures contenu dans chaque hash accessible par chaque clef.
Par exemple :
my $total_failures = 0; while ( my ($serial_num, $inner_hash) = each(%park) ) { $total_failures = $total_failures + scalar(@{$park{$serial_num}{failures}}); } print "total_failures = $total_failures\n";
La ligne 4 ci-dessus, utilise le fait qu'en Perl, utiliser un array dans un contexte scalaire, permet d'obtenir le nombre d'éléments de l'array.
Si tu veux juste le nombre d'anomalies pour un matériel donné, tu accèdes directement au bon matériel, et tu n'as pas besoin de boucle : tu utilises juste la référence au array en tant que scalaire, en prenant soin de la déréférencer préalablement comme ci-dessus avec
@{ ... }(pour que Perl sache que c'est un array).
my $failures_for_123456; $failures_for_123456 = scalar(@{$park{"123456"}{failures}});
scalar()est utilisé à des fins de lisibilité, sinon, il suffit de faire ceci pour utiliser l'array comme scalaire et obtenir le nombre de ses éléments :
$failures_for_123456 = @{$park{"123456"}{failures}};
Dal
blux
Messages postés
26450
Date d'inscription
dimanche 26 août 2001
Statut
Modérateur
Dernière intervention
6 novembre 2024
3 312
6 janv. 2015 à 14:43
6 janv. 2015 à 14:43
Ca s'éclaircit !
Je vais voir comment je peux tourner tout ça...
Merci.
Je vais voir comment je peux tourner tout ça...
Merci.
blux
Messages postés
26450
Date d'inscription
dimanche 26 août 2001
Statut
Modérateur
Dernière intervention
6 novembre 2024
3 312
6 janv. 2015 à 15:53
6 janv. 2015 à 15:53
Ca coince, car je veux que failures ait deux champs...
Comment puis-je le déclarer et/ou le remplir lors du push $park ?
Comment puis-je le déclarer et/ou le remplir lors du push $park ?
blux
Messages postés
26450
Date d'inscription
dimanche 26 août 2001
Statut
Modérateur
Dernière intervention
6 novembre 2024
3 312
6 janv. 2015 à 16:31
6 janv. 2015 à 16:31
en plus, je n'arrive pas à faire l'insertion :
J'ai l'erreur :
Type of arg 1 to push must be array (not hash element) at cumul.pl line 32, near "$ANC_CLI ;"
push $TAB_GRP{$GRP}{TAILLE},$ANC_CLI ;
J'ai l'erreur :
Type of arg 1 to push must be array (not hash element) at cumul.pl line 32, near "$ANC_CLI ;"
5 janv. 2015 à 18:15
Mes noms de variables sont plutôt parlants habituellement !
Cette structure de données est juste pour simuler une relation 1-n telle qu'on la conçoit dans une base de données.
Pour récupérer le tableau inséré dans ma cellule, je suis obligé de passer par le tableau 'conteneur' via le paquet de 4 indices ou je peux l'extraire et le mettre ailleurs ?
5 janv. 2015 à 19:25
Mais si ce que tu demandes c'est : est-ce que je peux me servir de la référence stockée dans le hash d'une autre façon qu'à partir du hash, la réponse est oui.
Tu peux le faire à partir du tableau d'origine, comme montré par le code d'exemple, ou tu peux copier cette référence dans une autre variable et déréfécencer à partir de là.
Tu peux aussi créer directement un tableau dans ton hash, sans avoir à créer un tableau préexistant, y pousser les valeurs avec push, et récupérer une référence à ce tableau pour gérer ce contenu indépendamment du hash.
Dal
Modifié par blux le 6/01/2015 à 11:55
Ce que je veux, c'est mettre un tableau différent pour chaque 'ligne' de mon tableau hashé.
Lorsque je vais relire mon tableau hashé, je veux récupérer le tableau qui est rattaché à chaque 'ligne'. C'est plus clair ?
exemple :
un tableau de hash pour un matériel informatique avec toute une série d'infos uniques (type, date d'achat, ram, dd...) ET pour chaque matériel la liste de ses pannes, par exemple. Donc tableau des pannes inséré dans la cellule qui va bien du tableau de hash.
Quand je relis mon tableau de hash, je récupère mes infos 'matériel' et je veux aussi boucler sur toutes les pannes de chaque matériel.
Pour le reste de tes explications, je veux bien un 'tit exemple, si c'est pas abuser...
Tu peux le faire à partir du tableau d'origine, comme montré par le code d'exemple, ou tu peux copier cette référence dans une autre variable et déréfécencer à partir de là.
Tu peux aussi créer directement un tableau dans ton hash, sans avoir à créer un tableau préexistant, y pousser les valeurs avec push, et récupérer une référence à ce tableau pour gérer ce contenu indépendamment du hash.
Et comment puis-je faire pour parcourir le tableau que j'ai référencé ? Comment obtenir sa taille (fonction scalar ?)
<edit>
bon, j'ai fini par trouver la bonne syntaxe !
Mais comme j'ai omis de dire que $arr est réinitialisé pour chaque ligne de $hash (je veux un tableau avec des valeurs différentes) seule la dernière 'version' de mon $arr est stockée dans toutes les lignes de $hash.
Je veux créer un tableau $arr différent pour chaque ligne de $hash et récupérer le $arr qui correspond à ce que j'ai mis lors du remplissage à mon parcours final de $hash
Et là, ça coince...
6 janv. 2015 à 11:14
6 janv. 2015 à 12:39
C'est juste, comme je l'expliquais, pour simuler une relation 1-n de bases de données, si le concept t'est familier...