[Charlotte.PM] find index of array element

Dale Lancaster dale at lancaster.hm
Wed Mar 23 09:45:24 PST 2005


I think the original requirement was to return the index in the original 
list of the matching element, not the actual element.  I don't believe the 
below accomplishes that.  Funny, that your example would actually produce 
the same answer in my test code, but only because perl is subtracting 1 from 
the value of the element in the matching array.

> Interesting approach. The form that I think Diona was recalling is in
> the Cookbook as Recipe 4.13. To put it into your context, it would look
> like the following:
>
>  @matching = grep { /3/ } @input;
>
> To get the first element, it would be:
>
>  print $matching[0] - 1;
>

Adding another element (0) to the list creates two different answers. 
Your's is still "2", mine is "3" which would be the correct element index 
number.  If Diona needed just the element contents, then yes, yours is 
definitely the way to go and is very clean and readable.

my @input=(0,1,2,3,4,3) ;

my $index ;
my ($j, $i) ;
my @matching = grep { /3/ } @input;

print $matching[0] - 1;

grep { $i++ ; $j=$i-1 if $_ =~ /3/ && !$j ; } @input ;

print $j ;

exit 1 ;

> Though Drew's point about scalability is good to remember, I hardly
> think you're going to have any issues with scalability until your arrays
> get over 100 elements. Until then, grepping through an  array may be
> faster than using a hash. Anyone care to write up that benchmark?
>
With fast computers and virtually unlimited memory, I think the array would 
have to be in the several hundred or low thousands to be noticeably slow.  I 
do agree though that parsing the whole list in general is not the best 
approach.  I tried "exiting" the grep process in the logic above, but there 
isn't a way to do it, so it will parse the whole list.

My preferered approach is to restructure the code to be readable, vs 
compact.  The general rule of thumb being that if I have a hard time reading 
it, the Perl interpreter might have just as hard a time.  Compact code does 
not equal faster code all the time.  So I would have done:

for ($i=0; $i < $input ; $i++) {
    last if  $input[$i] =~ /3/ ;
}
print $i ;

This is probably as fast or faster than my original code and of course 
doesn't parse the whole array and is much more readable and maintainable 
(and extensible).

:-)
dale









More information about the charlotte mailing list