Matching two arrays, and returning the "rest"

P

petersson

Hi,

I have two arrays. The first one contains a list of items. For
example:

abc
bca
bac
cab
acb

My second one contains fewer items, but parts of the individual items
match with the items in my first array.

12_bca
21_acb
22_cab

Hence that the "bca" in "12_bca" above matches with the single "bca"
in my first array, like this:

abc
bca : 12_bca
bac
cab : 22_cab
acb : 21_acb

Now I want a function that returns the items from my first array that
doesn't partially match any of the items in my second array. Like
this:

abc
bac

Note: the example above is extremely simplified. Splitting the second
array on the "_" sign won't work... Anyone done this before? Knows of
a simple solution?

Thanks in advance

/s
 
B

Ben Morrow

Hi,

I have two arrays. The first one contains a list of items. For
example:

abc
bca
bac
cab
acb

I'll call this @a1, since you didn;t give it a name.
My second one contains fewer items, but parts of the individual items
match with the items in my first array.

12_bca
21_acb
22_cab

and this @a2
Hence that the "bca" in "12_bca" above matches with the single "bca"
in my first array, like this:

abc
bca : 12_bca
bac
cab : 22_cab
acb : 21_acb

Now I want a function that returns the items from my first array that
doesn't partially match any of the items in my second array. Like
this:

abc
bac

grep { my $x = qr|\Q$_|; 0 == grep $x, @a2 } @a1; #untested

Ben
 
B

Brian McCauley

Ben Morrow said:
grep { my $x = qr|\Q$_|; 0 == grep $x, @a2 } @a1; #untested

You are missing / /

grep { my $x = qr|\Q$_|; 0 == grep /$x/, @a2 } @a1; #still untested

IMHO it looks neater as:

grep { my $x = qr/\Q$_/; ! grep /$x/, @a2 } @a1; #still untested

Of course it's probably faster to use index rather than m//

grep { my $x = $_; ! grep index($_,$x) > -1, @a2 } @a1; #still untested

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
B

Ben Morrow

Brian McCauley said:
You are missing / /

D'oh! I took it out automatically when I thought 'why not use qr//?'.
IMHO it looks neater as:

grep { my $x = qr/\Q$_/; ! grep /$x/, @a2 } @a1; #still untested
Agreed.

Of course it's probably faster to use index rather than m//

grep { my $x = $_; ! grep index($_,$x) > -1, @a2 } @a1; #still untested

I would hope that this would come down to the same thing when using
qr// and no regex metachars...

[formatting adjusted]
% perl -MBenchmark=cmpthese -e'my @a = 1..10_000;
cmpthese -10, {
qr => sub { my $x = qr/\Q4/; grep /$x/, @a },
index => sub { grep index($_, '4') > -1, @a }
}'
Benchmark: running index, qr for at least 10 CPU seconds...
index: 13 wallclock secs (10.57 usr + 0.00 sys = 10.57 CPU) @
137.18/s (n=1450)
qr: 12 wallclock secs (10.56 usr + 0.00 sys = 10.56 CPU) @
98.48/s (n=1040)
Rate qr index
qr 98.5/s -- -28%
index 137/s 39% --

....but it seems you are right :). Moving the qr// outside the cmpthese
makes no difference.

Ben
 
C

Chris Charley

Hi,

I have two arrays. The first one contains a list of items. For
example:

abc
bca
bac
cab
acb

My second one contains fewer items, but parts of the individual items
match with the items in my first array.

12_bca
21_acb
22_cab

Hence that the "bca" in "12_bca" above matches with the single "bca"
in my first array, like this:

abc
bca : 12_bca
bac
cab : 22_cab
acb : 21_acb

Now I want a function that returns the items from my first array that
doesn't partially match any of the items in my second array. Like
this:

abc
bac

Note: the example above is extremely simplified.
Hi
The following will do it :)

#!/usr/bin/perl
use strict;
use warnings;

my @a1 = qw /abc bca bac cab acb/;
my @a2 = qw /12_bca 21_acb 22_cab/;

my @unseen;
for my $first (@a1) {
my $idx;
for my $second (@a2) {
$idx = index($second, $first);
last unless $idx == -1;
}
push @unseen, $first if $idx == -1;
}
print "@unseen\n";

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top