Wyszukiwanie, czy wartość istnieje na liście obiektów za pomocą Linq


228

Powiedz, że mam klasę, Customerktóra ma właściwość FirstName. Więc mam List<Customer>.

Czy można użyć LINQ do sprawdzenia, czy lista ma klienta Firstname = 'John'w jednym wyciągu ... jak?

Odpowiedzi:


459

LINQ definiuje metodę rozszerzenia, która jest idealna do rozwiązania tego konkretnego problemu:

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

upewnij się, że odwołujesz się do System.Core.dll, tam mieszka LINQ.


24
Wszystko jest dobre, zastanawiam się, ilu programistów używa Count, kiedy powinno używać Any?
— RichardOD

12
Możesz także wyszukiwać bez rozróżniania wielkości liter: cus => cus.FirstName.Equals ("John", StringComparison.CurrentCultureIgnoreCase)
— jmservera

1
Wiem, że to stare pytanie, ale dlaczego nie korzystamy z metody Exists? Widząc, jak się robi, aby sprawdzić, czy coś istnieje.
— Blackunknown

6
Ponieważ nie wszystkie kolekcje mają Istnienie i nie przyjmuje wyrażenia lambda, a raczej obiekt, którego szukamy.
— zvolkov

1
@zvolkov, Wszelkie pomysły, dlaczego mój resharper sugeruje używanie bool has = list.All (cus => cus.FirstName! = "John"); Czy to jest bardziej optymalne?
— Gullu,

105

Odpowiedź Zvolkova jest idealna, aby dowiedzieć się, czy istnieje taki klient. Jeśli chcesz później skorzystać z klienta, możesz:

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

Wiem, że nie o to pytasz, ale pomyślałem, że uprzedzę kolejne pytanie :) (Oczywiście, to znajdzie tylko pierwszego takiego klienta ... aby znaleźć je wszystkie, po prostu użyj normalna whereklauzula).


7
Zwracam uwagę, że możesz docenić to, że zrobiłeś to później, jeśli chodzi o debugowanie, jeśli nagle zorientujesz się, który klient spełnia kryteria.
— mqp

1
Po prostu podniosłem tę odpowiedź o jeden, bo uwielbiam sposób, w jaki społeczność SO robi dodatkowy krok, aby dodać jeszcze więcej do pytania / odpowiedzi.
— barneymc

1
dzięki, pomogło mi to, ale czasami po prostu chcę uzyskać boolwynik, więc w takim przypadku .Anylub .FindIndexjest używany tutaj, co jest szybkie ?
— shaijut

1
@stom: Oboje są O (N), w zasadzie ... są to tylko wyszukiwania liniowe.
— Jon Skeet

wysadzić to w powietrze. Podoba mi się sposób, w jaki używasz składni list.FirstOrDefault zamiast tworzenia list.Where (). FirstOrDefault.
— GunWanderer

25

Jedna z opcji dla następujących pytań (jak znaleźć klienta, który może mieć dowolną liczbę imion):

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

lub w celu pobrania klienta z csv podobnej listy

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

10

Korzystając z Linq masz wiele możliwości, tutaj bez użycia 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")

To nie odpowiada na pytanie „jeśli” taki wpis istnieje; po prostu wylicza wartości, jeśli istnieją. Potrzebny jest dodatkowy krok, aby ustalić, czy to wyliczenie nie jest puste.
— jason

Następnie zmień opcję Where to Any. Prawdopodobnie bardziej filozoficzny dla mnie. Rzadko muszę wiedzieć, czy nie dbając o to, które to są. @jmservera: miałeś rację. Dawno zrezygnowałem z LINQ i teraz używam wyłącznie Lambdy.
— Chris Brandsma

Nie chcę być pedantyczny, kiedy mówię, że używanie połączeń lambda nadal technicznie korzysta z LINQ. (W szczególności korzystasz z LINQ-to-Objects.) Po prostu używasz wywołań metod, a nie słów kluczowych w języku.
— Judah Gabriel Himango

Czym różni się ta odpowiedź od Zvolkova?
— dotnetN00b

4

Technika, której użyłem przed odkryciem .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 będzie zerowy, jeśli nie będzie klienta o imieniu „John”.


2
Spowoduje to wyjątek, jeśli więcej niż jeden klient nazywa się John.
— Jon Skeet

1
Dziękuję za komentarz. Pozostawię odpowiedź jako częściowo poprawny przykład.
— M4N

Jest to nadal ważne w scenariuszu, gdy masz pewność, że jest 1 i chcesz, aby wyjątek został zgłoszony, jeśli jest więcej niż jeden, więc myślę, że dobrze jest, że go nie usunąłeś.
— RichardOD

1

Inna możliwość

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

4
W tym scenariuszu lepiej jest użyć dowolnego.
— RichardOD

1

Spróbuj tego, mam nadzieję, że ci to pomoże.

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

4
To to samo, co przyjęta odpowiedź sprzed ponad 8 lat. Upewnij się, że Twoja odpowiedź jest unikalna wśród wszystkich odpowiedzi.
— Tony_Henrich
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.