3

I'm new in Perl, which is the easiest way of finding out if the item exists in an array

Like in python I can do this

item = 'apple'
list = ['apple', 'banana']
if item in list:
 print item

output >>> 'apple'

In perl i can do it in this way

my $item = 'appel'
my @array = ('apple', 'banana')
for (@array){
 if ($_ eq $item){ print $item }
}

The for loop will take too long if my array has more than 100 items

1
  • 1
    Depending on how else you are using the contents of the list (and a littany of other considerations), a hash may be the better way to go. It's search will be O(1) as opposed to the O(n) approach of a list. Commented Jun 23, 2014 at 12:07

4 Answers 4

4

The core List::Util module provides a convenient alias for looping through all elements until one matches:

#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw(first);

my $item = 'apple';
my @array = ('apple', 'banana');

if (defined first {$_ eq $item} @array) {
    print $item;
}

first will stop iterating and return the match as soon as it finds one. Unfortunately, since it returns undef if no match is found, you can't use it to find if an array contains an undef value.

If you have version 1.33 or later you can use the any method which will work for undef:

use List::Util qw(any);
...
if (any {$_ eq $item} @array) {
    print $item;
}
Sign up to request clarification or add additional context in comments.

2 Comments

List::Util's any is a better idea. (Though it requires a very recent version of List::Util.) Imagine my $item = undef (that is, I'm trying to find out if undef is in the array). Your if condition will always evaluate to true, whether @array contains undef or not!
Thanks @tobyink, good to see that method added! Updated answer.
4

any method from List::MoreUtils will return true if any of the elements (stops looking further when first is found) satisfies condition.

use List::MoreUtils 'any';

my $item = 'appel';
my @array = ('apple', 'banana');

print "$item\n" if any { $_ eq $item } @array;

or using hash slice to make fast lookup,

my %look;
@look{@array} = ();
print "$item\n" if exists $look{$item};

Comments

4

Note that Python's in operator also loops over the list, but does so in optimized C code, so you don't notice the slowness for small to moderate lists. Linear search of large lists will take a noticeable amount of time, no matter the language.

Built-in Perl function closest to the in operator is the grep built-in. grep {$_ eq $item} @array in a scalar context will return a true value if $item is found inside the array. In your case:

my $item = 'apple';
my @array = ('apple', 'banana');
if (grep {$_ eq $item} @array) {
  print $item, "\n";
}

Python's in operator can also be defined by containers such as dict to use container-specific lookup more efficient than linear search. The Perl equivalent of this usage of in is the exists function.

Comments

2

If you want to find out if an item exists in a list of items, then an array is the wrong data structure to use. You should be using a hash.

Of course, it's simple enough to create the hash from an array.

my %hash = map { $_ => 1 } @array;

# Then checking for existence is simple
if ($hash{$item}) {
  # do something
}

1 Comment

This is certainly the best way to go if your items are something string-like (e.g. strings, numbers). Otherwise use any or grep.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.