将列表拆分成N个小的列表

我试图将一个列表分成一系列较小的列表。

我的问题:我的分割列表function不会将它们分割成正确大小的列表。 它应该将它们分成30个大小的列表,而是将它们分成大小为114的列表?

我怎样才能让我的function分成一个列表大小为30或更less的 X列表?

public static List<List<float[]>> splitList(List <float[]> locations, int nSize=30) { List<List<float[]>> list = new List<List<float[]>>(); for (int i=(int)(Math.Ceiling((decimal)(locations.Count/nSize))); i>=0; i--) { List <float[]> subLocat = new List <float[]>(locations); if (subLocat.Count >= ((i*nSize)+nSize)) subLocat.RemoveRange(i*nSize, nSize); else subLocat.RemoveRange(i*nSize, subLocat.Count-(i*nSize)); Debug.Log ("Index: "+i.ToString()+", Size: "+subLocat.Count.ToString()); list.Add (subLocat); } return list; } 

如果我在大小为144的列表上使用该函数,则输出为:

指数:4,大小:120
指数:3,大小:114
指数:2,大小:114
指数:1,大小:114
指数:0,大小:114

 public static List<List<float[]>> splitList(List<float[]> locations, int nSize=30) { var list = new List<List<float[]>>(); for (int i=0; i < locations.Count; i+= nSize) { list.Add(locations.GetRange(i, Math.Min(nSize, locations.Count - i))); } return list; } 

通用版本:

 public static IEnumerable<List<T>> splitList<T>(List<T> locations, int nSize=30) { for (int i=0; i < locations.Count; i+= nSize) { yield return locations.GetRange(i, Math.Min(nSize, locations.Count - i)); } } 

我build议使用这个扩展方法来按指定的块大小将源列表分块到子列表中:

 /// <summary> /// Helper methods for the lists. /// </summary> public static class ListExtensions { public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize) { return source .Select((x, i) => new { Index = i, Value = x }) .GroupBy(x => x.Index / chunkSize) .Select(x => x.Select(v => v.Value).ToList()) .ToList(); } } 

例如,如果您将18个项目的列表按5个大小sorting,则会显示4个列表,其中包含项目:5-5-5-3。

怎么样:

 while(locations.Any()) { list.Add(locations.Take(nSize).ToList()); locations= locations.Skip(nSize).ToList(); } 

Serj-Tm的解决scheme是好的,这也是通用版本作为列表的扩展方法(把它放到一个静态类):

 public static List<List<T>> Split<T>(this List<T> items, int sliceSize = 30) { List<List<T>> list = new List<List<T>>(); for (int i = 0; i < items.Count; i += sliceSize) list.Add(items.GetRange(i, Math.Min(sliceSize, items.Count - i))); return list; } 

我发现接受的答案(Serj-Tm)最健壮,但我想推荐一个通用版本。

  public static List<List<T>> splitList<T>(List<T> locations, int nSize = 30) { var list = new List<List<T>>(); for (int i = 0; i < locations.Count; i += nSize) { list.Add(locations.GetRange(i, Math.Min(nSize, locations.Count - i))); } return list; } 

我有一个通用的方法,将采取任何types包括浮动,它已经过unit testing,希望它可以帮助:

  /// <summary> /// Breaks the list into groups with each group containing no more than the specified group size /// </summary> /// <typeparam name="T"></typeparam> /// <param name="values">The values.</param> /// <param name="groupSize">Size of the group.</param> /// <returns></returns> public static List<List<T>> SplitList<T>(IEnumerable<T> values, int groupSize, int? maxCount = null) { List<List<T>> result = new List<List<T>>(); // Quick and special scenario if (values.Count() <= groupSize) { result.Add(values.ToList()); } else { List<T> valueList = values.ToList(); int startIndex = 0; int count = valueList.Count; int elementCount = 0; while (startIndex < count && (!maxCount.HasValue || (maxCount.HasValue && startIndex < maxCount))) { elementCount = (startIndex + groupSize > count) ? count - startIndex : groupSize; result.Add(valueList.GetRange(startIndex, elementCount)); startIndex += elementCount; } } return result; } 

Library MoreLinq有一个叫做Batch方法

 List<int> ids = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; // 10 elements int counter = 1; foreach(var batch in ids.Batch(2)) { foreach(var eachId in batch) { Console.WriteLine("Batch: {0}, Id: {1}", counter, eachId); } counter++; } 

结果是

 Batch: 1, Id: 1 Batch: 1, Id: 2 Batch: 2, Id: 3 Batch: 2, Id: 4 Batch: 3, Id: 5 Batch: 3, Id: 6 Batch: 4, Id: 7 Batch: 4, Id: 8 Batch: 5, Id: 9 Batch: 5, Id: 0 

ids被分成5个块,包含2个元素。