2009-04-25 7 views
1

Heylo encore,Perl - Comment accéder et archiver un élément qui se trouve dans un autre tableau

J'ai essayé de rendre mon programme plus facile à maintenir. J'ai un tableau que je déclare:

my @pizza = ($p1 = "Pizza One", $p2 = "Pizza Two"); 

Je avance puis aller mettre ce tableau de @Pizza dans un autre tableau, comme ceci:

my @food = (\@pizza); 

Lorsque je tente d'accéder soit p1 $ ou p2 $ via la propriété @food, je reçois une valeur renvoyée comme "Array {0x8001}" qui semble être une référence de mémoire. Qu'est-ce que j'ai essayé était ce:

$test = ${$food[$pizza[$p1]]}; 

Quel est le moyen le plus rapide d'accéder à cela? Je cherche à NE PAS utiliser d'index afin de faciliter la lisibilité du programme. pourriez-vous me pointer dans la bonne direction?

Cordialement,


Voilà ce que je suis en train de faire:

J'ai plusieurs bases de données (pour l'amour de pourparlers ceci est un exemple)

Base de données Un
Table One (D1T1) | Colonne Un | Colonne deux | Colonne trois | Colonne 4
Tableau deux (D1T2) | Colonne Un | Colonne deux | Troisième colonne

Base de données deux
Tableau un (D2T1) | Colonne Un | Colonne deux | Colonne trois
Tableau deux (D2T2) | Colonne Un | Colonne deux | Colonne trois
Tableau trois (D2T2) | Colonne Un | Colonne deux | Colonne trois

Entre ces deux bases de données il y a des informations qui sont relatives à des enregistrements particuliers à travers les deux. Ce que j'essaye de faire est de créer un tableau (chaque tableau représentera une base de données) et insérer des variables (chaque variable représentera un tableau.field dans la source de données) Une fois cela fait, je crée un tableau pour contenir tous les tableaux. (Ceux qui représentent les db) car ce tableau représentera une seule entrée à travers les deux bases de données sur lesquelles je peux alors agir. Exemple:

@ D1 = (t1.col1, t1.col4, t2.col1); @ D2 = (t1.col1, t2.col1, t3.col2, t3.col3);

@rec = (\ @ D1, \ @ D2);

Si je veux savoir ce qui se trouvait dans la base de données 2 -> Tableau 2 -> Colonne 4, quelle serait la déclaration? Dois-je utiliser des hachages à la place? J'ai une exigence pour ce tableau bidimensionnel/hash.

Toute aide est très appréciée.

MC

+1

est-il une raison que vous utilisez un tableau ici au lieu d'un hachage? Ce que vous faites dans la première ligne crée un tableau: @pizza = ("Pizza One", "Pizza Two") et deux variables $ p1 = "Pizza One", $ p2 = "Pizza Two". C'est plus ou moins où je te perds. Essayez-vous de trouver l'index de @pizza qui a la valeur $ p1? –

+4

Peut-être que ce serait mieux si vous avez arrêté et décrit la structure de données que vous essayez de construire et comment vous voulez y accéder. Quelque chose comme: Je veux une liste d'aliments ventilés par catégories telles que la pizza, et je veux que ces catégories contiennent des recettes individuelles accessibles par nom de recette (comme "Pizza hawaïenne"). Une fois que nous savons ce que vous faites avec les données, nous serons en mesure de vous aider. –

+0

Même si vous ne voulez pas expliquer votre problème à partir des principes de base et demander des solutions suggérées, au moins expliquer ce que vous pensez que vous faites avec le code que vous avez posté. Le my @pizza = ($ p1 = "Pizza One", $ p2 = "Pizza Two") a juste l'air bizarre et alors comme ce n'est pas évident ce que vous essayez de faire, il est difficile de vous orienter dans la bonne direction. –

Répondre

10

Ne sachant pas ce que vous essayez d'accomplir, quelles données vous modélisation, tout ce que je peux vous aider est la confusion de syntaxe. Il y a confusion ici sur plusieurs points.

# You wrote 
my @pizza = ($p1 = "Pizza One", $p2 = "Pizza Two"); 

Cela ne veut pas dire ce que vous voulez dire.Il fait le tableau ("Pizza One", "Pizza Two") mais il définit également $p1 pour être Pizza One et $p2 pour être Pizza Two. Je pense que vous essayez d'attribuer Pizza One à la clé p1. Je pense que vous voulez utiliser un hachage/tableau associé:

# Try a hash 
my %pizzas = (p1 => "Pizza One", p2 => "Pizza Two"); 

