You could also refer to the very complete Getting Matching Items From An Array.

At first I said, "of course GrandFather is right", but upon further testing the situation is not so clear. The optimizations in grep give it an edge over the C style for if you have to look approximately 1/2 way into the array. This did not surprise me as much as the poor performance of a binary search. ( code borrowed from Binary search). Though I think after struggling to coax grep to return a list value into a scalar context I would avoid that solution unless you really want multiple values returned.

oko1 gives an implementation of grep but I was thinking more something like: grep {$array[$_] eq $value} (0..$#array) as shown in the code below. Which, as I said, may be just quick enough.

#!/usr/bin/perl use Benchmark 'cmpthese'; use warnings; @array = ( 'a'..'zz' ); $value = 'mz'; my $res; my $position; print "for(): ".traditional(). "\tforeach: ".for_each(). "\tmap: ".maptohash(). "\tgrep_if: ".grep_if(). "\tbinary search: ".bin_search(). "\n"; cmpthese ( 1000, { for_loop => '$res = traditional()', map => '$res = maptohash()', for_each => '$res = for_each()', grep_if => '$res = grep_if()', bin_search => '$res = bin_search()', } ); sub traditional{ for ($position=0; $position <= $#array; $position++) { last if ($array[$position] eq $value); } return $position; } sub for_each{ for our $position ( 0..$#array ) { last if ($array[$position] eq $value) ; } return $position; } sub maptohash{ %indexed = map{ $array[$_], $_ } (0..$#array); return $indexed{$value}; } sub grep_if{ my @res = grep {$array[$_] eq $value} (0..$#array); return @res[0]; } sub bin_search { return BinSearch( $value, \&cmpFunc, \@array ); } sub BinSearch { my ($target, $cmp) = @_; my @array = @{$_[2]}; my $posmin = 0; my $posmax = $#array; return -0.5 if &$cmp (0, \@array, $target) > 0; return $#array + 0.5 if &$cmp ($#array, \@array, $target) < 0; while (1) { my $mid = int (($posmin + $posmax) / 2); my $result = &$cmp ($mid, \@array, $target); if ($result < 0) { $posmin = $posmax, next if $mid == $posmin && $posmax != $posmin; return $mid + 0.5 if $mid == $posmin; $posmin = $mid; } elsif ($result > 0) { $posmax = $posmin, next if $mid == $posmax && $posmax != $posmin; return $mid - 0.5 if $mid == $posmax; $posmax = $mid; } else { return $mid; } } } sub cmpFunc { my ($index, $arrayRef, $target) = @_; my $item = $$arrayRef[$index]; return $item cmp $target; } %perl foo.pl + [10:49pm] Scalar value @res[0] better written as $res[0] at foo.pl line 47. for(): 363 foreach: 363 map: 363 grep_if: 363 binary + search: 363 Rate map for_loop grep_if bin_search for_ea +ch map 200/s -- -69% -72% -81% -8 +8% for_loop 650/s 224% -- -8% -39% -6 +0% grep_if 707/s 253% 9% -- -33% -5 +7% bin_search 1058/s 428% 63% 50% -- -3 +6% for_each 1641/s 719% 153% 132% 55% +--


s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}

In reply to Re: Finding values position in array by starbolin
in thread Finding values position in array by cosmicperl

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.