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: 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: 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!
can I suggest other implementation? Code: sub in_array { my ($arr,$search_for) = @_; return grep {$search_for eq $_} @$arr; } or Code: sub in_array { my ($arr,$search_for) = @_; foreach my $value @$arr { return 1 if $value eq $search_for; } return 0; }
Cool! I guess the first one you suggested would be more efficient than your 2nd suggestion and my sub-routine. What say?
Lets time this Code: 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.
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