Suchen, ob in einer Liste von Objekten mit Linq ein Wert vorhanden ist


228

Angenommen, ich habe eine Klasse, Customerdie eine Eigenschaft hat FirstName. Dann habe ich eine List<Customer>.

Kann LINQ verwendet werden, um Firstname = 'John'in einer einzigen Anweisung herauszufinden, ob die Liste einen Kunden enthält . Wie?

Antworten:


459

LINQ definiert eine Erweiterungsmethode, mit der genau dieses Problem gelöst werden kann:

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

Stellen Sie sicher, dass Sie auf System.Core.dll verweisen. Dort lebt LINQ.


24
Any ist gut, ich frage mich, wie viele Entwickler Count verwenden, wenn sie Any verwenden sollen.
— RichardOD

12
Sie können auch eine Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchführen: cus => cus.FirstName.Equals ("John", StringComparison.CurrentCultureIgnoreCase)
— jmservera

1
Ich weiß, dass dies eine alte Frage ist, aber warum verwenden wir nicht die Exists-Methode? Sehen, wie es gemacht ist, um zu sehen, ob Dinge existieren.
— Blackunknown

6
Weil nicht alle Sammlungen Exists haben und es keinen Lambda-Ausdruck gibt, sondern das Objekt, nach dem wir suchen.
— Zvolkov

1
@zvolkov, Irgendwelche Ideen, warum mein Resharper vorschlägt, dass ich bool benutze, haben = list.All (cus => cus.FirstName! = "John"); Ist das optimaler?
— Gullu

105

Die Antwort von zvolkov ist die perfekte, um herauszufinden, ob es einen solchen Kunden gibt. Wenn Sie benötigen verwenden die Kunden danach, können Sie tun:

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

Ich weiß, dass Sie dies nicht gefragt haben, aber ich dachte, ich würde eine Folgefrage vorwegnehmen :) (Natürlich findet dies nur den ersten solchen Kunden ... um alle zu finden, verwenden Sie einfach a normale whereKlausel.)


7
Ich möchte darauf hinweisen, dass Sie es vielleicht zu schätzen wissen, dies später beim Debuggen getan zu haben, wenn Sie plötzlich neugierig sind, welcher Kunde den Kriterien entspricht.
— mqp

1
Ich liebe diese Art und Weise, wie die SO-Community den zusätzlichen Schritt unternimmt, um der Frage / Antwort noch mehr hinzuzufügen.
— Barneymc

1
danke es hat mir geholfen, aber manchmal möchte ich nur ein boolErgebnis erzielen, also in diesem Fall .Anyoder .FindIndexwird hier verwendet , was ist schnell ?
— Shaijut

1
@stom: Sie sind beide O (N), im Grunde ... sie sind nur lineare Suchen.
— Jon Skeet

das aufstoßen. Mir gefällt die Art und Weise, wie Sie die Syntax von list.FirstOrDefault verwenden, anstatt eine Liste zu erstellen.Where (). FirstOrDefault.
— GunWanderer

25

Eine Option für die folgende Frage (wie man einen Kunden findet, der eine beliebige Anzahl von Vornamen hat):

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

oder um den Kunden von csv einer ähnlichen Liste abzurufen

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

10

Mit Linq haben Sie viele Möglichkeiten, hier eine ohne 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")

Dies beantwortet nicht die Frage "ob" ein solcher Eintrag existiert; es werden lediglich die Werte aufgelistet, wenn sie existieren. Ein zusätzlicher Schritt ist erforderlich, um festzustellen, ob diese Aufzählung nicht leer ist.
— Jason

Ändern Sie dann "Wo" in "Beliebig". Wahrscheinlich philosophischer für mich. Ich muss selten wissen, ob sie sich nicht darum kümmern, welche sie sind. @jmservera: du hattest recht. Ich habe LINQ vor einiger Zeit aufgegeben und benutze jetzt ausschließlich Lambda.
— Chris Brandsma

Ich möchte nicht pedantisch sein, wenn ich sage, dass die Verwendung der Lambda-Aufrufe technisch immer noch LINQ verwendet. (Insbesondere verwenden Sie LINQ-to-Objects.) Sie verwenden nur die Methodenaufrufe anstelle von Sprachschlüsselwörtern.
— Judah Gabriel Himango

Wie unterscheidet sich diese Antwort von der von Zvolkov?
— dotnetN00b

4

Die Technik, die ich verwendet habe, bevor ich entdeckt habe .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 ist null, wenn kein Kunde mit dem Vornamen "John" existiert.


2
Dies löst eine Ausnahme aus, wenn mehr als ein Kunde John heißt.
— Jon Skeet

1
Danke für den Kommentar. Ich werde die Antwort als teilweise korrektes Beispiel belassen.
— M4N

Es ist immer noch gültig in einem Szenario, in dem Sie sicher sind, dass es 1 gibt und Sie möchten, dass eine Ausnahme ausgelöst wird, wenn mehr als eine vorhanden ist. Ich finde es also gut, dass Sie sie nicht gelöscht haben.
— RichardOD

1

Andere Möglichkeit

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

4
In diesem Szenario ist es vorzuziehen, Any zu verwenden.
— RichardOD

1

Versuchen Sie dies, ich hoffe es hilft Ihnen.

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

4
Das ist das Gleiche wie die akzeptierte Antwort von vor über 8 Jahren. Bitte stellen Sie sicher, dass Ihre Antwort unter allen Antworten eindeutig ist.
— Tony_Henrich
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.