Recherche si une valeur existe dans une liste d'objets à l'aide de Linq


228

Disons que j'ai une classe Customerqui a une propriété FirstName. Ensuite, j'ai un List<Customer>.

LINQ peut-il être utilisé pour trouver si la liste contient un client Firstname = 'John'dans une seule déclaration. Comment?

Réponses:


459

LINQ définit une méthode d'extension parfaite pour résoudre ce problème exact:

using System.Linq;
...
    bool has = list.Any(cus => cus.FirstName == "John");

assurez-vous de référencer System.Core.dll, c'est là que réside LINQ.


24
Tout est bon, je me demande combien de développeurs utilisent Count alors qu'ils devraient utiliser Any?
— RichardOD

12
Vous pouvez également effectuer une recherche insensible à la casse: cus => cus.FirstName.Equals ("John", StringComparison.CurrentCultureIgnoreCase)
— jmservera

1
Je sais que c'est une vieille question, mais pourquoi n'utilisons-nous pas la méthode Exists? Voir comme c'est fait pour voir si les choses existent.
— Blackunknown

6
Parce que toutes les collections n'ont pas Exists, et cela ne prend pas une expression lambda, mais plutôt l'objet que nous recherchons.
— zvolkov

1
@zvolkov, toutes les idées pour lesquelles mon resharper suggère d'utiliser bool has = list.All (cus => cus.FirstName! = "John"); Est-ce plus optimal?
— Gullu

105

La réponse de zvolkov est parfaite pour savoir s'il existe un tel client. Si vous devez utiliser le client par la suite, vous pouvez faire:

Customer customer = list.FirstOrDefault(cus => cus.FirstName == "John");
if (customer != null)
{
    // Use customer
}

Je sais que ce n'est pas ce que vous demandiez, mais je pensais que j'aurais anticipé une question de suivi :) (Bien sûr, cela ne trouve que le premier de ces clients ... pour tous les trouver, utilisez simplement un whereclause normale .)


7
Je voudrais souligner que vous pourriez apprécier d'avoir fait cela plus tard en ce qui concerne le débogage, si vous vous trouvez soudainement curieux de savoir quel client correspondait aux critères.
— mqp

1
Juste en augmentant cette réponse d'un cos j'aime la façon dont la communauté SO va l'étape supplémentaire pour ajouter encore plus à la question / réponse.
— barneymc

1
merci ça m'a aidé, mais parfois je veux juste obtenir un boolrésultat, alors dans ce cas .Anyou .FindIndexest utilisé ici qui est rapide ?
— shaijut

1
@stom: Ce sont tous les deux O (N), en gros ... ce ne sont que des recherches linéaires.
— Jon Skeet

cogner cela. J'aime la façon dont vous utilisez la syntaxe de list.FirstOrDefault au lieu de faire une list.Where (). FirstOrDefault.
— GunWanderer

25

Une option pour la question suivante (comment trouver un client qui pourrait avoir un certain nombre de prénoms):

List<string> names = new List<string>{ "John", "Max", "Pete" };
bool has = customers.Any(cus => names.Contains(cus.FirstName));

ou pour récupérer le client de csv de liste similaire

string input = "John,Max,Pete";
List<string> names = input.Split(',').ToList();
customer = customers.FirstOrDefault(cus => names.Contains(cus.FirstName));

10

En utilisant Linq, vous avez de nombreuses possibilités, en voici une sans utiliser de lambdas:

//assuming list is a List<Customer> or something queryable...
var hasJohn = (from customer in list
         where customer.FirstName == "John"
         select customer).Any();

5
customerList.Any(x=>x.Firstname == "John")

Cela ne répond pas à la question "si" une telle entrée existe; il énumère simplement les valeurs si elles existent. Une étape supplémentaire est nécessaire pour déterminer si cette énumération n'est pas vide.
— jason

Ensuite, changez le Où en Tout. Probablement plus philosophique pour moi. J'ai rarement besoin de savoir si je m'en fiche de ceux qu'ils sont. @jmservera: vous aviez raison. J'ai abandonné LINQ il y a quelque temps et j'utilise maintenant Lambda exclusivement.
— Chris Brandsma

Je ne veux pas être pédant quand je dis que l'utilisation des appels lambda est toujours techniquement en utilisant LINQ. (En particulier, vous utilisez LINQ-to-Objects.) Vous utilisez simplement les appels de méthode plutôt que les mots-clés de langage.
— Judah Gabriel Himango

En quoi cette réponse diffère-t-elle de celle de Zvolkov?
— dotnetN00b

4

La technique que j'ai utilisée avant de découvrir .Any():

var hasJohn = (from customer in list
      where customer.FirstName == "John"
      select customer).FirstOrDefault() != null;

3
List<Customer> list = ...;
Customer john = list.SingleOrDefault(customer => customer.Firstname == "John");

john sera nul si aucun client n'existe avec un prénom "John".


2
Cela lèvera une exception si plus d'un client s'appelle John.
— Jon Skeet

1
Merci pour le commentaire. Je vais laisser la réponse comme un exemple partiellement correct.
— M4N

Il est toujours valide dans un scénario lorsque vous êtes sûr qu'il y en a 1 et que vous souhaitez qu'une exception soit levée s'il y en a plusieurs, donc je pense qu'il est bon que vous ne l'ayez pas supprimé.
— RichardOD

1

Une autre possibilité

if (list.Count(customer => customer.Firstname == "John") > 0) {
 //bla
}

4
Il est préférable d'utiliser Any dans ce scénario.
— RichardOD

1

Essayez ceci, j'espère que cela vous aidera.

 if (lstCustumers.Any(cus => cus.Firstname == "John"))
 {
     //TODO CODE
 }

4
C'est la même chose que la réponse acceptée d'il y a plus de 8 ans. Veuillez vous assurer que votre réponse est unique parmi toutes les réponses.
— Tony_Henrich
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.