2011-04-08 52 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; 
}