Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I wanted to ask you how I can find the last position of a specific number in an array, e.g.:
$array=(1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6);
How could I find the last-occuring position of '4' for example in the array?

Replies are listed 'Best First'.
Re: Find last position of an element in array
by davido (Cardinal) on Mar 28, 2022 at 21:04 UTC

    List::Util is a core Perl module (ships with Perl) and provides a subroutine called first. That subroutine returns the actual element. But if you treat indexes as elements and reverse them you can get what you need:

    #!/usr/bin/env perl use strict; use warnings; use List::Util qw(first); my @array = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); my $idx = first {$array[$_] == 4} reverse 0..$#array; print "$idx\n";

    If non-Core modules are allowed, which they ought to be, you can use List::MoreUtils, which provides lastidx, in which case you could do this:

    #!/usr/bin/env perl use strict; use warnings; use List::MoreUtils qw(lastidx); my @array = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); my $idx = lastidx {$_ == 4} @array; print "$idx\n";

    If you don't want to use a module, just do this:

    #!/usr/bin/env perl use strict; use warnings; my @array = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); my $idx; for (reverse 0..$#array) { if ($array[$_] == 4) { $idx = $_; last; } } print "$idx\n";

    And then repent for not being willing to use a module (even though this is quite easy to solve without).


    Dave

Re: Find last position of an element in array
by Anonymous Monk on Mar 28, 2022 at 16:06 UTC
Re: Find last position of an element in array
by LanX (Saint) on Mar 28, 2022 at 16:25 UTC
    TIMTOWTDI

    one possibility is to loop backwards, $array[-1] gives you the last element and so on.

    please note that this is illegal incorrect syntax

    > $array=(1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6);

    you most probably meant

    @array=(1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6);

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      please note that this is illegal syntax

      "Illegal" is a bit strong. It is perfectly valid syntax, compiles fine and evaluates the list in scalar context. That's just not what the OP was after in this case.


      🦛

Re: Find last position of an element in array
by johngg (Canon) on Mar 28, 2022 at 21:32 UTC

    You could build a hash, keyed by @array items with the value being array position, via a map that, in effect, keeps overwriting the position of each item until the last one is reached.

    johngg@abouriou:~/perl/Monks$ perl -Mstrict -Mwarnings -E 'say q{}; my @array = ( 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, + 6 ); my %lasts = map { $array[ $_ ] => $_ } 0 .. $#array; say qq{$_ => $lasts{ $_ }} for sort keys %lasts;' 1 => 2 2 => 7 3 => 10 4 => 16 5 => 18 6 => 19

    I hope this is helpful.

    Cheers,

    JohnGG

Re: Find last position of an element in array
by ikegami (Patriarch) on Mar 29, 2022 at 03:12 UTC

    The array appears to be sorted. If that's the case, and if the array's very large, you might want to use a binary search. It would have to be larger to really benefit, though.

Re: Find last position of an element in array
by kcott (Archbishop) on Mar 29, 2022 at 05:45 UTC

    TMTOWTDI

    $ perl -E ' my @array = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); { local $" = ""; say rindex "@array", "4"; } say "@array[16, 17]"; ' 16 4 5

    In your example data, you show only elements with single digits. The solution I presented assumes this is representative data.

    — Ken

Re: Find last position of an element in array
by Discipulus (Canon) on Mar 29, 2022 at 07:14 UTC
    Hello, some unseen solution in the spirit of TIMTOWTDI

    use strict; use warnings; my @array = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); # tricky and destructive 1 until 4 == pop @array; print "last occurence of 4 was at ",$#array + 1," position\n"; # or even uglier @array = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); 1 until 4 == pop @array; push @array, 4; print "last occurence of 4 was at $#array position\n"; # non destructive copying $#array @array = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); my $lastindex = $#array; $lastindex-- until $array[ $lastindex ] == 4; print "last occurence of 4 is at $lastindex position\n"; # non destructive taking last of sort-grepping on indexes print "last occurence of 4 is at ",( sort{ $a <=> $b }grep{ $array[$_] + == 4 }0..$#array )[-1]," position\n";

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Find last position of an element in array
by dbuckhal (Chaplain) on Mar 29, 2022 at 17:38 UTC

    skipping past the sigil or brace mismatch, here is my five minute contribution...

    perl -le ' my @arr = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); print (@arr - index((reverse(@arr)), 4)); ' __output__ 17

      G'day dbuckhal,

      17 = off-by-one error. Fix: use $#arr instead of @arr.

      $ perl -le ' my @arr = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); print ($#arr - index((reverse(@arr)), 4)); print "@arr[16, 17]"; ' 16 4 5

      — Ken

      You can avoid the maths with rindex:

      $ perl -le ' my @arr = (1,1,1,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,6); print rindex( join (q{}, @arr), 4 ); ' 16

      🦛