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?

Tony_Henrich
quelle

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.

zvolkov
quelle
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.)

Jon Skeet
quelle
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));
Mike Sackton
quelle
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();
jmservera
quelle
5
customerList.Any(x=>x.Firstname == "John")
Chris Brandsma
quelle
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;
Ian Boyd
quelle
3
List<Customer> list = ...;
Customer john = list.SingleOrDefault(customer => customer.Firstname == "John");

John ist null, wenn kein Kunde mit dem Vornamen "John" existiert.

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