Wie durchblättern Sie eine Sammlung in LINQ, vorausgesetzt Sie haben eine startIndex
und eine count
?Eine Sammlung mit LINQ durchsuchen
Antwort
Vor ein paar Monaten schrieb ich einen Blog-Post über Fluent Interfaces und LINQ, die eine Erweiterungsmethode auf IQueryable<T>
und eine andere Klasse verwendet, um die folgende natürliche Weise Paginieren eine LINQ-Sammlung zur Verfügung zu stellen.
var query = from i in ideas
select i;
var pagedCollection = query.InPagesOf(10);
var pageOfIdeas = pagedCollection.Page(2);
Sie können den Code aus der MSDN Code Gallery Seite erhalten: Pipelines, Filters, Fluent API and LINQ to SQL.
Es ist sehr einfach mit den Erweiterungsmethoden Skip
und Take
.
var query = from i in ideas
select i;
var paggedCollection = query.Skip(startIndex).Take(count);
Diese Frage ist etwas alt, aber ich wollte meinen Paging-Algorithmus veröffentlichen, der die gesamte Prozedur (einschließlich Benutzerinteraktion) zeigt.
const int pageSize = 10;
const int count = 100;
const int startIndex = 20;
int took = 0;
bool getNextPage;
var page = ideas.Skip(startIndex);
do
{
Console.WriteLine("Page {0}:", (took/pageSize) + 1);
foreach (var idea in page.Take(pageSize))
{
Console.WriteLine(idea);
}
took += pageSize;
if (took < count)
{
Console.WriteLine("Next page (y/n)?");
char answer = Console.ReadLine().FirstOrDefault();
getNextPage = default(char) != answer && 'y' == char.ToLowerInvariant(answer);
if (getNextPage)
{
page = page.Skip(pageSize);
}
}
}
while (getNextPage && took < count);
Wenn Sie jedoch nach Leistung sind, und in der Produktion Code, sind wir alle nach Leistung, sollten Sie nicht Paging LINQ verwenden, wie oben gezeigt, sondern IEnumerator
die darunter liegende, sich Paging zu implementieren. Wie in der Tat ist es so einfach wie der LINQ-Algorithmus, der oben gezeigt, aber leistungsfähigere:
const int pageSize = 10;
const int count = 100;
const int startIndex = 20;
int took = 0;
bool getNextPage = true;
using (var page = ideas.Skip(startIndex).GetEnumerator())
{
do
{
Console.WriteLine("Page {0}:", (took/pageSize) + 1);
int currentPageItemNo = 0;
while (currentPageItemNo++ < pageSize && page.MoveNext())
{
var idea = page.Current;
Console.WriteLine(idea);
}
took += pageSize;
if (took < count)
{
Console.WriteLine("Next page (y/n)?");
char answer = Console.ReadLine().FirstOrDefault();
getNextPage = default(char) != answer && 'y' == char.ToLowerInvariant(answer);
}
}
while (getNextPage && took < count);
}
Erläuterung: Der Nachteil von Skip()
für mehrfach in einem „kaskadenartig“ verwendet, ist, dass es wird nicht wirklich den "Zeiger" der Iteration speichern, wo sie zuletzt übersprungen wurde. - Stattdessen wird die ursprüngliche Sequenz mit Skip-Anrufen geladen, was dazu führt, dass die bereits "konsumierten" Seiten immer wieder "konsumiert" werden. - Das kannst du selbst beweisen, wenn du die Sequenz ideas
so erstellst, dass es zu Nebenwirkungen kommt. -> Auch wenn Sie 10-20 und 20-30 übersprungen haben und 40+ verarbeiten möchten, sehen Sie alle Nebenwirkungen von 10-30 erneut ausgeführt werden, bevor Sie anfangen, 40+ zu wiederholen. Die Variante, die direkt die Schnittstelle IEnumerable
verwendet, erinnert sich stattdessen an die Position des Endes der letzten logischen Seite, so dass kein explizites Überspringen erforderlich ist und die Nebenwirkungen nicht wiederholt werden.
Ich löste das ein bisschen anders als das, was die anderen haben, da ich meinen eigenen Paginator mit einem Repeater machen musste. Also machte ich zum ersten Mal eine Sammlung von Seitenzahlen für die Sammlung von Gegenständen, die ich habe:
// assumes that the item collection is "myItems"
int pageCount = (myItems.Count + PageSize - 1)/PageSize;
IEnumerable<int> pageRange = Enumerable.Range(1, pageCount);
// pageRange contains [1, 2, ... , pageCount]
Mit diesem ich einfach das Element Sammlung in eine Sammlung von „Seiten“ partitionieren können. Eine Seite in diesem Fall ist nur eine Sammlung von Elementen (IEnumerable<Item>
). Dies ist, wie Sie es tun können Skip
und Take
zusammen mit der Auswahl des Index aus den oben erstellten pageRange
mit:
IEnumerable<IEnumerable<Item>> pageRange
.Select((page, index) =>
myItems
.Skip(index*PageSize)
.Take(PageSize));
Natürlich
müssen Sie jede Seite als eine zusätzliche Sammlung handhaben, aber z.B. Wenn Sie Repeater verschachteln, ist das eigentlich einfach zu handhaben.Die Einzeiler TLDR Version wäre dies:
var pages = Enumerable
.Range(0, pageCount)
.Select((index) => myItems.Skip(index*PageSize).Take(PageSize));
die als diese verwendet werden können:
for (Enumerable<Item> page : pages)
{
// handle page
for (Item item : page)
{
// handle item in page
}
}
- 1. Eine Sammlung von Regexen effizient durchsuchen
- 2. Filtering Sammlung mit LINQ
- 3. Linq Abfrage gegen eine Sammlung Eigenschaft mit einer Sammlung Parameter
- 4. So durchsuchen Sie eine Sammlung mit einem Array in Powershell
- 5. Dynamische LINQ für eine Sammlung?
- 6. Sortierung Sammlung innerhalb der Sammlung mit Linq
- 7. Linq mit benutzerdefinierten Basis-Sammlung
- 8. Linq Elemente aus einer Sammlung in eine andere Sammlung entfernen
- 9. LINQ: Gruppierung Sammlung
- 10. Wie eine Sammlung von Sammlungen in Linq
- 11. Intersect eine Sammlung von Sammlungen in LINQ
- 12. Seite eine generische Sammlung ohne Linq
- 13. Unterschied von einer Sammlung aus einer anderen Sammlung mit Linq
- 14. LINQ, schaffen einzigartige Sammlung von einer Sammlung
- 15. Wie Sie eine Sammlung und ihre Untersammlung mit LINQ bestellen?
- 16. Abfrage einer Unterkollektion einer Sammlung mit linq
- 17. C# Linq Sammlung groupby mit konvertieren
- 18. Objekt auswählen aus verschachtelten Sammlung mit Linq
- 19. Überprüfung der Duplizierung mit LINQ in Sammlung
- 20. Wie filter Kind Sammlung mit Linq dynamische
- 21. Sortierung einer beobachtbaren Sammlung mit linq
- 22. Linq: Queryable.OrderBy() mit einer Sammlung von Expressions
- 23. Versuchen, eine Sammlung mit LINQ zu filtern, wo die Sammlung eine Sammlung hat, die auch eine Sammlung mit einer Eigenschaft enthält, die nullbar ist
- 24. LINQ Abfrage zu Observable-Sammlung
- 25. Linq: IsNot in Object Sammlung
- 26. NHibernate Abfrage auf eine Zeichenfolge Sammlung mit Linq führt entweder Fehler oder leere Sammlung
- 27. Holen Sie sich eine Sammlung basierend auf der Eigenschaft einer anderen Sammlung mit Linq
- 28. Linq, um eine Sammlung mit Werten aus einer anderen Sammlung zu aktualisieren?
- 29. Wie LINQ verwenden Kind Sammlung
- 30. Durchsuchen des Tags mit Ransack
Ich glaube, dass es in Ordnung ist, so etwas zu tun. Er hat vielleicht eine Antwort, aber vielleicht will er auch sehen, was andere Leute mitbringen können. –
Dies wurde ursprünglich am ersten Tag der Beta-Phase von StackOverflow veröffentlicht, also die 66 für die Artikel-ID. Ich habe das System getestet, für Jeff. Plus es schien wie nützliche Informationen anstelle der üblichen Test Mist, der manchmal aus Beta-Tests kommt. –