6
$\begingroup$

Nearestgives me the closest value to my reference, but what if I am always looking for the closest value, which is lower than my reference?

list = {0.2, 0.25, 0.32, 0.36, 0.40, 0.45, 0.50, 0.55, 0.63, 0.70, 
0.80, 0.90, 1.00, 1.10, 1.25, 1.30, 1.40, 1.50, 1.60, 1.80, 2.00, 
2.20, 2.50, 2.80, 3.00, 3.20, 3.60, 4.00, 4.50, 5.00, 5.50, 6.30, 
7.00, 8.00};

ref = 3.902;

result = Nearest[list, ref][[1]]

4.

...as in the example above: how I tell Mathematica that I need the 3.6 value instead of 4.0?

$\endgroup$

2 Answers 2

5
$\begingroup$

Leave the elements greater than the reference out of consideration, by, for example, DeleteCases:

Nearest[DeleteCases[list, x_ /; x > ref], ref]

or Cases:

Nearest[Cases[list, x_ /; x < ref], ref]

or for any 1D list of numbers like in your case (I assume, list might also be unsorted)

Last@Sort@Select[list, # < ref &]

or simply replace Nearest with Max and apply to the list where numbers above ref have been dropped

Max@Select[list, # < ref &]

or several other ways which don't yet come to my mind.

$\endgroup$
2
  • $\begingroup$ This seems a bit inefficient on large lists given that it creates a new copy. $\endgroup$
    – lirtosiast
    Commented Jul 1, 2019 at 5:53
  • $\begingroup$ @lirtosiast It's going to be O(n) complexity in any case, most likely will use O(n) memory regardless of implementation too. $\endgroup$
    – LLlAMnYP
    Commented Jul 2, 2019 at 13:12
6
$\begingroup$

Another possibility is to use a custom distance function with a penalty:

Nearest[list, 3.902, DistanceFunction -> (Abs[#1 - #2] + 100 Boole[#1 < #2] &)]
   {3.6}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.