Re: Finding index of an entry in an Array
by jrsimmon (Hermit) on Dec 07, 2007 at 02:04 UTC
|
Assuming you're wanting a simple iteration and not some type of sort algorithm, this will do the trick. my $index = 0;
my $input = $ARGV[0] || 'bar';
my @repo = qw (foo bar qux);
$index++ until @repo[$index] eq $input or $index > $#repo; #don't want
+ to loop forever if it's not found
It's worth noting that in your example, bar is at index 1, not index 2.
Update:
Fixed the typo pointed out by dwu
| [reply] [d/l] [select] |
|
$index++ until @repo[$index] eq $input or $i > $#repo;
Did you perhaps mean:
$index++ until $repo[$index] eq $input or $index > $#repo;
since you don't declare $i anywhere, and I'd have a hard time not getting that to loop forever when I started comparing zero to $#repo :)
Edit: thanks to IRCperson for spotting $repo[$index] | [reply] [d/l] [select] |
Re: Finding index of an entry in an Array
by Fletch (Bishop) on Dec 07, 2007 at 03:20 UTC
|
Aside from the fact that the index of 'bar' in your sample array is 1 not 2 (remember array indexen start at 0) . . .
use List::Util qw( first );
my $idx = first { $repo[ $_ ] eq 'bar' } 0..$#repo;
The cake is a lie.
The cake is a lie.
The cake is a lie.
| [reply] [d/l] |
|
use List::MoreUtils;
my $input = 'qux';
my @repo = qw (foo bar qux);
Print List::MoreUtils::first_index {$_ eq $input} @repo;
| [reply] [d/l] |
|
This concept works without List::Util as well,
my @array = qw(dog cat mat bat hat);
my ($idx) = grep { $array[$_] eq 'bat' } 0 .. $#array;
Update: Fletch noted an issue, when I was quickly testing on the command line I wasn't assigning to a variable, just printing (e.g. print grep { ... } 0 .. $#array, which evaluates in list context, not scalar context as I through up here with the assignment. Adding the parens clears that up. (Thanks Fletch).
---
s;;:<).>|\;\;_>?\\^0<|=!]=,|{\$/.'>|<?.|/"&?=#!>%\$|#/\$%{};;y;,'} -/:-@[-`{-};,'}`-{/" -;;s;;$_;see;
Warning: Any code posted by tuxz0r is untested, unless otherwise stated, and is used at your own risk.
| [reply] [d/l] |
|
my( $idx ) = grep { $array[ $_ ] eq 'bar' ) 0..$#array;
my @indexen = grep { $array[ $_ ] eq 'bar' } 0..$#array;
That aside, yup that's another way to do it. :)
The cake is a lie.
The cake is a lie.
The cake is a lie.
| [reply] [d/l] |
Re: Finding index of an entry in an Array
by sh1tn (Priest) on Dec 07, 2007 at 03:18 UTC
|
{map($_ eq 'bar' && last || $index++, @repo)};
#or
{grep(/^\Q$input\E$/ && last || $index++, @repo)};
| [reply] [d/l] |
Re: Finding index of an entry in an Array
by Anonymous Monk on Dec 07, 2007 at 03:41 UTC
|
if you are doing a sufficiently large number of look-ups in the @repo array, it will be advantageous to do a cached look-up of the index. (this will be all the more true if the array is large.)
perl -wMstrict
-e "my @repo = qw(foo bar qux bar zot); my %repo_index;
$repo_index{$repo[$_]} = $_ for reverse 0 .. $#repo;
print $repo_index{bar};"
1
note that if there are duplicate entries in the array, the index of the first (lowest index) entry will be returned. eliminate the reverse call to have it the other way. | [reply] [d/l] [select] |
|
note that if there are duplicate entries in the array, the index of the first (lowest index) entry will be returned. eliminate the reverse call to have it the other way.
This should be restated to say exactly two duplicate entries. A third or further duplicates would be undetectable with this method.
| [reply] |
|
i don't understand your point. i would not say my approach was able to directly detect any number of duplicates, whether 2, 3 or more. (the only, and somewhat awkward, way to detect the presence of duplicates with this specific caching approach would be to build two caches, one based on ascending indices, the other based on descending indices, and compare the two indices derived from the two caches. if they are not the same, two or more duplicates must exist. however, i can think of better ways to handle this sort of info.)
the point i was trying, perhaps clumsily, to make in my original post was that my method, in common with all the other approaches that had appeared by then, would, due to the use of reverse, return the first (i.e., lowest) index of a match in the case of duplicates, but that a variation could easily be had that would return the last/highest index.
since my original post, i see that some solutions have been posted that return the indices of all matches, which i did not understand to be a requirement of the original question. oh, well...
| [reply] [d/l] |
Re: Finding index of an entry in an Array
by ysth (Canon) on Dec 07, 2007 at 05:56 UTC
|
Wanting to do this is often a clue that you shouldn't have been using an array in the first place.
| [reply] |
Re: Finding index of an entry in an Array
by l.frankline (Hermit) on Dec 07, 2007 at 06:23 UTC
|
my $input = $ARGV[0] || 'bar';
my @repo = qw (foo bar qux);
map{ print $_ if $repo[$_] eq $input } 0..$#repo;
Don't put off till tomorrow, what you can do today.
| [reply] [d/l] |
Re: Finding index of an entry in an Array
by poolpi (Hermit) on Dec 07, 2007 at 08:39 UTC
|
#!/usr/bin/perl
use strict;
use warnings;
my $input = $ARGV[0] || 'bar';
my @repo = qw(foo baz bar boo);
my $i;
map{ print $i if /$input/; $i++ } @repo;
HTH,
PooLpi | [reply] [d/l] |
Re: Finding index of an entry in an Array
by Anonymous Monk on Dec 07, 2007 at 16:33 UTC
|
a caching approach to returning all indices of an item in an array:
perl -wMstrict
-e "my @repo = qw(foo bar qux bar bar zot); my %repo_indices;
push @{ $repo_indices{$repo[$_]} }, $_ for 0 .. $#repo;
print qq(@{ $repo_indices{bar} });"
1 3 4
| [reply] [d/l] |