Phoenix.pm: map + grep problem

Scott Walters scott at illogics.org
Mon May 5 11:13:10 CDT 2003


On  0, Victor Odhner <vodhner at cox.net> wrote:
> 
> Here's a really basic Perl construct that for some reason I've never 
> used.  In this case I'm trying to take the intersection of two arrays, 
> and this seemed appropriate to me:
> 
>   @a1=(a,b,c,d);
>   @a2=(b,d,f);

I assume that a, b, c, d etc are variables or quoted strings or you're really doing something like:
  @a1 = qw(a b c d);

>   print( ( map{grep /^$_$/, @a2} @a1 ), "\n");

map{} and grep{} each localize $_. You have to copy the data at one point as access
to the previous $_ will be hidden.

  print(map({ my $x = $_; grep { $_ eq $x } @a2 } @a1), "\n");

...would be closer to the mark.

However, the Cookbook will probably tell you to use hashes - then you can do a hashed
(very quick access to a given element) rather than looping through each and every element
of an array:

  # (1, 2, 3, 4) -> ( 1=>1, 2=>1, 3=>1, 4=>1 ) - just make keys exist for each element
  %a2 = map { $_ => 1 } @a2;

  foreach my $i (@a1) {
    if(exists $a2{$i}) {
      print "a1 and a2 both have the element '$i'\n";
    }
  }

-scott



> 
> What I get is bdfbdfbdfbdf.
> 
> It doesn't seem that $_ is being set to each element
> of @a1 and then grepped against @a2.
> 
> Can anybody explain my blind spot here?
> 
> Again, I just want a list that is the intersection
> of the two lists.  Of course I can run a loop, but
> "map" seems a nice tight way to do the job.
> 
> Vic
> 



More information about the Phoenix-pm mailing list