Perl: the Markov chain saw PerlMonks

### Get Position of Element in an array

 on Nov 16, 2010 at 13:17 UTC Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks

I want to get position of element in an array

```@input=('a','b','c','d');
my \$char='b';

I want \$char position in an array;

Replies are listed 'Best First'.
Re: Get Position of Element in an array
by ELISHEVA (Prior) on Nov 16, 2010 at 14:01 UTC

Using grep or map to solve this means that you would have to go through the entire length of the array even if the character was at the beginning. Here's a solution that stops as soon as the character is found.

```sub foo {
my (\$aChars, \$ch) = @_;
my \$i=0;
for (@\$aChars) {
return \$i if \$ch eq \$_;
\$i++;
};
}

my @aChars =('a','b','c','d');
print "c=", findChar(\@aChars, 'c'), "\n";
# outputs c=2

Or if you have an aversion to subs,

```my \$k='c';
my \$i=0;

for (@aChars) { last if \$k eq \$_; \$i++; };

print "\$k=\$i\n";
#also outputs c=2

Update:Put in mssing final ';' and patched to print position=array index rather than position = ordinal value. (i.e. c=2 instead of c=3).

Re: Get Position of Element in an array
by LanX (Bishop) on Nov 16, 2010 at 13:54 UTC
this will impress your professor! =)
```  DB<1> @input=('a','b','c','d');

DB<2> %pos= map { \$_=>\$i++ } @input

DB<3> print \$pos{a}
0
DB<4> print \$pos{d}
3

... so what if elements aren't unique?

Cheers Rolf

>... so what if elements aren't unique?

since this question hasn't been answered yet here a variation for finding the first idx!

```%pos= map { \$_=>\$i++ } reverse @input;

If you need it more than once, then the overhead for building a hash will easily pay off.

Cheers Rolf

Re: Get Position of Element in an array
by roboticus (Chancellor) on Nov 16, 2010 at 13:25 UTC

Try this:

```@input=('a','b','c','d');
my \$char='b';
print "\$char is at position(s): ",
join(", ", grep { \$char eq \$input[\$_] } 0..\$#input),
"\n";

Note: Untested, you keep all the bits if it breaks, etc...

...roboticus

Re: Get Position of Element in an array
by mykl (Monk) on Nov 16, 2010 at 14:55 UTC

```use List::MoreUtils qw(firstidx);
@input=('a','b','c','d');
my \$char='b';
print firstidx { \$_ eq \$char } @input;

--

"Any sufficiently analyzed magic is indistinguishable from science" - Agatha Heterodyne

Re: Get Position of Element in an array
by Ratazong (Monsignor) on Nov 16, 2010 at 13:36 UTC
And another idea:
```print index(join("",@input),\$char);
note: position-counting starts with zero ...

Update Seems the example given by the OP led me to a too simplified solution. Thanks for spotting the limitations, LanX

thank god perl arrays can only hold one character strings!

... ;-D

Cheers Rolf

Re: Get Position of Element in an array
by happy.barney (Friar) on Nov 16, 2010 at 13:32 UTC
```my (\$pos) = grep \$input[\$_] eq \$val, 0 .. \$#input;
or create lookup table:
```my (\$first, \$last) = ({}, {});
@\$first{reverse @input} = reverse 0 .. \$#input;
@\$last{@input} = 0 .. \$#input;

my \$val = 'b';
print "Last index  : ", \$last->{\$val};
print "First index : ", \$first->{\$val};
Re: Get Position of Element in an array
by Anonymous Monk on Nov 16, 2010 at 13:34 UTC
Re: Get Position of Element in an array
by SimonClinch (Deacon) on Nov 16, 2010 at 15:27 UTC
Nothing seems to beat the obvious for efficiency in my mind:-
```my @input=('a','b','c','d');
my \$char='b';
# --------------
my \$pos = -1;
ELM: for ( my \$i = 0; \$i <= \$#input; \$i++ ) {
if ( \$char eq \$input[\$i] ) {
\$pos = \$i;
last ELM;
}
}
with \$pos now having -1 for no match or 0+ for where the match was made in the array.

One world, one people

Create A New User
Node Status?
node history
Node Type: perlquestion [id://871719]
Approved by Corion
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2018-06-20 10:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Should cpanminus be part of the standard Perl release?

Results (116 votes). Check out past polls.

Notices?