2010-10-27 78 views
1

我剛剛寫了一些分頁擴展方法,我很想知道是否有任何改進。我可以改進這些分頁擴展方法嗎?

我與底座分頁方法,在那裏你提供的頁面大小和頁面數都非常高興(如下圖所示)

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<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); 
     } 
    } 

這似乎有點嫌疑人必須爲產量回歸迭代兩次(一次爲計數一次。

是否有任何明顯的方法可以改進這些方法?

+0

對於你只通過網頁遍歷產量的回報。有一個foreach的解決方法,但我懷疑它會更快,因爲foreach本身比較慢。如果您渴望表現,我寧願改進分頁方法。像Skip()和Take()這樣的IEnumerable擴展方法可以手動編寫,並且在這種特殊情況下它們的運行速度會更快。 (你必須從X循環到Y索引,而不是從X循環到結束,然後從X循環到Y,如跳過並採取行動) – AlexanderMP 2010-10-27 05:37:04

回答

3

看看MoreLinq批次: - 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); 
} 
+0

看看這些批處理方法後,我真的無法弄清楚它們是如何工作的噢感謝您的鏈接,但看起來像一個偉大的圖書館! – 2010-10-27 06:14:14

+0

死鏈接(這就是爲什麼鏈接只有答案是壞的)。 – MrLore 2016-08-18 14:53:52

相關問題