Cercare se esiste un valore in un elenco di oggetti usando Linq


228

Di 'che ho una lezione Customer che ha una proprietà FirstName. Quindi ho un List<Customer>.

LINQ può essere utilizzato per scoprire se l'elenco ha un cliente con Firstname = 'John'in una singola istruzione .. come?

Risposte:


459

LINQ definisce un metodo di estensione perfetto per risolvere questo problema esatto:

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

assicurati di fare riferimento a System.Core.dll, è qui che vive LINQ.


24
Qualcuno va bene, mi chiedo quanti sviluppatori usano Count quando dovrebbero usare Any?
— RichardOD,

12
Puoi anche effettuare una ricerca senza distinzione tra maiuscole e minuscole: cus => cus.FirstName.Equals ("John", StringComparison.CurrentCultureIgnoreCase)
— jmservera,

1
So che questa è una vecchia domanda, ma perché non stiamo usando il metodo Exists? Visto che è fatto per vedere se le cose esistono.
— Blackunknown il

6
Perché non tutte le raccolte hanno esistenze e non richiede un'espressione lambda, ma piuttosto l'oggetto che stiamo cercando.
— Zvolkov,

1
@zvolkov, Qualche idea sul perché il mio resharper mi sta suggerendo di usare bool has = list.All (cus => cus.FirstName! = "John"); È più ottimale?
— Gullu,

105

La risposta di zvolkov è quella perfetta per scoprire se esiste un cliente del genere. Se in seguito è necessario utilizzare il cliente, è possibile:

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

So che questo non è quello che mi stavi chiedendo, ma ho pensato di anticipare una domanda successiva :) (Certo, questo trova solo il primo cliente del genere ... per trovarli tutti, basta usare un whereclausola normale .)


7
Vorrei sottolineare che potresti apprezzare di averlo fatto più tardi quando si tratta di debug, se ti trovi improvvisamente curioso di sapere quale cliente corrispondesse ai criteri.
— mqp,

1
Basta dare una risposta a questa risposta perché adoro il modo in cui la community SO fa il passo in più per aggiungere ancora di più alla domanda / risposta.
— barneymc,

1
grazie mi ha aiutato, ma a volte voglio solo ottenere boolrisultati, quindi in quel caso .Anyo .FindIndexè usato qui che è veloce ?
— Shaijut,

1
@stom: Sono entrambi O (N), in sostanza ... sono solo ricerche lineari.
— Jon Skeet,

alzando questo. Mi piace il modo in cui usi la sintassi di list.FirstOrDefault invece di fare un elenco.Where (). FirstOrDefault.
— GunWanderer,

25

Un'opzione per la seguente domanda (come trovare un cliente che potrebbe avere un numero qualsiasi di nomi):

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

o per recuperare il cliente da CSV di un elenco simile

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

10

Usando Linq hai molte possibilità, qui una senza usare 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")

Ciò non risponde alla domanda "se" esiste una voce del genere; enumera semplicemente i valori se esistono. È necessario un passaggio aggiuntivo per determinare se questa enumerazione non è vuota.
— Jason,

Quindi modificare la destinazione. Probabilmente più filosofico per me. Raramente ho bisogno di sapere se senza preoccuparsi di quelli che sono. @jmservera: avevi ragione. Ho rinunciato a LINQ qualche tempo fa e ora uso esclusivamente Lambda.
— Chris Brandsma,

Non intendo essere pedante quando dico che l'uso delle chiamate lambda sta ancora tecnicamente usando LINQ. (In particolare, stai usando LINQ-to-Objects.) Stai solo usando le chiamate del metodo piuttosto che le parole chiave del linguaggio.
— Judah Gabriel Himango,

In che modo questa risposta differisce da quella di zvolkov?
— dotnetN00b,

4

La tecnica che ho usato prima di scoprire .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 sarà nullo se non esiste alcun cliente con un nome di "John".


2
Ciò genererà un'eccezione se più di un cliente si chiama John.
— Jon Skeet,

1
Grazie per il commento. Lascerò la risposta come un esempio parzialmente corretto.
— M4N,

È ancora valido in uno scenario quando sei sicuro che ci sia 1 e desideri che venga sollevata un'eccezione se più di una, quindi penso che sia positivo che tu non l'abbia eliminata.
— RichardOD,

1

Un'altra possibilità

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

4
È preferibile utilizzare Any in questo scenario.
— RichardOD,

1

Prova questo, spero che ti aiuti.

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

4
È la stessa risposta accettata di oltre 8 anni fa. Assicurati che la tua risposta sia unica tra tutte le risposte.
— Tony_Henrich,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.