Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Find last position of an element in array

by Anonymous Monk
on Mar 28, 2022 at 16:02 UTC ( [id://11142463]=perlquestion: print w/replies, xml ) Need Help??

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

      🦛

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2024-04-19 09:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found