How to avoid procedural loops in this example?
As is demonstrated very well in this post you can use a criteria for your pattern, thereby only applying your function as long as you are searching and not to all elements. Also there is a specific FirstPosition
function.
f[x_] := Module[{}, Pause[0.5]; 2 x]
AbsoluteTiming[
Position[f /@ Range[10], 10, 1, 1]
]
AbsoluteTiming[
FirstPosition[f /@ Range[10], 10]
]
{5.00824, {{5}}}
{5.01055, {5}}
AbsoluteTiming[
Position[Range[10], _?(f[#] == 10 &), 1, 1]
]
AbsoluteTiming[
FirstPosition[Range[10], _?(f[#] == 10 &)]
]
{3.00378, {{5}}}
{3.00329, {5}}
SelectFirst
would work:
SelectFirst[Range[10], f[#] == 10 &]
You can tell that it only executes f
on indexes 1-5 if you add a Print
statement to the definition:
f[x_] := (Print[x]; 2 x)
1 + LengthWhile[Range@10, f@# != 10 &]
5