# 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
>

```