Does Perl have a build-in function to get the index of an element in an array? Or I need write such a function by myself? [ equivalent to PHP array_search() or JavaScript array.indexOf() ]
+21
A:
use List::Util qw(first);
$idx = first { $array[$_] eq 'whatever' } 0..$#array;
(List::Util is core)
or
use List::MoreUtils qw(firstidx);
$idx = firstidx { $_ eq 'whatever' } @array;
(List::MoreUtils is on CPAN)
hobbs
2010-07-11 06:52:16
This is definitely the way to go, 9 times out of 10.
Zaid
2010-07-11 07:21:58
Why is this better than your solution, Zaid?
masonk
2010-07-11 13:52:59
@masonk : Backwards-compatibility for one. Also, `first` will exit the implicit loop upon finding the index that matches. The `grep` equivalent would be `$idx = grep { $array[$_] eq 'whatever' and last } 0 .. $#array;`, a bit hairy for my liking. And then it's miles ahead in the speed-race, when run as `List::Util::XS`.
Zaid
2010-07-11 14:24:37
Just realized you can't `last` out of `grep` cleanly. Whoops!
Zaid
2010-07-11 20:26:43
+1
A:
You can write a function for this:
sub array_search {
my ($arr, $elem) = @_;
my $idx;
for my $i (0..$#$arr) {
if ($arr->[$i] eq $elem) {
$idx = $i;
last;
}
}
return $idx;
}
The index of the first matching element will be returned, or undef
.
eugene y
2010-07-11 07:43:47
My final solution: sub array_search { my ($element, @array) = @_; foreach (0..$#array) { if ($array[$_] eq $element) { return $_; } } return -1; }
powerboy
2010-07-11 16:53:03
+3
A:
Here's a post-5.10 way to do it, with the added benefit of determining how many indexes match the given value.
my @matches = grep { $array[$_] ~~ $element } 0 .. $#array;
If all elements are guaranteed to be unique, or just the first index is of interest:
my ($index) = grep { $array[$_] ~~ $element } 0 .. $#array;
Zaid
2010-07-11 10:15:46
That answer does not fit the question. The index is what goes into the square brackets for array access, so: a number between `0` and `$#array`.
daxim
2010-07-11 11:49:35
+5
A:
Here is an autobox
solution:
use autobox::Core;
my @things = qw/blue black green red green yellow/;
my $first_green = @things->first_index( sub{ $_[0] eq 'green' } ); # code block
my $last_green = @things->last_index ( qr/^green$/ ); # or regex
say $first_green; # => 2
say $last_green; # => 4
/I3az/
draegtun
2010-07-11 12:55:23