74 votes

Comment obtenir le nombre le plus proche à partir d'une List<int> avec LINQ ?

Comment obtenir le nombre le plus proche à partir d'un List<int> avec LINQ ?

Par exemple :

List<int> numbers = new List<int>();
numbers.Add(2);
numbers.Add(5);
numbers.Add(7);
numbers.Add(10)

Je dois trouver la valeur la plus proche du numéro 9 dans la liste. Dans ce cas, il s'agit de 10.

Comment puis-je faire cela avec LINQ ?

6 votes

Pouvez-vous préciser ce que vous entendez par "plus proche d'une liste" ?

2 votes

Quels numéros, quelle liste, et qu'avez-vous essayé ?

0 votes

Tout type de code que vous pourriez fournir aide toujours à faire comprendre votre question et donc à y répondre :)

163voto

Elian Ebbing Points 8363

Si vous utilisez LINQ to Objects et la liste est longue, j'utiliserais :

List<int> list = new List<int> { 2, 5, 7, 10 };
int number = 9;

int closest = list.Aggregate((x,y) => Math.Abs(x-number) < Math.Abs(y-number) ? x : y);

Cette méthode est légèrement plus complexe que la solution proposée par Anthony Pegram, mais elle présente l'avantage de ne pas avoir à trier la liste au préalable. Cela signifie que vous avez une complexité temporelle de O(n) au lieu de O(n*log(n)) et une utilisation de la mémoire de O(1) au lieu de O(n) .

0 votes

Merci pour la réponse, mais je ne comprends pas cette partie : ? x : y, qu'est-ce que cela signifie ?

1 votes

C'est l'opérateur de condition. Voir msdn.microsoft.com/en-us/library/ty67wk28.aspx . Je l'utilise pour choisir x ou y en fonction de celui qui est le plus proche de number .

0 votes

Comment connaître l'index aussi ? l'index du numéro de placard ??

50voto

Anthony Pegram Points 58528

Si vous souhaitez utiliser LINQ pour effectuer cette tâche, vous pouvez procéder comme suit.

List<int> list = new List<int> { 2, 5, 7, 10 };
int number = 9;

// find closest to number
int closest = list.OrderBy(item => Math.Abs(number - item)).First();

7 votes

L'inconvénient de cette solution est qu'elle doit d'abord ordonner la liste, ce qui nuit aux performances si la liste est longue. Voir ma réponse pour une solution qui renvoie la valeur en O(n) temps.

1 votes

@Elian, je suis d'accord. Le mien est peut-être plus lisible. J'aurais plaidé pour une boucle générale afin d'éviter complètement LINQ si les performances n'étaient pas suffisantes, mais j'ai mon propre travail à faire ;)

3 votes

Je préférerais utiliser LINQ plutôt que des méthodes d'extension. Cependant, il s'agit toujours d'un beau code. Pas d'optimisation prématurée, juste un code simple et propre. + Je suis très content de ce que j'ai fait, et j'en suis ravi.

6voto

Les solutions ci-dessus sont toutes O(N) au mieux.

Si vous avez une grande liste et que vous exécutez cette requête sur l'élément le plus proche plusieurs fois, il serait plus efficace de trier la liste en premier ( O(NlogN) ) et utiliser ensuite List<T>.BinarySearch pour chaque requête. Les performances pour k Les requêtes sont O( (k+N)logN ) par rapport à O(kN) de la méthode précédente.

4voto

Lev Points 396

Aujourd'hui, il existe également une option simple et agréable :

List<int> list = new List<int> { 2, 5, 7, 10 };
int number = 9;

int min = list.Min(i => (Math.Abs(number - i), i)).i;

-1voto

A. Randhawa Points 51

Vous pouvez utiliser la recherche binaire. Il s'agit d'une méthode intégrée en c# qui vous aidera à rechercher le nombre le plus proche. Voici un exemple : https://msdn.microsoft.com/en-us/library/y15ef976(v=vs.110).aspx

1 votes

Une recherche binaire exige que la liste soit triée en premier, ce qui peut nuire aux performances.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X