http://qs321.pair.com?node_id=264346

harry34 has asked for the wisdom of the Perl Monks concerning the following question:

how could I write code to check how many times items in array 1 are present in array 2
e.g if @array_1 =A B
e.g if @array_2 =A B C D A D B A C

cheers

update (broquaint): title change (was array)

Replies are listed 'Best First'.
Re: Code requested for array intersection count
by edan (Curate) on Jun 09, 2003 at 15:19 UTC
Re: Code requested for array intersection count
by tcf22 (Priest) on Jun 09, 2003 at 15:16 UTC
Try using grep.
```my @a1 = qw( A B );
my @a2 = qw( A B C D A D B A C );

foreach my \$el(@a1){
my \$count = grep /^\$el\$/, @a2;
print "\$el is in Array2 \$count times\n";
}
produces
```A is in Array2 3 times
B is in Array2 2 times
Re: Code requested for array intersection count
by dvergin (Monsignor) on Jun 09, 2003 at 15:26 UTC
As 3dan notes, this question has been asked and answered many times. But just for fun, here's a quick (tested) solution that takes a different approach from that of tcf22. This leaves a hash (%counts) with all the results available for later processing. (tcf22's approach could be adjusted to do that also.)
```#!/usr/bin/perl -w
use strict;

my @array_1 = qw/A B/;
my @array_2 = qw/A B C D A D B A C/;

my %check_1 = map { \$_ => 1 } @array_1;
my %counts;
map { \$counts{\$_}++ if \$check_1{\$_} } @array_2;

print "\$_ : \$counts{\$_}\n" for keys %counts;
Which results in:

A : 3
B : 2

------------------------------------------------------------
"Perl is a mess and that's good because the
problem space is also a mess.
" - Larry Wall

Re: Code requested for array intersection count
by Fletch (Chancellor) on Jun 09, 2003 at 15:25 UTC

Strictly speaking he doesn't want the intersection. He wants to put the elements from @array_2 into a bag (Set::Bag) but only if they're present in @array_1.

```my %wanted = map { \$_, 1 } @array_1;
my \$bag = Set::Bag->new( );
foreach( @array_2 ) {
\$bag->insert( \$_ => 1 ) if \$wanted{ \$_ };
}
Re: Code requested for array intersection count
by sauoq (Abbot) on Jun 09, 2003 at 15:43 UTC

As you don't care how many times the items are in array 1, I'd use a hash rather than multiple greps. A hash will make it an O(M + N) algorithm, the greps are an O(M x N) solution. Of course, this will use more memory too and you should take that into consideration when choosing which to use.

```my %seen;
@seen{@array_1} = (0) x @array_1;
exists( \$seen{\$_} ) and \$seen{\$_}++ for @array_2;

```-sauoq
"My two cents aren't worth a dime.";
```
Re: Code requested for array intersection count
by toma (Vicar) on Jun 09, 2003 at 23:58 UTC
Here's a forward-looking approach:
```use Quantum::Superpositions;

my @arr1= qw (two two three five four six six six seven);
my @arr2= qw (one one three four bee seven eight six);

my @intersection = eigenstates(any(@arr1) eq any(@arr2));

print "There are ",scalar(@intersection)," common elements\n";
print "Values: @intersection\n";
It should work perfectly the first time! - toma
Re: Code requested for array intersection count
by ChOas (Curate) on Jun 11, 2003 at 10:21 UTC
And just to do it one more different way :)
```#!/usr/bin/perl -w
use strict;
my @array_1 = qw/A B X/;
my @array_2 = qw/A B C D A D B A C/;
my %Seen;

++\$Seen{\$_} for @array_2;
print "\$_ : ",exists \$Seen{\$_}||0,"\n" for @array_1