简体   繁体   中英

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?

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 .

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?

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

infact you can also use map function to loop through

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM