startIndex
とcount
がある場合、LINQでコレクションをページングするにはどうすればよいですか?LINQでコレクションをページングする
答えて
数ヶ月前に私は、LINQのコレクションをページ付け、次の自然な方法を提供するIQueryable<T>
と別のクラスに拡張メソッドを使用流暢インターフェイスとLINQに関するブログ記事を書きました。
var query = from i in ideas
select i;
var pagedCollection = query.InPagesOf(10);
var pageOfIdeas = pagedCollection.Page(2);
コードは、MSDNコードギャラリーページから入手できます。Pipelines, Filters, Fluent API and LINQ to SQL
Skip
とTake
拡張メソッドでは非常に簡単です。
var query = from i in ideas
select i;
var paggedCollection = query.Skip(startIndex).Take(count);
この質問は多少古くなっていますが、手順全体(ユーザーとの対話を含む)を示すページングアルゴリズムを投稿したいと考えました。あなたは、パフォーマンスの後であり、生産コードで、我々はすべてのパフォーマンス後にしている場合
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);
しかし、あなたは上記のようにLINQのページングを使用すべきではありませんが、基礎となるIEnumerator
むしろ自分でページングを実装します。実際のところ、それは、上に示したLINQ-アルゴリズムと同じくらい簡単ですが、よりパフォーマンス:
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);
}
説明:「カスケード方式」での複数回のSkip()
を使用しての欠点は、ということであり、最後にスキップされた反復の「ポインタ」は実際には格納されません。代わりに元のシーケンスにスキップコールがフロントロードされます。これにより、既に消費されたページを何度も何度も「消費」することになります。 - シーケンスideas
を作成して副作用が生じるように自分自身で証明することができます。 - > 10-20と20-30をスキップして40+を処理したい場合でも、40+の繰り返しを開始する前に、10-30のすべての副作用が再度実行されるのを見るでしょう。 IEnumerable
のインターフェースを直接使用するバリアントは、最後の論理ページの終わりの位置を覚えているので、明示的にスキップする必要はなく、副作用は繰り返されません。
私はリピーターで自分のページネーターを作っていたので、他のものと少し違って解決しました。だから私は、最初に私が持っているアイテムのコレクションのためのページ番号のコレクションを作っ:
// 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]
私は簡単に「ページ」のコレクションにアイテムコレクションを分割することができ、これを使用します。この場合のページは単なるアイテムの集合(IEnumerable<Item>
)です。あなたは追加のコレクションとして、各ページを処理する必要がなく、例えばもちろん
IEnumerable<IEnumerable<Item>> pageRange
.Select((page, index) =>
myItems
.Skip(index*PageSize)
.Take(PageSize));
:これは、上記で作成したpageRange
からインデックスを選択して一緒にSkip
とTake
を使用してそれを行うことができる方法でありますリピーターを入れ子にしている場合は、実際には扱いやすいです。
ワンライナーTLDRバージョンは、このようになります:
このとして使用することができますvar pages = Enumerable
.Range(0, pageCount)
.Select((index) => myItems.Skip(index*PageSize).Take(PageSize));
:
for (Enumerable<Item> page : pages)
{
// handle page
for (Item item : page)
{
// handle item in page
}
}
- 1. LINQとリストビューによるページング
- 2. Backbone.jsのページングされたコレクション
- 3. linqを使用するコレクション
- 4. Linqを汎用コレクションのページングに使用するにはどうすればよいですか?
- 5. LINQでSelectListItemのコレクションを作成する
- 6. ネストしたコレクションをLinqでソートする
- 7. コレクションのLinq結合コレクション
- 8. linqでコレクションのコレクションをフィルタリングする方法は?
- 9. LINQ(コレクション内のコレクション)でコードを簡略化する
- 10. LINQ:グループ化コレクション
- 11. linqページング - 合計行を取得
- 12. Linqは別のコレクションの値でコレクションを更新しますか?
- 13. LINQ - 子コレクションのフィルタリング
- 14. Linqの子コレクションをフィルタリングする方法
- 15. コレクションを比較するエンティティへのLINQ
- 16. NHibernate - ページングされた子コレクションを持つ親を取得する
- 17. VB.NET LINQ - コレクション内のコレクションの数?
- 18. Linqからのコレクション内のコレクション
- 19. 同じlinqチェーン内のlinqコレクションを参照する方法は?
- 20. ビジネスレイヤのページング/並べ替えグリッドビューのLINQ
- 21. ページングのサポート - ADO.NET Entitry FrameworkとLINQ
- 22. オーバーレイ/ Linqで2つのコレクションを結合
- 23. LINQどこにコレクションの句
- 24. フィルタの親コレクションのLINQクエリ
- 25. linqの子コレクションの最後
- 26. レルムC# - 空のコレクションのLINQ
- 27. 2つのコレクションを繰り返すLINQ
- 28. Linqを使ってNHibernateでオブジェクトと子コレクションを取得する
- 29. コレクションでLINQを使用して複製を確認する
- 30. LINQで必要なコレクションを取得する方法
私はそれがこのような何かをするためにOKだと信じています。彼は答えを持っているかもしれないが、多分彼は他の人々が同様に思い付くことができるものを見たいと思うかもしれない。 –
これは、StackOverflowのベータ期間の最初の日、つまり記事IDの66日に最初に掲載されました。私はジェフのためにシステムをテストしていました。それは、ベータテストから時々出てくる通常のテストの間違いの代わりに、役に立つ情報のように思えました。 –