2011-04-08 23 views
9

我現在有一個包含大約190個元素的列表。如何將列表分割成每個列表中最多包含50個元素的小列表?如何根據C#中的索引拆分列表?

結果可以是50,50,50和40個元素的列表。

+0

可能重複[分割清單與LINQ子列表(http://stackoverflow.com/questions/419019/split-list-into-sublists-with-linq) – psubsee2003 2014-04-13 11:45:47

回答

20

假設您的意思是List<T>,您可以反覆使用GetRange方法。哎呀,你可以用LINQ做到這一點:

var lists = Enumerable.Range(0, (list.Count + size - 1)/size) 
     .Select(index => list.GetRange(index * size, 
            Math.Min(size, list.Count - index * size))) 
     .ToList(); 

或者你可以只使用一個循環,當然:

public static List<List<T>> Split(List<T> source, int size) 
{ 
    // TODO: Prepopulate with the right capacity 
    List<List<T>> ret = new List<List<T>>(); 
    for (int i = 0; i < source.Count; i += size) 
    { 
     ret.Add(source.GetRange(i, Math.Min(size, source.Count - i))); 
    } 
    return ret; 
} 

這在某種程度上比使用GroupBy更有效,但它僅限於List<T>作爲輸入。

我們有另一種使用IEnumerable<T>的方法,其中MoreLINQ的方法是Batch.cs

+2

@Downvoter:護理解釋? – 2011-04-08 07:58:45

+0

歷史:我從來沒有見過喬恩,甚至連一秒都沒有看到過-1。我會問他的位置:負選民會照顧詳細嗎? - >當然他把我打到那個:-) – Peter 2011-04-08 07:59:30

+1

@Jon,我沒有倒下,但我認爲這是由於後來的例子。 – 2011-04-08 08:00:58

10

你可以使用LINQ:

var list = Enumerable.Range(1, 190); 
var sublists = list 
    .Select((x, i) => new { Index = i, Value = x }) 
    .GroupBy(x => x.Index/50) 
    .Select(x => x.Select(v => v.Value).ToList()) 
    .ToArray(); 
+0

感謝您的建議,但Jon的foreach只是更乾淨。 – Awesome 2011-04-08 08:09:49

+0

+1:我喜歡這個,因爲它是聲明性的 – Peter 2011-04-08 08:13:05

0
var list = new List<int>(Enumerable.Range(1,190)); 
var page_size = 50; 
var max_pages = 1 + list.Count()/page_size; 

for(int page = 1; page <= max_pages; page++) { 
    var chunk = list.Skip(page_size * (page-1)).Take(page_size); 
    // do whatever 
} 
1

我已經嘗試了遞歸方法。只是爲了看看它會是什麼樣子。

List<List<T>> SplitIntoChunks<T>(IEnumerable<T> originalList, int chunkSize) 
{ 
    if(originalList.Take(1).Count() == 0) 
    { 
     return new List<List<T>>(); 
    } 

    var chunks = new List<List<T>> {originalList.Take(chunkSize).ToList()}; 
    chunks.AddRange(SplitIntoChunks(originalList.Skip(chunkSize), chunkSize)); 
    return chunks; 
}