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?

Tony_Henrich
la source

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.

zvolkov
la source
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 .)

Jon Skeet
la source
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));
Mike Sackton
la source
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();
jmservera
la source
5
customerList.Any(x=>x.Firstname == "John")
Chris Brandsma
la source
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;
Ian Boyd
la source
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".

M4N
la source
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
}
Krassi
la source
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
 }
Fabio Stratotti
la source
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