Например, учитывая, что входной массив отсортирован в порядке возрастания asort()
, вы будете выполнять поиск намного быстрее, используя дихотомический поиск .
Вот быстрая и грязная адаптация некоторого кода, который я использую, чтобы вставить новое событие в Итерируемый список событий, отсортированный по объектам DateTime…
Таким образом, этот код будетвернуть ближайшую точку слева (до / поменьше).
Если вы хотите найти математически ближайшую точку: рассмотрите сравнение расстояния искомого значения с возвращаемым значением и точкой непосредственно справа(далее) возвращаемого значения (если оно существует).
function dichotomicSearch($search, $haystack, $position=false)
{
// Set a cursor between two values
if($position === false)
{ $position=(object) array(
'min' => 0,
'cur' => round(count($haystack)/2, 0, PHP_ROUND_HALF_ODD),
'max' => count($haystack)
);
}
// Return insertion point (to push using array_splice something at the right spot in a sorted array)
if(is_numeric($position)){return $position;}
// Return the index of the value when found
if($search == $haystack[$position->cur]){return $position->cur;}
// Searched value is smaller (go left)
if($search <= $haystack[$position->cur])
{
// Not found (closest value would be $position->min || $position->min+1)
if($position->cur == $position->min){return $position->min;}
// Resetting the interval from [min,max[ to [min,cur[
$position->max=$position->cur;
// Resetting cursor to the new middle of the interval
$position->cur=round($position->cur/2, 0, PHP_ROUND_HALF_DOWN);
return dichotomicSearch($search, $haystack, $position);
}
// Search value is greater (go right)
// Not found (closest value would be $position->max-1 || $position->max)
if($position->cur < $position->min or $position->cur >= $position->max){return $position->max;}
// Resetting the interval from [min,max[ to [cur,max[
$position->min = $position->cur;
// Resetting cursor to the new middle of the interval
$position->cur = $position->min + round(($position->max-$position->min)/2, 0, PHP_ROUND_HALF_UP);
if($position->cur >= $position->max){return $position->max;}
return dichotomicSearch($search, $haystack, $position);
}