【问题标题】:How to use linq to paginate a SortedList in Ascending or Descending order如何使用 linq 以升序或降序对 SortedList 进行分页
【发布时间】:2012-08-30 02:50:24
【问题描述】:

这就是我想要的:

if (order == SortOrder.Ascending) {
    return list.Values.Skip(pageIndex * numberPerPage).Take(numberPerPage);
} else if (order == SortOrder.Descending) {
    return list.Values.Reverse().Skip(pageIndex * numberPerPage).Take(numberPerPage);
}

但是,我不想每次调用时都反转列表,我可以编写一个 for 循环,向后遍历列表并自己实现分页,但我正在寻找一种简单的方法来获得这个用 linq 完成。

【问题讨论】:

  • 我认为您需要显示 list 和 list.Values 的声明/数据类型。
  • 列表很简单:SortedList list;

标签: c# linq pagination


【解决方案1】:

除了存储“排序”列表(调用Reverse 实际上只是创建一个向后迭代器,它不会重新排序)。如果您不想使用,则不必使用Skip

例如,如果您总是显示第 1 页,然后是第 2 页,然后是第 3 页,您可以简单地单独使用 Take

// done when user clicks something to change `order`
orderedEnumerator = order == SortOrder.Ascending ? list : list.Reverse();
//...
foreach(var e in orderedEnumerator.Take(pageSize)
{
// show first page
}
foreach(var e in orderedEnumerator.Take(pageSize)
{
// show second page
}
foreach(var e in orderedEnumerator.Take(pageSize)
{
// show third page
}

实际的foreach 代码可能是在不同时间执行的同一块代码,例如:

IEnumerable<MyType> GetCurrentPage()
{
    return orderedEnumerator.Take(pageSize);
}

public void nextPageButton_Click(object sender, EventArgs e)
{
   foreach(var e in GetCurrentPage())
   {
      // elements in current page
   }
}

【讨论】:

  • 这假设他们正在按顺序移动页面,但是是的。
  • 我怀疑 Reverse() 会创建一个反向迭代器,感谢您提供此信息,正是我所需要的。
  • 更多信息可以在msdn.microsoft.com/en-us/library/bb358497.aspx找到例如:“与OrderBy不同,这种排序方法在确定顺序时不考虑实际值本身。相反,它只是以相反的顺序返回元素它们是由底层来源产生的。”
【解决方案2】:

一些想法。

  1. 当他们改变排序顺序时,只反转一次列表。然后正常调用分页:

    SortOrder oldOrder = SortOrder.Ascending;
    
    void SetSortOrder(SortOrder newOrder)
    {
        if(oldOrder != newOrder)
        {
            list.Values = list.Values.Reverse().ToList();
            oldOrder = newOrder;
        }
    }
    
    IEnumerable<Stuff> GetPage(int pageIndex, int numberPerPage, SortOrder order)
    {
        SetSortOrder(order);
        return list.Values.Skip(pageIndex * numberPerPage).Take(numberPerPage);
    }
    
  2. 在内存中保留一个升序降序列表:

    List<Stuff> ascendingList, descendingList;
    
    void SetLists()
    {
        ascendingList = list.Values;
        descendingList = list.Values.Reverse().ToList();
    }
    
    IEnumerable<Stuff> GetPage(int pageIndex, int numberPerPage, SortOrder order)
    {
        return (order == SortOrder.Ascending ? ascendingList : descendingList).Skip(pageIndex * numberPerPage).Take(numberPerPage);
    }
    

【讨论】:

  • 这些解决方案都不像 for 循环那样高效,我正在寻找一种高效但更易于编写和阅读的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 2017-06-10
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
相关资源
最近更新 更多