Je vais fournir une réponse tardive qui s'efforce d'éviter les itérations inutiles et les appels de fonction excessifs en maintenant deux variables temporaires et en mettant en place un retour anticipé.
Une solution élégante ne devrait pas exiger une complexité temporelle supérieure à n -- en d'autres termes, le grand O devrait être O(n) et le petit o devrait être o(1) . Le grand O ne fait qu'empirer en pré-triant la meule de foin, puis en itérant à nouveau la meule de foin. Pour arriver à o(1) vous aurez besoin d'un retour rapide lorsqu'une correspondance identique est rencontrée - il n'est pas nécessaire de chercher plus loin.
Mon extrait renvoie arbitrairement la première valeur apparaissant avec la distance la plus faible (dans le cas où plusieurs valeurs ont la même distance). Tout autre comportement n'est pas spécifié par l'OP.
Une amélioration triviale des performances par rapport à d'autres réponses est que abs()
est le seul appel de fonction dans la boucle et il est appelé au maximum une fois par itération. Certaines réponses précédentes recalculent la distance de la valeur actuelle ainsi que la correspondance la plus proche à chaque itération - c'est plus de travail que nécessaire.
Code : ( Démo )
$haystack = [-6, 0, 5, 10, 11, 12, 20];
$needles = [0, 3, 14, -3];
function getNearest($needle, $haystack) {
if (!$haystack) {
throw new Exception('empty haystack');
}
$bestDistance = PHP_INT_MAX;
foreach ($haystack as $value) {
if ($value === $needle) {
return $needle;
}
$distance = abs($value - $needle);
if ($distance < $bestDistance) {
$bestDistance = $distance;
$keep = $value;
}
}
return $keep ?? $value; // coalesce to silence potential IDE complaint
}
foreach ($needles as $needle) { // each test case
echo "$needle -> " . getNearest($needle, $haystack) . "\n";
}
Sortie :
0 -> 0
3 -> 5
14 -> 12
-3 -> -6
2 votes
Je ne sais pas ce que vous voulez faire.
0 votes
Il n'existe pas de fonction intégrée pour ce faire. Vous devrez écrire la vôtre. Vous devriez également envisager de demander à un véritable question dans votre question ; qu'est-ce qui vous pose problème actuellement ?
4 votes
@meagar je pense que la déclaration est très claire, ayant à demandez à une question n'est pas une obligation, n'est-ce pas ?
0 votes
@amosrivera En fait, ça l'est. Votre question doit être un question pour que la communauté fournisse des réponses. Nous ne pouvons pas répondre à une déclaration. Il s'agit du format auquel les messages sont censés et doivent se conformer sur Stack Overflow.
5 votes
La question "Comment puis-je trouver la valeur "la plus proche" d'une aiguille ?" n'est-elle pas une question ?
0 votes
@meagar ma faute, je vais devoir vérifier la méta.
2 votes
@FMaz Oui, mais j'ai édité cela pour vous quand aucun changement ne semblait se profiler.
0 votes
Vous ne voulez pas trouver des "aiguilles" (dans une botte de foin). Vous voulez, pour un nombre cible, trouver le nombre le plus proche dans un tableau.