【问题标题】:Pagination in C# - can I simplify my code? [closed]C# 中的分页 - 我可以简化我的代码吗? [关闭]
【发布时间】:2014-05-19 17:48:19
【问题描述】:

我可以简化我的代码吗?

我有很长的清单。我使用一些 API,每个方法调用最多接受 25 条记录。

我写了简单的分页

List<long> items = new List<long>(); // this will contain 100+ records

int itemsCnt = items.Count();
int pagesCnt = (itemsCnt + (itemsCnt % 25)) / 25; // calculating total pages

int page = 0;

while (page < pagesCnt)
{
    List<long> itemsSinglePageList = items.GetRange(page, 25);

    ProcessPageOfRecords(itemsSinglePageList);
    page++;
}

我想知道我是否可以简化一下。

【问题讨论】:

  • 这个问题似乎跑题了,因为它属于codereview.stackexchange.com
  • 我觉得 stackoverflow 走错了路。我想知道“questions_about_for_loops_in_cpp.stackexchange.com”或“questions_about_tables_in_html.stackexchange.com”之类的网站何时开始出现。

标签: c# pagination


【解决方案1】:
int pagesCnt = (itemsCnt + (itemsCnt % 25)) / 25; // calculating total pages

这不是你想要的。模数是余数,这意味着它用于减法,而不是加法。以下两个是正确的,但我更喜欢后者:

int pagesCnt = ((itemsCnt - (itemsCnt % 25)) / 25) + 1; 

int pagesCnt = Math.Ceiling ( (double)itemsCnt / 25 ) ; //Rounding up is basically what you want here.

但是,为了进行深入审查,我建议将其发布到 https://codereview.stackexchange.com/,因为它们更适合这些类型的答案。

编辑解释为什么在您的情况下模数使用错误:

假设有 26 个项目。让我们使用您的公式:

(itemsCnt + (itemsCnt % 25)) / 25

(26 + (26 % 25)) / 25

(26 + (1)) / 25

(27 ) / 25

//Not casted as double, so it's an int division
1

用我的例子:

Math.Ceiling ( (double)itemsCnt / 25 )

Math.Ceiling ( (double)26 / 25 )

Math.Ceiling ( 1.04 )

2

【讨论】:

  • 我搞砸了那个模数......感谢您抓住它以及使用 Math.Ceiling() 方法的提示。这确实是我想要的。
  • 没问题,在这些类型的计算中很容易出错 :) 出于某种原因,模数是一个未被充分利用的运算,因为我看到多次出现错误用法,或者在循环 int 的情况下值,只需选择 if(myCounter == cyclusSize) myCounter = 0; 而不是 myCounter = ++myCounter % cyclusSize;。我觉得奇怪的是人们不默认使用模数进行循环操作,但也许我的数学背景使我比其他开发人员更频繁地使用它。
  • 我同意这样的计算容易出错。最好的解决方案是避免它们...查看下面关于在不进行此类计算的情况下生成批次的答案。
  • @st4hoo:这并不是纯粹针对你,也没有冒犯的意思,但我发现开发人员现在都接受“永远不应该使用困难的东西!”是非常错误的。诚然,在使用需要很少字符的操作时,创建混淆代码相当容易,因为人们试图在一行中放置太多。那里的问题是人们在一行中放置了太多代码,而不是模数对于任何人来说都很难考虑正确使用它。
  • @Flatter:我没有说“永远不要使用困难的东西!”。我说你应该避免容易出错的技术。这种方法可以减少出错的风险。另一点是:当你只想使用它时,为什么要重新发明轮子?
【解决方案2】:
var numbers = Enumerable.Range(1,100);
var items_per_page =25;
var pages = numbers.Count ()/items_per_page;

for (int i = 0; i < pages; i++)
{
    // Do something like
    var some_var = numbers.Skip(i*items_per_page).Take(items_per_page);
    // use that some_var in funky ways
}

应该这样做......

【讨论】:

  • 我想到了这个,但这应该是表现不佳吧。
  • 这应该有利于阅读和理解,对于 100 个对象,它胜过性能...如果您担心性能,可以添加ToArray,然后使用索引...
【解决方案3】:

您需要使用 PageSize 和 PageNo 吗?

我发现使用 Skip & Take 更改为 olny,然后依靠 Linq 为我做所有事情,更容易且不易出错:

var toShow = items.Skip(skip).Take(pageSize);

【讨论】:

    【解决方案4】:

    看MoreLinq的批处理方法。

    您可以像这样从源集合中快速创建批次:

    var batches = Enumerable.Range(1,100000).Batch(25);
    

    所以你的一些重构后的逻辑将是这样的:

    List<long> items = new List<long>(); // this will contain 100+ records
    
    items.Batch(25).ForEach(batch => ProcessPageOfRecords(batch));
    

    【讨论】:

      【解决方案5】:

      可能不是最有效的,但在一个 Linq 中完成。

      int pageSize = 25;
      var pages = list.Select((item, i) => new { Page = i/pageSize, Item = item })
          .GroupBy(g => g.Page)
          .Select(d => new { Page = d.Key, Items = d.Select(i => i.Item).ToList() })
          .ToList()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多