skeniver
skeniver

Reputation: 2647

In Perl, how can I transform an array of hashes in to an array of values?

I have an array of hashes:

my @sports;
push @sports, { id=>1, name=>'Rugby' };
push @sports, { id=>2, name=>'Football' };

and I want to get an array of all the names (to display in a CGI popup menu). I tried using this grep statement:

my @names = grep { $_->{name} } @sports;

but it just returns an array of hash values...

So I am currently resorting to using a loop to iterate through all the values, pushing them into another array.

Is there a way to speed this up?

Upvotes: 2

Views: 168

Answers (4)

Lumi
Lumi

Reputation: 15264

You want map, not grep:

use strict;
use warnings;
my @sports;
push @sports, { id=>1, name=>'Rugby' };
push @sports, { id=>2, name=>'Football' };
my @names = map $_->{name}, @sports;
print for @names;
D:\temp> perl -l m.pl
Rugby
Football

But note this doesn't have anything to do with speed, at least not in a significant way, and speed shouldn't be your primary concern; readability should be it. Of course, efficiency is important, but don't let yourself be fooled into thinking that the more concise and cryptic your code the better your program's performance. This is not so. To assess performance, benchmark your programs.

Upvotes: 7

flesk
flesk

Reputation: 7579

The solution is trivial if you've really hard coded the populating of @sports as in your example:

my (@sports, @names);
push @sports, { id=>1, name=>'Rugby' };
push @names, 'Rugby';
push @sports, { id=>2, name=>'Football' };
push @names, 'Football';

This avoids the second loop altogether.

Upvotes: 0

run
run

Reputation: 1186

for my $i ( 0 .. $#sports) {  
     print "$sports[$i]{name} \n";    
}

infact you can also use map function to loop through

Upvotes: 0

Tom Melly
Tom Melly

Reputation: 108

my @sports;
push @sports, { id=>1, name=>'Rugby' };
push @sports, { id=>2, name=>'Football' };
foreach(@sports){
  push @names, $_->{'name'};
}
foreach(@names){
  print "$_\n";
}

Ah, sorry - reread your post. TBH, however you write it, I suspect that internally a loop will be taking place anyway. Are you sure you're not trying to prematurely optimise? Is there a performance issue?

Upvotes: 0

Related Questions