3

Given an array @A we want to check if the element $B is in it. One way is to say this:

Foreach $element (@A){
    if($element eq $B){
        print "$B is in array A";
    }
}

However when it gets to Perl, I am thinking always about the most elegant way. And this is what I am thinking: Is there a way to find out if array A contains B if we convert A to a variable string and use

index(@A,$B)=>0

Is that possible?

Nikhil Jain
  • 8,232
  • 2
  • 25
  • 47
Majic Johnson
  • 341
  • 3
  • 15
  • Related: http://stackoverflow.com/questions/7898499/grep-to-find-item-in-perl-array http://stackoverflow.com/questions/3086874/find-the-item-in-an-array-that-meets-a-specific-criteria-if-there-is-one-perl – daxim Apr 20 '12 at 07:06

3 Answers3

13

There are many ways to find out whether the element is present in the array or not:

  1. Using foreach

    foreach my $element (@a) {
        if($element eq $b) {
           # do something             
           last;
        }
    }
    
  2. Using Grep:

    my $found = grep { $_ eq $b } @a;
    
  3. Using List::Util module

    use List::Util qw(first); 
    
    my $found = first { $_ eq $b } @a;
    
  4. Using Hash initialised by a Slice

    my %check;
    @check{@a} = ();
    
    my $found = exists $check{$b};
    
  5. Using Hash initialised by map

    my %check = map { $_ => 1 } @a;
    
    my $found = $check{$b};
    
bvr
  • 9,687
  • 22
  • 28
Nikhil Jain
  • 8,232
  • 2
  • 25
  • 47
  • The List::Util::first() example is (potentially) subtly incorrect when searching for false values, since `$found` will also evaluate false. (`die unless $found` ... oops!) [List::MoreUtils::any](http://search.cpan.org/perldoc?List::MoreUtils) does the right thing here. – pilcrow May 02 '12 at 19:56
6
use 5.10.1;

$B ~~ @A and say '$B in @A';
yazu
  • 4,462
  • 1
  • 20
  • 14
  • You have to be very careful with this because this distributes the match over the elements. If @A has an array reference element that contains $B, this will still match even though $B isn't a top level element of @A. The smart match is fundamentally broken for this and many other reasons. – brian d foy Apr 20 '12 at 13:07
0
use List::AllUtils qw/ any /;
print "\@A contains $B" if any { $B eq $_ } @A;
obmib
  • 466
  • 2
  • 6
  • 2
    I would recommend `first` in this case, as it does not have to traverse whole array. It can stop when item is found. – bvr Apr 20 '12 at 07:43
  • any can stop too because it needs only one element to be true. – brian d foy Apr 20 '12 at 13:10
  • Beware that `first` can also return a false value if it finds, e.g., "0", which would confound the example given in this answer. `any` has the desired semantics. – pilcrow May 03 '12 at 01:38