Ich suche nach einer sehr schnellen Möglichkeit, eine Sammlung in C # herauszufiltern. Ich verwende derzeit generische List <Object> -Sammlungen, bin jedoch offen für die Verwendung anderer Strukturen, wenn diese eine bessere Leistung erbringen.
Derzeit erstelle ich gerade eine neue Liste <Objekt> und durchlaufe die ursprüngliche Liste. Wenn die Filterkriterien übereinstimmen, habe ich eine Kopie in die neue Liste eingefügt.
Gibt es einen besseren Weg, dies zu tun? Gibt es eine Möglichkeit zum Filtern, sodass keine temporäre Liste erforderlich ist?
c#
collections
filtering
Jason Z.
quelle
quelle
Antworten:
Wenn Sie C # 3.0 verwenden, können Sie linq viel besser und viel eleganter verwenden:
Wenn Sie das nicht finden
.Where
können, müssen Sie esusing System.Linq;
oben in Ihre Datei importieren .quelle
.Where(predefinedQuery)
statt verwenden.Where(x => x > 7)
?public bool predefinedQuery(int x) { return x > 7; }
. Dann.Where(predefinedQuery)
würden Sie gut funktionieren.Hier ist ein Codeblock / Beispiel für eine Listenfilterung mit drei verschiedenen Methoden, die ich zusammengestellt habe, um die Lambdas- und LINQ-basierte Listenfilterung zu zeigen.
quelle
List<T>
hat eineFindAll
Methode, die die Filterung für Sie durchführt und eine Teilmenge der Liste zurückgibt.MSDN hat hier ein großartiges Codebeispiel: http://msdn.microsoft.com/en-us/library/aa701359(VS.80).aspx
EDIT: Ich habe dies geschrieben, bevor ich ein gutes Verständnis von LINQ und der
Where()
Methode hatte. Wenn ich das heute schreiben würde, würde ich wahrscheinlich die oben erwähnte Methode von Jorge verwenden. DieFindAll
Methode funktioniert immer noch, wenn Sie in einer .NET 2.0-Umgebung stecken bleiben.quelle
Sie können IEnumerable verwenden, um die Notwendigkeit einer temporären Liste zu beseitigen.
Dabei ist Matches der Name Ihrer Filtermethode. Und Sie können dies wie folgt verwenden:
Dadurch wird bei Bedarf die Funktion GetFilteredItems aufgerufen. In einigen Fällen, in denen Sie nicht alle Elemente in der gefilterten Sammlung verwenden, kann dies zu einem guten Leistungsgewinn führen.
quelle
Um dies zu tun, können Sie die RemoveAll-Methode der "List <>" - Klasse zusammen mit einer benutzerdefinierten "Predicate" -Klasse verwenden ... aber alles, was Sie tun müssen, ist den Code zu bereinigen ... unter der Haube macht es dasselbe was du bist ... aber ja, es macht es an Ort und Stelle, also machst du dasselbe mit der temporären Liste.
quelle
Sie können die FindAll- Methode der Liste verwenden und einen Delegaten zum Filtern bereitstellen. Ich stimme jedoch @ IainMH zu, dass es sich nicht lohnt, sich zu viele Sorgen zu machen , es sei denn, es handelt sich um eine riesige Liste.
quelle
Wenn Sie möchten, können Sie auch die vom C # 3-Compiler bereitgestellte spezielle Abfragesyntax verwenden:
quelle
Die Verwendung von LINQ ist relativ viel langsamer als die Verwendung eines Prädikats, das für die Lists-
FindAll
Methode bereitgestellt wird. Seien Sie auch vorsichtig mit LINQ, da die Aufzählung vonlist
erst ausgeführt wird, wenn Sie auf das Ergebnis zugreifen. Dies kann bedeuten, dass der Inhalt, wenn Sie glauben, eine gefilterte Liste erstellt zu haben, möglicherweise von dem abweicht, was Sie beim tatsächlichen Lesen erwartet haben.quelle
Wenn Ihre Liste sehr groß ist und Sie wiederholt filtern, können Sie die ursprüngliche Liste nach dem Filterattribut und der binären Suche sortieren, um den Start- und Endpunkt zu finden.
Anfangszeit O (n * log (n)) dann O (log (n)).
Die Standardfilterung benötigt jedes Mal O (n).
quelle