maintenant $pizzas{p1} est Pizza One. Sinon, il suffit de faire une liste:

# An array 
my @pizzas = ("Pizza One", "Pizza Two"); 

Et puis $pizzas[0] est Pizza One. Continuons ...

# You wrote 
my @food = (\@pizza); 

Vous essayez de faire une autre liste se référer à @pizza. Ce qui précède fait $food[0] référence à @pizza ce qui n'est pas ce que vous vouliez dire. Les références en Perl sont des scalaires et ont une syntaxe différente.

# What you probably meant 
my $food = \@pizza; 

maintenant $food->[0] est Pizza One et $food->[0] est Pizza Two.

# You wrote 
$test = ${$food[$pizza[$p1]]}; 

Il suffit d'ajouter plus d'accolades jusqu'à obtenir une sortie. Je vous recommande de lire le Perl Data Structures Cookbook. Oh, et allumer les avertissements. Ne les éteignez pas avant qu'ils ne partent tous et ne les éteignez pas parce qu'il y en a trop. Vraiment. Vraiment vraiment.

Mise à jour

« Je veux savoir ce qui a eu lieu dans la base de données 2 -> Tableau 2 -> 4 colonne quelle serait la déclaration soit »

N'utilisez pas de chiffres. Nommez-les, parce que je suis sûr qu'ils ont des noms. Alors oui, vous voulez des hachages. Supposons que Database Foo -> Table Bar -> Column Baz. Vous accéderons qui aiment ...

$values = $databases->{Foo}{Bar}{Baz}; 

ou longue main

$tables = $databases->{Foo}; 
$columns = $tables->{Bar}; 
$values = $columns->{Baz}; 

$values peut être une référence à un tableau de toutes les valeurs de foo.bar.baz, ou d'une autre clé de hachage par le clé primaire de Foo.Bar. Le plus logique dépend de ce que vous faites avec les données.

Je vais vous laisser le soin d'adapter la réponse de Chaz pour générer des hachages au lieu de tableaux.

Bien sûr, je dois demander pourquoi vider l'ensemble des deux bases de données dans une grande structure en mémoire et ensuite travailler dessus? Si vous avez des bases de données, interrogez-les. Ce sera plus rapide et plus flexible.

Nous sommes de retour à la question la plus élémentaire; qu'est-ce que vous essayez vraiment de faire?

+0

Je pense qu'il veut dire qu'il ne veut pas beaucoup de nombres magiques saupoudrés dans son code (comme $ object [1]), pour lesquels la solution est soit un hashref au lieu d'un arrayref, soit "use constant" ou "use enum" "pour déclarer des constantes pour vos index de champs. – cjm

+0

C'est exactement cjm. Les clés auxquelles j'accède doivent représenter les données qu'elles contiennent. J'ai édité l'article original pour clarifier ce que j'essaie de faire. Je pense que les références de hachage sont la voie à suivre, je google des hachages bidimensionnels pour voir si j'arrive à quelque chose. J'apprécie vraiment votre aide. –

+0

Ahh, je l'ai mal interprété comme "Je ne cherche pas à utiliser des index ..." – Schwern

0

Sur la base de ce que vous avez décrit est sonne comme vous avez besoin quelque chose comme ceci:

#!/usr/bin/perl 

use strict; 
use warnings; 

my @dbs; 
while (<DATA>) { 
    chomp; 
    if (/^Database/) { 
     push @dbs, []; 
     next; 
    } 
    my @table = split /\s*\|\s*/; 
    push @{$dbs[-1]}, [ @table[1 .. $#table] ]; 
} 

print "datbase 1, table 2, column 1: $dbs[0][1][0]\n"; 

for my $db (0 .. $#dbs) { 
    for my $table (0 .. $#{$dbs[$db]}) { 
     for my $col (0 .. $#{$dbs[$db][$table]}) { 
      print "($db, $table, $col) is $dbs[$db][$table][$col]\n"; 
     } 
    } 
} 


__DATA__ 
Database One 
Table One (D1T1) | D1T1C1 | D1T1C2 | D1T1C3 | D1T1C4 
Table Two (D1T2) | D1T2C1 | D1T2C2 | D1T2C3 

Database Two 
Table One (D2T1) | D2T1C1 | D2T1C2 | D2T1C3 
Table Two (D2T2) | D2T2C1 | D2T2C2 | D2T2C3 
Table Three (D2T2) | D2T3C1 | D2T3C2 | D2T3C3 
Questions connexes