4

我有一个值列表:

IList<V> values = { V1, V2, V3, V4, V5, V6, V7 };

我想将列表转换为列表列表,其中每个子列表都是指定的大小。每个子列表的大小可能会有所不同。例如:

IList<IList<V>> values_size2 = { { V1, V2 }, { V3, V4 }, { V5, V6 }, { V7 } };
IList<IList<V>> values_size3 = { { V1, V2, V3 }, { V4, V5, V6 }, { V7 } };
IList<IList<V>> values_size4 = { { V1, V2, V3, V4 }, { V5, V6, V7 } };

我可能可以使用嵌套循环很容易地做到这一点,但想知道是否有一种聪明的方法可以使用 LINQ 做到这一点?

我最初的想法是以某种方式使用Aggregate方法,但没有立即想到。

谢谢。

4

4 回答 4

6

这是一个基于泛型IEnumerableBatch函数。您只需将返回类型从 更改IEnumerable<IEnumerable<T>>IEnumerable<IList<T>>没有其他更改(因为在我的实现中它已经是一个列表。要更改整个内容以返回一个列表列表,您需要在结果上调用 `ToList ,或者创建一个更多涉及重构。

请注意,从技术上讲,这不是使用 LINQ,它只是创建一种新方法,该方法使用 LINQ 常用的相同样式和模式。

public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source
    , int batchSize)
{
    //TODO validate parameters

    List<T> buffer = new List<T>();

    foreach (T item in source)
    {
        buffer.Add(item);

        if (buffer.Count >= batchSize)
        {
            yield return buffer;
            buffer = new List<T>();
        }
    }
    if (buffer.Count >= 0)
    {
        yield return buffer;
    }
}
于 2012-12-12T17:51:06.503 回答
5

您可以使用MoreLINQ Batch 扩展(可从Nuget 获得):

IList<IList<V>> values_size2 = values.Batch(2);
IList<IList<V>> values_size3 = values.Batch(3);
IList<IList<V>> values_size4 = values.Batch(4);

您也可以在此处查看来源。

于 2012-12-12T17:51:50.193 回答
1
 public static IEnumerable<IEnumerable<T>> Chunks<T>(this IEnumerable<T> source, int chunkSize)
 {
     while (source.Any())
     {
         yield return source.Take(chunkSize);
         source = source.Skip(chunkSize);
     }
 }
于 2016-08-18T18:27:56.493 回答
1

使用 .NET 6,您可以使用新的ChunkLinq 方法

List<IList<V>> values_size2 = values.Chunk(2).ToList();
List<IList<V>> values_size3 = values.Chunk(3).ToList();
List<IList<V>> values_size4 = values.Chunk(4).ToList();
于 2021-06-16T15:28:41.300 回答