paola82 has asked for the wisdom of the Perl Monks concerning the following question:
Hi dear monks,
I need two know if a element of an array is also in another array, so I found a module, array::compare, but I looked at these examples and I think...that's not ok for me, do you have any suggestions, thanks you alla
Re: comparing two array
by citromatik (Curate) on Jun 17, 2009 at 12:21 UTC
|
print +(grep {$_ eq $elem} @array) ? "Yes" : "No";
Or
my %h = map { $_ => 1 } @array;
print defined $h{$elem} ? "Yes" : "No";
Update: Changed the grep regexp by eq (see the comment below from davorg)
| [reply] [d/l] [select] |
|
print +(grep {/$elem/} @array) ? "Yes" : "No";
$ cat ./arr
#!/usr/bin/perl
my @arr = (100 .. 110);
my $elem = 11;
print +(grep { /$elem/ } @arr) ? 'Yes' : 'No';
$ ./arr
Yes$
Hmm... You might want to reconsider your idea of equality :-)
| [reply] [d/l] |
|
print exists $h{$elem} ? "Yes" : "No";
the second example? | [reply] [d/l] |
|
Considering all the values in %h are 1, it doesn't make any difference whether you use exists $h{$elem}, defined $h{$elem} or $h{$elem}.
| [reply] [d/l] [select] |
|
print defined $h{$elem} ? "Yes" : "No";
print exists $h{$elem} ? "Yes" : "No";
print $h{$elem} ? "Yes" : "No";
Are all equivalent (give the same result). exists returns true if the specified element in the hash has ever been initialized, even if its current value is undefined. In this case, all elements has been initialized to 1. If you undefine one element of the hash, for example undef $h{$elem}, then $h{$elem} still exists, but its value is undef
| [reply] [d/l] [select] |
Re: comparing two array
by si_lence (Deacon) on Jun 17, 2009 at 12:36 UTC
|
use strict;
use warnings;
my @a = (1, 3, 5, 6, 7, 8);
my @b = (2, 3, 5, 7, 9);
my (@isect, %seen, %isect);
foreach my $e (@a) { $seen{$e} = 1 }
foreach my $e (@b) {
if ( $seen{$e} ) { $isect{$e} = 1 }
}
@isect = keys %isect;
print "@isect\n";
cheers
si_lence
| [reply] [d/l] |
Re: comparing two array
by dorko (Prior) on Jun 17, 2009 at 15:47 UTC
|
use strict;
use warnings;
use List::Compare;
my @Llist = qw(abel abel baker camera delta edward fargo golfer)
+;
my @Rlist = qw( baker camera delta delta edward fargo golfer
+hilton);
my $lc = List::Compare->new(\@Llist, \@Rlist);
my @intersection = $lc->get_intersection;
print join ", ", @intersection;
# Results:
# baker, camera, delta, edward, fargo, golfer
Of course, either of those two lists could consist of only one item.
Cheers,
Brent
| [reply] [d/l] |
Re: comparing two array
by bichonfrise74 (Vicar) on Jun 17, 2009 at 17:27 UTC
|
Another way of doing it...
!/usr/bin/perl
use strict;
my %list;
my @a = qw( 1 2 3 );
my @b = qw( 3 1 5 );
for my $i (@a) {
$list{$i}++ if ( grep /$i/, @b );
}
print "Results:\n" . join ", ", keys %list;
| [reply] [d/l] |
|
Are you aware that you are using unescaped data in a regular expression? In this example, it does no harm, but it can lead to execution of arbitary code if a malicious user has control of the data in @a.
Imagine @a = ( '(?{ `/bin/rm -rf /` })' );
Update:
As you don't match the entire value, but only a part, your algorithm will fail as soon as @b contains multi-digit numbers or strings with digits: Change @b to my @b = qw( 3 1 5 far2simple ); and your program will list 2 as one of the members of @b.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
| [reply] [d/l] [select] |
|
|