我有一个C#字符串集合。每个字符串都是一个可以出现在页面上的句子。我还有一组分页符,它是int的集合。表示将字符串集合拆分为新页面的索引。

示例:字符串集合中的每10个项目都是一个页面,因此分页符集合将是int的集合,其值为10,20,30 ......

因此,如果有2个字符串页面,则分页符集合中将有1个项目,如果有1个页面,则分页符集合将没有项目。

我正在尝试创建以下功能:

List<string> GetPage(List<string> docList, List<int> pageBreakList, int pageNum)
{
    // This function returns a subset of docList - just the page requested
}

我在写这个函数时已经采取了一些措施,并继续提出复杂的if和switch语句,以考虑在该范围之外请求的单页和双页文档和页码(例如,如果返回最后一页,则应返回如果页码为0或更少,页码大于页数和第一页。)

我对这个问题的困难让我提出了一个问题:是否有一个众所周知的模式或算法来解决这种类型的子集查询?

有帮助吗?

解决方案

&QUOT;纯QUOT; Linq不适合这个问题。最合适的是依赖List(T)的方法和属性。没有 - 那么多特殊情况。

//pageNum is zero-based.
List<string> GetPage(List<string> docList, List<int> pageBreaks, int pageNum)
{

  // 0 page case
  if (pageBreaks.Count != 0)
  {
    return docList;
  }

  int lastPage = pageBreaks.Count;

  //requestedPage is after the lastPage case
  if (requestedPage > lastPage)
  {
    requestedPage = lastPage;
  }


  int firstLine = requestedPage == 0 ? 0  :
      pageBreaks[requestedPage-1];
  int lastLine = requestedPage == lastPage ? docList.Count :
      pageBreaks[requestedPage];

  //lastLine is excluded.  6 - 3 = 3 - 3, 4, 5

  int howManyLines = lastLine - firstLine;

  return docList.GetRange(firstLine, howManyLines);
}

您不希望使用linq的.Count()方法替换.Count属性。 您不希望使用linq的.Skip(n).Take(m)方法替换.GetRange()方法。

如果你想将这些集合投射到其他集合中,Linq会更合适:

IEnumerable<Page> pages =
  Enumerable.Repeat(0, 1)
  .Concat(pageBreaks)
  .Select
  (
    (p, i) => new Page()
    {
      PageNumber = i,
      Lines = 
        docList.GetRange(p, ((i != pageBreaks.Count) ? pageBreaks[i] : docList.Count)  - p)
    }
  );

其他提示

不确定分页符列表的用途。我会这样想。字符串集合,页码和页面大小。然后你可以做类似的事情:

List<string> strings = ...
int pageNum = ...
int pageSze = ...

if (pageNum < 1) pageNum = 1;
if (pageSize < 1) pageSize = 1;

List<string> pageOfStrings = strings.Skip( pageSize*(pageNum-1) ).Take( pageSize ).ToList();

如果根据您的评论每页的页数不同,请尝试以下操作。您可能需要调整边缘条件检查...

List<string> strings = ...
List<int> sizes = ...

int pageNum = ...
int itemsToSkip =  0;
int itemsToTake = 1;

if (pageNum > 1)
{
   sizes.Take( pageNum - 2).Sum();

   if (pageNum <= sizes.Count)
   {
       itemsToTake = sizes[pageNum-1]
   }
{

List<string> pageOfStrings = strings.Skip( itemsToSkip ).Take( itemsToTake );
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top