myCars.TakeWhile(car => !myCondition(car)).Count();
Es funktioniert! Denke darüber nach. Der Index des ersten übereinstimmenden Elements entspricht der Anzahl der (nicht übereinstimmenden) Elemente davor.
Geschichtsstunde
Auch ich mag die schreckliche Standardlösung nicht, die du bereits in deiner Frage vorgeschlagen hast. Wie die akzeptierte Antwort habe ich mich für eine ganz normale Schleife entschieden, allerdings mit einer kleinen Änderung:
public static int FindIndex(this IEnumerable items, Predicate predicate) {
int index = 0;
foreach (var item in items) {
if (predicate(item)) break;
index++;
}
return index;
}
Beachte, dass es die Anzahl der Elemente zurückgibt, anstatt -1
, wenn es keine übereinstimmung gibt. Aber lassen wir uns von diesem kleinen Ärgernis vorerst nicht stören. Tatsächlich stürzt die schreckliche Standardlösung in diesem Fall ab und ich halte es für überlegen, einen Index zurückzugeben, der außerhalb der Grenzen liegt.
Jetzt sagt mir ReSharper, dass Schleifen in LINQ-Ausdrücke umgewandelt werden können. Während die Funktion die Lesbarkeit meistens verschlechtert, war das Ergebnis diesmal beeindruckend. Also Lob an JetBrains.
Analyse
Vorteile
- Kurz
- Kombinierbar mit anderen LINQ
- Vermeidet das
new
en anonymer Objekte
- Wertet nur die Auflistung aus, bis das Prädikat zum ersten Mal übereinstimmt
Daher halte ich es für optimal in Bezug auf Zeit und Platzbedarf und bleibt dabei lesbar.
Nachteile
- Am Anfang nicht ganz offensichtlich
- Gibt kein
-1
zurück, wenn es keine Übereinstimmung gibt
Natürlich kannst du es immer hinter einer Erweiterungsmethode verbergen. Und was im Falle keiner übereinstimmung am besten zu tun ist, hängt stark vom Kontext ab.
0 Stimmen
Ähnlich: get-list-element-position-in-c-sharp-using-linq
0 Stimmen
Auch diese Informationen wären hilfreich - stackoverflow.com/questions/4049773/…
11 Stimmen
Eigentlich gibt es eine
index
Anweisung:var result = items.Select((item, index) => new { index, item });