如何通过 Linq 将集合拆成多个块?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过 Linq 将集合拆成多个块?相关的知识,希望对你有一定的参考价值。
咨询区
BlakeH:
请问是否可以用 linq 按序生成带有多个固定 size 的块?我的理想情况下还可以对这些 块
进行操作。
回答区
Sergey Berezovskiy:
说实话,你不需要写任何代码,使用 MoreLINQ
中的批次方法即可,它可以按序拆解到固定大小的桶中,你可以直接在 Nuget 上安装 MoreLINQ 包。
int size = 10;
var batches = sequence.Batch(size);
如果你好奇它的实现方法,可参考如下源码:
public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(
this IEnumerable<TSource> source, int size)
TSource[] bucket = null;
var count = 0;
foreach (var item in source)
if (bucket == null)
bucket = new TSource[size];
bucket[count++] = item;
if (count != size)
continue;
yield return bucket;
bucket = null;
count = 0;
if (bucket != null && count > 0)
yield return bucket.Take(count).ToArray();
dana:
这个需求确实比较常见,在 .NET6 中添加了一个 Enumerable.Chunk()
扩展方法,然后你就可以像下面这样使用。
var list = new List<int> 1, 2, 3, 4, 5, 6, 7 ;
var chunks = list.Chunk(3);
// returns 1, 2, 3 , 4, 5, 6 , 7
如果你对源码感兴趣,可以参考如下:
public static IEnumerable<TSource[]> Chunk<TSource>(this IEnumerable<TSource> source, int size)
if (source == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
if (size < 1)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.size);
return ChunkIterator(source, size);
private static IEnumerable<TSource[]> ChunkIterator<TSource>(IEnumerable<TSource> source, int size)
using IEnumerator<TSource> e = source.GetEnumerator();
while (e.MoveNext())
TSource[] array = new TSource[size];
array[0] = e.Current;
int i;
for (i = 1; i < array.Length; i++)
if (!e.MoveNext())
break;
array[i] = e.Current;
if (i == array.Length)
yield return array;
continue;
Array.Resize(ref array, i);
yield return array;
break;
点评区
发现 .NET6 下的 Enumerable 增加了一些 By 系列方法:MinBy
,ExceptBy
,IntersectBy
,又有得学了。
以上是关于如何通过 Linq 将集合拆成多个块?的主要内容,如果未能解决你的问题,请参考以下文章