Go4Expert

Go4Expert (http://www.go4expert.com/)
-   Perl (http://www.go4expert.com/articles/perl-tutorials/)
-   -   in_array Functionality in Perl (http://www.go4expert.com/articles/inarray-functionality-perl-t8978/)

pradeep 21Feb2008 20:56

in_array Functionality in Perl
 

Introduction



One of the strengths of PHP when it comes to arrays is considered to be the in_array function (http://php.net/in_array), this function takes two parameters; the array and the item to be searched in the array and then returns a boolean result whether the item exists in the array. Perl inherently lacks this functionality, even popular Perl modules like List::Util lack such a function/method.

As it was said by Plato once, "Necessity... the mother of invention.", I required to check whether a name existed in an array, bored by using conventional method of iterating the array every time I need to check, I wrote a simple sub-routine to get the job done.

This sub-routine take two arguments, a reference to the array to be searched, and the item that needs to be searched. Simple enough the sub-routine works like magic, even my friend have found it very useful. I thought may be someone might find it useful, here's it, take a look.

Code: Perl

sub in_array
 {
     my ($arr,$search_for) = @_;
     my %items = map {$_ => 1} @$arr; # create a hash out of the array values
     return (exists($items{$search_for}))?1:0;
 }


Sample Usage



Code: Perl

my @arr = ('Amlan','Pradeep','Shency','Shabbir');
 
 
 sub in_array
 {
     my ($arr,$search_for) = @_;
     my %items = map {$_ => 1} @$arr;
     return (exists($items{$search_for}))?1:0;
 }
 
 if(in_array(\@arr,'Amlan'))
 {
     print "Hurray! Amlan you are in!!\n";
 }
 else
 {
     print "Ooops! Amlan you are out!!\n";
 }


Output :



Code:

[pradeep@go4expert ~]$ ./amlan_test.pl
 Hurray! Amlan you are in!!
 [pradeep@go4expert ~]$

I guess the code is self-explanatory for everyone to understand. Enjoy!

oleber 22Feb2008 12:47

Re: in_array Functionality in Perl
 
can I suggest other implementation?

Code: Perl

sub in_array {
     my ($arr,$search_for) = @_;
     return grep {$search_for eq $_} @$arr;
}


or

Code: Perl

sub in_array {
      my ($arr,$search_for) = @_;
     foreach my $value @$arr {
         return 1 if $value eq $search_for;
     }
     return 0;
 }


pradeep 22Feb2008 13:22

Re: in_array Functionality in Perl
 
Cool! I guess the first one you suggested would be more efficient than your 2nd suggestion and my sub-routine. What say?

oleber 22Feb2008 14:51

Re: in_array Functionality in Perl
 
Lets time this

Code: Perl

use Benchmark qw(:all) ;

sub in_array_pradeep {
    my ($arr,$search_for) = @_;
    my %items = map {$_ => 1} @$arr;
    return (exists($items{$search_for}))?1:0;
}

sub in_array_1 {
    my ($arr,$search_for) = @_;
    return grep {$search_for eq $_} @$arr;
}

sub in_array_2 {
    my ($arr,$search_for) = @_;
    foreach my $value (@$arr) {
        return 1 if $value eq $search_for;
    }
    return 0;
}

my @arr = qw(Amlan Pradeep Shency Shabbir oleber or use subroutine references timethese benchmark running times of Perl code);

timethese(100000,
{
    'in_array_pradeep' => sub {in_array_pradeep(\@arr, $_) foreach @arr},
    'in_array_1' => sub {in_array_1(\@arr, $_) foreach @arr},
    'in_array_2' => sub {in_array_2(\@arr, $_) foreach @arr},
});


and the results in my machine are:

Code:

Benchmark: timing 100000 iterations of in_array_1, in_array_2, in_array_pradeep...
in_array_1:  5 wallclock secs ( 5.34 usr +  0.00 sys =  5.34 CPU) @ 18726.59/s (n=100000)
in_array_2:  5 wallclock secs ( 4.48 usr +  0.00 sys =  4.48 CPU) @ 22321.43/s (n=100000)
in_array_pradeep: 32 wallclock secs (32.13 usr +  0.00 sys = 32.13 CPU) @ 3112.36/s (n=100000)

Now lets speak about the results.

:embarasse The solution of pradeep is very slow. This seems obvious since he is creating a big structure in memory.

Now the other two are interesting.

:nice: The grep is fast since runs in C code inside the machine, but has to check all the elements.

:happy: The foreach stops when finds the first matching, so just half the match are needed in average.

pradeep 3Mar2008 18:50

Re: in_array Functionality in Perl
 
Hi oleber, I saw your post today! Good finding, even I was wondering that my sub-routine wasn't very efficient. And today only I figured out that using grep would be better, but I see that you have already posted it :-)


All times are GMT +5.5. The time now is 14:15.