2010-11-24 3 views
1

Ich habe diese:Perl: Erhalten Sie parallel Wert in Hash-Array

my(%arr) = (
monsters => ["Test","Test2"], 
kills => [-1, -2  ]); 

Später dann suche ich nach Test2:

if (grep { $_ eq "Test2"} @{ $arr{monsters} }) 
{ 
    #Get parallel value of Test2 (-2) 
    next; 
} 

Wie kann ich den parallel Wert erhalten, ohne den Index zu kennen (ein tatsächliches Variable wird bei der Suche verwendet und nicht ein String-Literal)?

Antwort

4

Versuchen einen Hash von Hashes:

my %arr = (
    'Test' => { 
    'kills' => -1, 
    }, 
    'Test2' => { 
    'kills' => -2, 
    }, 
); 

print $arr{'Test2'}{'kills'}, "\n"; 
+1

Wie würde ich das durchlaufen, um es zu drucken? Vergiss es, ich habe es verstanden: while (($ k, $ v) = jeder% arr) { print "$ k =>", $ arr {"$ k"} {"kills"}, "\ n" ; } – Zeno

+1

Sicher oder so ähnlich: foreach (Sortierschlüssel% arr) {print "$ _ = $ arr {$ _} {'kills'} \ n"; } – dmah

+0

Was ist mit Sortieren nach Kills? – Zeno

5

Anstatt eine grep nur Schleife über den Array und eine Zählvariable halten:

for my $idx(0 .. $#{ $arr{monsters} }) { 
    if ($arr{monsters}[$idx] eq 'Test2') { 
     print "Kills = $arr{kills}[$idx]\n"; 
     last; 
    } 
} 

Ein besserer Weg, dies zu handhaben, jedoch könnte sein, Ihre Datenstruktur zu überdenken. Anstelle von parallelen Anordnungen, ein Array von Hashes betrachten:

my @monsters = ({ name => 'Test', kills => -1 }, { name => 'Test2', kills => -2 }); 

, nun ein bestimmtes Monster zu finden:

my ($monst) = grep { $_->{name} eq 'Test2' } @monsters; 
print $monst->{kills}; 

Dies würde ermöglichen es Ihnen, die Suche nach Namen und ebenso leicht tötet. Wenn du immer nach dem Namen suchst, dann ist es vielleicht besser, einen Hash auf den Namen zu setzen und auf die Anzahl der Kills zu zeigen (wie es @dmah vorschlägt).

Ein noch besserer Weg, damit umzugehen, wäre es, deine Monster in einer Klasse zu verpacken und jedes Objekt über seine eigenen Tötungen im Auge zu behalten, aber ich überlasse das als Übung für das OP.