Gibt es eine LINQ-Erweiterung oder (eine vernünftige / effiziente Menge von LINQ-Erweiterungen), die bestimmen, ob eine Sammlung mindestens 'x' Elemente hat?

8

Ich habe Code, der wissen muss, dass eine Sammlung nicht leer sein oder nur ein Element enthalten sollte.

Im Allgemeinen möchte ich eine Erweiterung des Formulars:

bool collectionHasAtLeast2Items = collection.AtLeast(2);

Ich kann einfach eine Erweiterung schreiben, die Auflistung aufzählen und einen Indexer inkrementieren, bis ich die gewünschte Größe erreicht habe oder keine Elemente mehr habe, aber ist da schon etwas im LINQ-Framework, das das tun würde? Meine Gedanken (in der Reihenfolge von dem, was zu mir kam) sind ::

bool collectionHasAtLeast2Items = collection.Take(2).Count() == 2; oder

bool collectionHasAtLeast2Items = collection.Take(2).ToList().Count == 2;

Das scheint zu funktionieren, obwohl das Verhalten der Aufnahme von mehr Elementen als die Sammlung nicht definiert ist (in der Dokumentation) Enumerable.Take Methode , scheint jedoch zu tun, was man erwarten würde.

Es ist nicht die effizienteste Lösung, entweder einmal die Elemente zu nummerieren, dann wieder zu zählen, was unnötig ist, oder einmal aufzählen, um die Elemente zu nehmen, und dann eine Liste zu konstruieren, um die count-Eigenschaft isn zu erhalten 't Enumerator-y, wie ich eigentlich nicht die Liste wollen.

Es ist nicht schön, weil ich immer zwei Behauptungen machen muss, indem ich zuerst 'x' nehme und dann überprüfe, ob ich tatsächlich 'x' erhalten habe, und es hängt von undokumentiertem Verhalten ab.

Oder vielleicht könnte ich verwenden:

bool collectionHasAtLeast2Items = collection.ElementAtOrDefault(2) != null;

Das ist jedoch nicht semantisch klar. Vielleicht ist das Beste, das mit einem Methodennamen zu verbinden, der bedeutet, was ich will. Ich gehe davon aus, dass dies effizient sein wird, habe ich nicht über den Code nachgedacht.

Einige andere Gedanken verwenden Last() , aber ich möchte explizit nicht die gesamte Sammlung aufzählen.

Oder vielleicht Skip(2).Any() , wieder nicht semantisch vollständig offensichtlich, aber besser als ElementAtOrDefault(2) != null , obwohl ich denke, dass sie das gleiche Ergebnis produzieren?

Irgendwelche Gedanken?

    
nicodemus13 14.05.2012, 12:14
quelle

3 Antworten

4
%Vor%     
Thomas Levesque 14.05.2012, 12:31
quelle
4

Sie können Count() >= 2 verwenden, wenn Sie die Sequenz ICollection implementieren?

Hinter der Szene, Enumerable.Count() Erweiterung der Methode prüft, implementiert die Sequenz unter Schleife ICollection . Wenn dies tatsächlich der Fall ist, wird Count -Eigenschaft zurückgegeben, daher sollte die Ziel-Performance O (1) sein.

Also sollte ((IEnumerable<T>)((ICollection)sequence)).Count() >= x auch O (1) haben.

    
abatishchev 14.05.2012 12:16
quelle
3

Sie könnten Count verwenden, aber wenn Leistung ein Problem ist, sind Sie besser mit Take .

%Vor%

Da Take (glaube ich) eine verzögerte Ausführung verwendet, wird sie nur einmal durch die Sammlung gehen.

abatiishchev hat erwähnt, dass Count O (1) mit ICollection ist, also könntest du so etwas machen und das Beste aus beiden Welten herausholen.

%Vor%

Du könntest auch Skip/Any verwenden, ich wette, es wäre sogar schneller als Take/Count .

    
Kendall Frey 14.05.2012 12:27
quelle