Смещенный цикл foreach - PullRequest
       21

Смещенный цикл foreach

3 голосов
/ 28 ноября 2011

Я хочу реализовать простую подкачку.

В настоящее время у меня есть Dictionary, и я отображаю его содержимое на странице, повторяя его с помощью цикла foreach.
Я не смог найти способ сместить цикл foreach.

Допустим, у меня есть 100 предметов. 5 штук на страницу, что в сумме составляет 20 страниц. Я начну со следующего:

int counter = 0;
int itemsPerPage = 5;
int totalPages = (items.Count - 1) / itemsPerPage + 1;
int currentPage = (int)Page.Request.QueryString("page"); //assume int parsing here
Dictionary<string, string> currentPageItems = new Dictionary<string, string>;

foreach (KeyValuePair<string, string> item in items) //items = All 100 items
{
    //---Offset needed here----
    currentPageItems.Add(item.Key, item.Value);
    if (counter >= itemsPerPage)
        break;
    counter++;
}

Это будет правильно выводить первую страницу - теперь, как мне отобразить последующие страницы?

Ответы [ 5 ]

3 голосов
/ 28 ноября 2011

Предполагая, что первая страница = страница 1:

var currentPageItems =
    items.Skip(itemsPerPage * (currentPage - 1)).Take(itemsPerPage)
    .ToDictionary(z => z.Key, y => y.Value);

Обратите внимание, что технически это не надежно, поскольку http://msdn.microsoft.com/en-us/library/xfhwa508.aspx заявляет:

For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair(Of TKey, TValue) structure representing a value and its key. The order in which the items are returned is undefined.

Таким образом, теоретически возможно для одного и того же запроса для первых 10 элементов вернуть другой набор из 10 элементов, даже без каких-либо изменений в словаре.С практической точки зрения этого не происходит.Но не ожидайте, что какие-либо дополнения к словарю будут добавлены, например, на последнюю страницу.

3 голосов
/ 28 ноября 2011

С LINQ вы можете использовать Skip и Take, чтобы легко достичь подкачки.

var currentPageItems = items.Skip(itemsPerPage * currentPage).Take(itemsPerPage);
1 голос
/ 28 ноября 2011

Если вы не хотите перебирать некоторые элементы только для того, чтобы перейти к некоторым элементам соответствующего индекса, возможно, стоит переместить ваши элементы из словаря во что-то, что можно проиндексировать, например List<KeyValuePair> (очевидно, создавая list будет перебирать ВСЕ элементы словаря, но потенциально может сделать это только один раз).

Это тогда можно использовать так:

var dictionary = new Dictionary<string, string>();
var list = dictionary.ToList();

var start = pageNumber*pageSize;
var end = Math.Min(list.Count, start + pageSize);
for (int index = start; index++; index < end)
{
    var keyValuePair = list[index];
}
1 голос
/ 28 ноября 2011

Используйте LINQ Skip() и Take():

foreach(var item in items.Skip(currentPage * itemsPerPage).Take(itemsPerPage))
{
    //Do stuff
}
1 голос
/ 28 ноября 2011

Вы можете сделать это, используя методы расширения Linq Skip и Take ...

using System.Linq

...

var itemsInPage = items.Skip(currentPage * itemsPerPage).Take(itemsPerPage)
foreach (KeyValuePair<string, string> item in itemsInPage) 
{
    currentPageItems.Add(item.Key, item.Value);
}
...