Assume I have an ordered, ascending list {1,4,10,12,20}
.
I want to find the smallest position of an element of the list such that the element is not less than 11?
The position in question is 4.
How to do this easily?
FirstPosition[{1, 4, 10, 12, 20}, _?(# >= 11 &)]
(* Out: {4} *)
If you want just the number $4$, then use First@FirstPosition[...]
.
This question is closely related to the question Best way to insert element into an ordered list at the correct position?
, where it was noted that Leonid Shifrin's bsearchMax
from this answer is a fast way to solve the problem. Like flinty's answer it uses a binary search but it appears to be faster.
bsearchMax[{1, 4, 10, 12, 20}, 11]
4
For a list of decent size, bsearchMax
can be orders of magnitude faster than FirstPosition
.
A couple of slower alternatives to FirstPosition
:
data = {1, 4, 10, 12, 20};
Position[data, SelectFirst[data, # >= 11 &]][[1, 1]]
Needs["Combinatorica`"]; Ceiling@BinarySearch[data, 11]
list = {1, 4, 10, 12, 20, 12};
Using PositionIndex
First @ First @ KeySelect[GreaterEqualThan @ 11] @ PositionIndex[list]
4
list = {1, 4, 10, 12, 20, 12};
Using GroupBy
:
First[Keys@GroupBy[Thread[Range@Length@# -> #] &@list, #[[2]] >= 11 &][True]]
4
list = {1, 4, 10, 12, 20}
list~Join~{11} // Sort // FirstPosition[11]
or
SplitBy[list, #1 < 11 &] // 1 + Length@First @# &
{4}
11
is not in the list. $\endgroup$