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.