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.