Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

How do I find the index of a specific array value?

by BigVic (Initiate)
on Apr 26, 2001 at 03:44 UTC ( [id://75660]=perlquestion: print w/replies, xml ) Need Help??

BigVic has asked for the wisdom of the Perl Monks concerning the following question: (arrays)

How do I find the index of a specific array value?

Originally posted as a Categorized Question.

  • Comment on How do I find the index of a specific array value?

Replies are listed 'Best First'.
Re: how do i find the index of a specific array value?
by merlyn (Sage) on Apr 26, 2001 at 03:47 UTC
    my @array = qw( your array here ); my $search_for = "here"; my( $index )= grep { $array[$_] eq $search_for } 0..$#array;
        grep $array$_ eq $search_for, 0 .. $#array; will return matched array which stores the index of the matching words. my @index_arr = grep {$array$_ eq $search_for} 0 .. $#array; or my @index_arr = grep $array$_ eq $search_for, 0 .. $#array; foreach (@index_arr) { print "matching position = $_\n"; }
      Newbie question: I am very new to Perl and am a little confused about grep here.

      my ($index) = grep $array[$_] eq $search_for, 0 .. $#array;

      This is what I think is happening: grep is stepping through the range of numbers in list 0..$#array and substituting each in $_, and then using this as an index to find the corresponding element in @array. Eventually the expression $array[$_]eq $search_for is true and that element of the range 0..$#array is put into a list returned by grep, which is then assigned to ($index).

      This is my area of confusion: If @array has duplicate values, why does grep seem to stop when it finds the first value rather than produce a list of two values? Yet if I replace ($list) with @list, I get the index of both duplicate elements. I would greatly appreciate it if someone could cast some light on my darkness here :)

        I've got it! I think - this is a list, not an array, and according to Perlfaq4.pod (I know, I know, but I was looking under "grep") you can't push/pop a list as you can an array. This is also explained very well in the Perl Journal at http://www.tpj.com/articles/2001/0101/0101a/0101a.htm
Re: how do i find the index of a specific array value?
by hdp (Beadle) on Apr 26, 2001 at 04:26 UTC
    For very large arrays where bailing out as soon as a match is found is a win:
    my @a = ( 1 .. 1_000_000 ); # some large array my $want = 5843; my $index = 0; ++$index until $a[$index] == $want or $index > $#a;
      The last line should be ++$index until $a[$index] == $want or $want > $#a, and thanks to stephen for pointing this out.
Re: how do i find the index of a specific array value?
by I0 (Priest) on Apr 26, 2001 at 10:03 UTC
    You could use an index hash:
    my @array = qw( your array here ); my $search = "array"; my %index; @index{@array} = (0..$#array); my $index = $index{$search}; print $index, "\n";
    This is a win, for larger arrays, if you need to do multiple/many lookups while the array remains static.
Re: How do I find the index of a specific array value?
by marcussen (Pilgrim) on Jul 25, 2008 at 03:16 UTC

    Using merlyn's example with regular expressions, so you don't need to know the exact value of the element you are matching;

    my @array = ( 'Name: Mr. Jones', 'Phone: 555-555', 'Email: jones@example.com' ); my ( $index )= grep { $array[$_] =~ /Phone/ } 0..$#array;
    Replace ( $index ) with an array to match multiple instances.

Re: How do I find the index of a specific array value?
by snoopy (Curate) on Sep 07, 2005 at 01:45 UTC
    I like List::MoreUtils:
    use List::MoreUtils; my @array = qw( Apples Oranges Brains Toes Kiwi); my $search = "Toes"; my $index = List::MoreUtils::first_index {$_ eq $search} @array; print "index of $search = $index\n";
Re: how do i find the index of a specific array value?
by MeowChow (Vicar) on Apr 26, 2001 at 08:25 UTC
Re: How do I find the index of a specific array value?
by simul (Novice) on Dec 07, 2009 at 06:39 UTC
    If the array is large and sorted, you might want search it more efficiently:
    my @array = qw( your large, sorted array here ); my $search = "thing"; my $index = bsearch(\@array, $search); sub bsearch { my ($array, $word) = @_; my $low = 0; my $high = @$array - 1; while ( $low <= $high ) { my $try = int( ($low+$high) / 2 ); $low = $try+1, next if $array->[$try] lt $word; $high = $try-1, next if $array->[$try] gt $word; return $try; } return; }
Re: How do I find the index of a specific array value?
by myuserid7 (Scribe) on Aug 13, 2010 at 05:34 UTC
    You should use first() from List::Util. It is a core module, unlike List::MoreUtils and other modules mentioned above, so it is portable and can be used with no extra effort.
    use List::Util qw(first); my @array = qw( Apples Oranges Brains Toes Kiwi); my $search = "Toes"; my $index = first { $array[$_] eq $search } 0 .. $#array; print "index of $search = $index\n";
Re: how do i find the index of a specific array value?
by stephen (Priest) on Apr 26, 2001 at 08:59 UTC
    For really, really large arrays where you're doing repeated searches, here's a more magical way (at the expense of memory):
    my @a = ( .. some extremely huge array .. ); my @want = ( .. some array of things I want to find ) my $index_a = make_indexfinder(\a); foreach ( @want ) { print $index_a->($want), "\n"; } sub make_indexfinder { my ($arrayref) = @_; my %value_table = (); my $last_index = 0; return sub { my ($quarry) = @_; exists $value_table{$quarry} and return $value_table{$quarry}; for ($last_index .. $#$arrayref) { ($quarry eq $arrayref->[$_]) and do { $last_index = $_; $value_table{ $quarry } = $_; return $_; }; $value_table{ $arrayref->[$_] } = $_; } return undef; }; }

    Originally posted as a Categorized Answer.

Re: How do I find the index of a specific array value?
by Anonymous Monk on Oct 14, 2003 at 09:05 UTC
    @array = (...some 1_000_000 element array...); $search_for = "blah"; my $index = 0; while ( $array[$index] != $search_for ) { $index++ }

    Originally posted as a Categorized Answer.

Re: How do I find the index of a specific array value?
by SM177Y (Initiate) on Sep 15, 2015 at 08:46 UTC

    I also was looking for a method to do this, preferably the fastest possible. With a relatively small array (256), the use List::Util qw(first); method was actually significantly slower than simply iterating through the array and breaking(last) out once the match was found. In my test example on a 2.5MB file doing a sort of Sbox type lookup, the iterating took about 3m45s on my old Atom netbook where as the use List::Util qw(first); method required over 5m. Does anyone know the fastest way to perform these index lookups? A few of the examples shown appear to be basically identical. Hashing an array(did I say that right?) is a concept I am not yet familiar with.

    Originally posted as a Categorized Answer.

Re: How do I find the index of a specific array value?
by myuserid7 (Scribe) on Aug 13, 2010 at 05:31 UTC

    You should use first() from List::Util. List::Util is a core module, unlike List::MoreUtils and other modules mentioned above, so it is portable and can be used with no extra effort.

    use List::Utils qw(first); my @array = qw( Apples Oranges Brains Toes Kiwi); my $search = "Toes"; my $index = first {$_ eq $search} @array; print "index of $search = $index\n";
      I meant
      use List::Utils qw(first); my @array = qw( Apples Oranges Brains Toes Kiwi); my $search = "Toes"; my $index = first {$array[$_] eq $search} 0..$#array; print "index of $search = $index\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://75660]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-23 21:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found