创建(大部分)长度相等的集合

本文关键字:集合 大部分 创建 | 更新日期: 2023-09-27 18:12:48

使用LINQ(或morelinq),如何将未知长度(但较小)的数组划分为偶数集,最后是较小的(不均匀的)集,但保持每个列表内的顺序?

var array = new int[] {1,2,3,4}; var sets = array.something(3); 寻找…的结果:{1,2},{3},{4}

{1} -> {1},{},{}
{1,2} -> {1},{2},{}
{1,2,3} -> {1},{2},{3}
{1,2,3,4} -> {1,2},{3},{4}
{1,2,3,4,5} -> {1,2},{3,4},{5}
{1,2,3,4,5,6} -> {1,2},{3,4},{5,6}

我的原始代码:

const int MaxPerColumn = 6;
var perColumn = (list.Count + columnCount - 1) / columnCount;
for (var col = 1; col <= columnCount; col++)
{
    var items = list.Skip((col - 1) * columnCount).Take(perColumn).Pad(MaxPerColumn, "").ToList();
    // DoSomething
}

没有工作,因为{1,2,3,4}列表创建了{1,2},{3,4},{}

创建(大部分)长度相等的集合

我建议不要在这里使用Linq,而是在实现中使用IEnumerator<T>,甚至不是IEnumerable<T>:

public static IEnumerable<T[]> Something<T>(this IEnumerable<T> source, int count) {
  if (null == source)
    throw new ArgumentNullException("source");
  else if (count <= 0)
    throw new ArgumentOutOfRangeException("count");
  int c = source.Count();
  int size = c / count + (c % count > 0 ? 1 : 0);
  int large = count - count * size + c;    
  using (var en = source.GetEnumerator()) {
    for (int i = 0; i < count; ++i) {
      T[] chunk = new T[i < large ? size : size - 1];
      for (int j = 0; j < chunk.Length; ++j) {
        en.MoveNext();
        chunk[j] = en.Current;
      }
      yield return chunk;
    }
  }
}

var array = new int[] { 1, 2, 3, 4 };
string result = string.Join(", ", array
  .Something(5)
  .Select(item => $"[{string.Join(", ", item)}]"));
// [1], [2], [3], [4], []
Console.Write(result);

这是一个链接

public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int count)
{
    int c = source.Count();
    int chunksize = c / count + (c % count > 0 ? 1 : 0);
    while (source.Any())
    {
        yield return source.Take(chunksize);
        source = source.Skip(chunksize);
    }
}

基于https://stackoverflow.com/a/6362642/215752和https://stackoverflow.com/a/39985281/215752