Reputation: 1323
Can I use 'map' or some similar function to make the codes simpler?
# $animal and @loads are pre-defined somewhere else.
my @bucket;
foreach my $item (@loads) {
push @bucket, $item->{'carrot'} if $animal eq 'rabbit' && $item->{'carrot'};
push @bucket, $item->{'meat'} if $animal eq 'lion' && $item->{'meat'};
}
Upvotes: 0
Views: 70
Reputation: 27183
This question would be easier to answer authoritatively with a bit more sample data. As it is I need to make a lot of assumptions.
Assuming:
@loads = (
{ carrot => 47, meat => 32, zebras => 25 },
{ carrot => 7, zebras => 81 },
);
and @buckets
should look like:
@buckets = ( 47, 32, 7 );
when @animals
looks like:
@animals = qw/ rabbit lion /;
Here's a maptastic approach. To understand it you will need to think in terms of lists of values as the operands rather than scalar operands:
my @animals = qw/ rabbit lion /;
my %eaten_by = (
lion => 'meat',
rabbit => 'carrot',
mouse => 'cheese',
);
# Use a "hash slice" to get a list of foods consumed by desired animals.
# hash slices let you access a list of hash values from a hash all at once.
my @foods_eaten = @eaten_by{ @animals };
# Hint: read map/grep chains back to front.
# here, start with map @loads and then work back to the assignment
my @bucket =
grep $_, # Include only non-zero food amounts
map @{$_}{@foods_eaten}, # Hash slice from the load, extract amounts of eaten foods.
map @loads; # Process a list of loads defined in the loads array
Rewritten in a verbose nested loop you get:
my @buckets;
for my $item ( @loads ) {
for my $animal ( @animals ) {
my $amount = $item{ $eaten_by{$animal} };
next unless $amount;
push @buckets, $amount;
}
}
Which one to use? It all depends on your audience--who will be maintaining the code? Are you working with a team of Perl hackers featuring 4 of the perl5porters? use the first one. Is your team composed of one or two interns that come and go with the seasons who will spend 1% of their time working on code of any kind? Use the second example. Likely, your situation is somewhere in the middle. Use your discretion.
Happy hacking!
Upvotes: 0
Reputation: 189587
Are you looking for something like this?
%foods = ( 'lion' => 'meat', 'rabbit' => 'carrot');
# ...
foreach my $item (@loads) {
push @bucket, $item->{$food{$animal}} if $item->{$food{$animal}};
}
Upvotes: 3