Zeno
Zeno

Reputation: 1839

Perl: Get parallel value in hash array

I have this:

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

Then later I search for Test2:

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

How can I get the parallel value without knowing the index (an actual variable is used when searching and not a string literal)?

Upvotes: 1

Views: 340

Answers (2)

friedo
friedo

Reputation: 67068

Rather than using a grep, just loop over the array and keep a count variable:

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

A better way to handle this, however, might be to rethink your data structure. Instead of parallel arrays, consider an array of hashes:

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

Now, to find a specific monster:

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

This would allow you to search by name and kills equally easily. If you are going to always search by name, then making a hash keyed on name and pointing to the number of kills (as @dmah suggests) might be better.

An even better way to handle this would be to wrap up your monsters in a class, and have each object keep track of its own kills, but I'll leave that as an exercise for the OP.

Upvotes: 5

dmah
dmah

Reputation: 236

Try a hash of hashes:

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

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

Upvotes: 4

Related Questions