3 Stimmen

Aufgeräumte Möglichkeit, die Position meines Objekts in Linq-Sammlungen zu erhalten

Ich habe derzeit ein Objekt namens Woche. Eine Woche ist Teil eines Saison-Objekts. Die Saison kann viele Wochen enthalten. Was ich tun möchte, ist die Position meiner Woche zu finden (ist es die erste Woche in der Saison (also #1) oder ist es die zweite (also #2).

int i = 0;
        foreach ( var w in Season.Weeks.OrderBy(w => w.WeekStarts)){
            if(w.Id == Id){
                return i;
            }
            i+=1;
        }

Im Moment ist das, was ich habe. Ich ordne die Wochen in einem zweiten Schritt nach ihrem Startdatum, um sicherzustellen, dass sie in der richtigen Reihenfolge sind. Und ich durchlaufe sie, bis ich die Woche finde, die mit der Woche übereinstimmt, die ich mir gerade anschaue. und gibt den int zurück, den ich hochgezählt habe..

Ich habe das Gefühl, dass es einen einfacheren Linq-Weg geben sollte, dies zu tun, da es ziemlich unordentlich aussieht!

5voto

Ani Punkte 107342

Wenn Sie es vorziehen, keine FindIndex-Erweiterungsmethode zu schreiben oder die sortierten Elemente in ein Array/Liste zu laden, könnten Sie die Überladung von Select verwenden, die den Index des Elements liefert:

 return Season.Weeks
              .OrderBy(w => w.WeekStarts)
              .Select((week, index) => new { Week = week, Index = index })
              .First(a => a.Week.Id == Id)
              .Index;

Wenn nicht garantiert ist, dass die angegebene Id existiert, verwenden Sie stattdessen FirstOrDefault:

var weekIndexTuple = Season.Weeks
                           .OrderBy(w => w.WeekStarts)
                           .Select((week, index) => 
                                    new { Week = week, Index = index })
                           .FirstOrDefault(a => a.Week.Id == Id);

if(weekIndexTuple != null)
{
    return weekIndexTuple.Index;
}
else
{
   // Ich bin mir nicht sicher, wie Sie in diesem Fall weitermachen möchten.
   ...      
}

2voto

Joel Beckham Punkte 17560

Hier sind Antworten auf eine sehr ähnliche Frage: Wie kann man den Index eines Elements in einem IEnumerable erhalten?

Viele Antworten sind sehr ähnlich zu dem, was du bereits machst. Es könnte eine gute Idee sein, die Logik in eine Erweiterungsmethode auszulagern, um die Trennung der Belange und die einfachere Wiederverwendung zu erleichtern. Hier ist der Code von Marc Gravell aus dem obigen Link:

public static int IndexOf(this IEnumerable source, T value)
{
    int index = 0;
    var comparer = EqualityComparer.Default; // oder als Parameter übergeben
    foreach (T item in source)
    {
        if (comparer.Equals(item, value)) return index;
        index++;
    }
    return -1;
}

1voto

Daniel DiPaolo Punkte 53359

SLaks hat eine praktische Erweiterungsmethode für IEnumerables gepostet, die Ihnen eine Methode gibt, um den Index innerhalb von LINQ-Aufrufen selbst zu finden: Wie kann man den Index mit LINQ erhalten?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X