The FirstPosition[]
function can be use to locate the first position of an occurrence in a list. For example FirstPosition[list,_?NumericQ]
will find the position of the first occurrence of a number in a list. Is there a function to find the last position of a occurrence? If not perhaps someone has a clever way to do it.
$\begingroup$
$\endgroup$
6
1 Answer
$\begingroup$
$\endgroup$
0
The clean but inefficient way is to simply find all positions and take the last one:
x = {16, {10, {78, 1}, 32, 15}, 30, 30}
Position[x, _?OddQ][[-1]]
{2, 4}
It proves faster to reverse everything and use FirstPosition
:
lastPosition[x_, pat_] :=
Module[{rev, pos},
rev = Reverse[HoldComplete[x], 1 + Range @ Depth @ x];
pos = Rest @ FirstPosition[rev, pat];
1 - pos + Length /@ Unevaluated @@@ FoldList[Part[#, {1}, #2] &, rev, Most@pos]
]
lastPosition[x, _?OddQ]
{2, 4}
Timing on a large expression:
SeedRandom[4]
x =
Nest[
RandomChoice[{
{#, #2} &,
{#2, #} &,
Prepend,
Append
}][#, RandomInteger[99]] &,
{1},
2000
];
Needs["GeneralUtilities`"]
Position[x, _?OddQ][[-1]] // AccurateTiming
lastPosition[x, _?OddQ] // AccurateTiming
0.374521 0.000297869
Both output:
{2, 1, 1, 1, 3, 2, 2, 2, 4}
FirstPosition[Reverse@list,_?NumericQ]
?:) $\endgroup$Length[list]-FirstPostion[Reverse@list,_?NumericQ]
. $\endgroup$(Length[list]+1)-FirstPosition[list,_?NumericQ]
$\endgroup$list
is not a flat list. For nested lists such asexpr={{a,b,2},{c,3,{x,5}},{u,r}}
,Position[expr,_?NumericQ,Infinity][[-1]]
is much simpler than anything usingFirstPosition
. $\endgroup$