我可以改进这些分页扩展方法吗?

发布于 2024-09-28 21:09:28 字数 1184 浏览 0 评论 0 原文

我刚刚编写了几个分页扩展方法,我很想知道是否可以做出任何改进。

我对基本分页方法非常满意,您可以提供页面大小和页码(如下所示),

    public static IEnumerable<T> Paginate<T>(this IEnumerable<T> source, int pageSize, int pageNumber)
    {
        if (pageSize == 0) throw new ArgumentOutOfRangeException("pageSize");
        if (pageNumber == 0) throw new ArgumentOutOfRangeException("pageNumber");

        return source.Skip(pageSize * (pageNumber - 1)).Take(pageSize);
    }

但我想知道是否有更好的方法来执行“自动”分页,它返回一个 IEnumerable>

    public static IEnumerable<IEnumerable<T>> Paginate<T>(this IEnumerable<T> source, int pageSize)
    {
        source.ThrowIfNull("source");
        if (pageSize == 0) throw new ArgumentOutOfRangeException("pageSize");

        var pageCount = (int)Math.Ceiling(source.Count() / (double)pageSize);

        if (pageSize == 1)
            pageCount = source.Count();

        for (int i = 1; i <= pageCount; i++)
        {
            yield return source.Paginate(pageSize, i);
        }
    }

必须迭代两次似乎有点可疑(一次用于计数,一次用于收益率返回。

有没有任何明显的方法可以改进这些方法?

I've just written a couple of pagination extension methods and I was curious to know if there was any improvements I could make.

I'm pretty happy with the base pagination method, where you supply both the page size and page number (as seen below)

    public static IEnumerable<T> Paginate<T>(this IEnumerable<T> source, int pageSize, int pageNumber)
    {
        if (pageSize == 0) throw new ArgumentOutOfRangeException("pageSize");
        if (pageNumber == 0) throw new ArgumentOutOfRangeException("pageNumber");

        return source.Skip(pageSize * (pageNumber - 1)).Take(pageSize);
    }

but I was wondering if there was a better way to do the "auto" pagination, where it returns a IEnumerable<IEnumerable<T>>

    public static IEnumerable<IEnumerable<T>> Paginate<T>(this IEnumerable<T> source, int pageSize)
    {
        source.ThrowIfNull("source");
        if (pageSize == 0) throw new ArgumentOutOfRangeException("pageSize");

        var pageCount = (int)Math.Ceiling(source.Count() / (double)pageSize);

        if (pageSize == 1)
            pageCount = source.Count();

        for (int i = 1; i <= pageCount; i++)
        {
            yield return source.Paginate(pageSize, i);
        }
    }

It seems a bit suspect to have to iterate twice (once for the count and once for the yield return.

Is there any obvious way I could improve these methods?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

灯角 2024-10-05 21:09:28

看一下 MoreLinq Batch:- http ://code.google.com/p/morelinq/source/browse/trunk/MoreLinq/Batch.cs?r=84

其实现为:

public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(
              this IEnumerable<TSource> source, int size)
{
  TSource[] bucket = null;
  var count = 0;

  foreach (var item in source)
  {
      if (bucket == null)
          bucket = new TSource[size];

      bucket[count++] = item;
      if (count != size)
          continue;

      yield return bucket;

      bucket = null;
      count = 0;
  }

  if (bucket != null && count > 0)
      yield return bucket.Take(count);
}

Take a look at MoreLinq Batch :- http://code.google.com/p/morelinq/source/browse/trunk/MoreLinq/Batch.cs?r=84

Which is implemented as:

public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(
              this IEnumerable<TSource> source, int size)
{
  TSource[] bucket = null;
  var count = 0;

  foreach (var item in source)
  {
      if (bucket == null)
          bucket = new TSource[size];

      bucket[count++] = item;
      if (count != size)
          continue;

      yield return bucket;

      bucket = null;
      count = 0;
  }

  if (bucket != null && count > 0)
      yield return bucket.Take(count);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文