Fun little question. It seems to be getting a lot of good answers, but in any case I'll throw in my 2 cents. My immediate though is that this sort of fits the loop construct LengthWhile
, since we really just want to keep on counting until we get a hit, but it doesn't naturally work on trailing lists, so we'll just add this to it. In that regard here's my suggesting:
countWhileList[list_, n_, criteria_] :=
LengthWhile[
Range[n + 1, Length@list],
criteria[list[[# - n ;; #]]] &
] + 1 + n
Which can then be used as:
normalDeviation[list_] := Abs[(Mean[list] - list[[-1]])/StandardDeviation[list]]
countWhileList[testData, 40, normalDeviation[#] < 1 &]
Which will count trailing lists of 40 elements and return the number of the first hit that fails the criteria. Depending on preference, it could instead be made to count the number of successes by removing the +1
.
Naturally if you then want the value, you can use Part
as in
Part[testData,countWhileList[testData, 40, normalDeviation[#] < 1 &]]
Keeping in this style but allowing for multiple returns you could use instead
selectWhereList[list_, n_, criteria_, m_] :=
Select[Range[n + 1, Length@list], criteria[list[[# - n ;; #]]] &, m]
Part[test, First@selectWhereList[test, 40, normalDeviation[#] > 3 &, 1]]
Which is essentially just the inner part of Mr. Wizards solution. Personally I prefer my first, if only because I so rarely get to use LengthWhile
for anything constructive.