找回密码
 立即注册

QQ登录

只需一步,快速开始

工控课堂 首页 工控文库 上位机编程 查看内容

如何通过 Linq 将集合拆成多个块?

2021-12-5 22:01| 发布者: gk-auto| 查看: 766| 评论: 0

摘要: 来源:StackoverflowNET技术问答https://mp.weixin.qq.com/s/Z9O0BmamvVAw6Lu_6Yx_dw咨询区BlakeH:请问是否可以用 linq 按序生成带有多个固定 size 的块?我的理想情况下还可以对这些块进行操作。回答区Sergey Bere ...

来源:Stackoverflow NET技术问答

https://mp.weixin.qq.com/s/Z9O0BmamvVAw6Lu_6Yx_dw

咨询区

  • 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> { 1234567 };

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,又有得学了。

关注公众号,加入500人微信群,下载100G免费资料!
发表评论

最新评论

热门文章
关闭

站长推荐上一条 /1 下一条

QQ|手机版|免责声明|本站介绍|工控课堂 ( 沪ICP备20008691号-1 )

GMT+8, 2025-12-23 07:14 , Processed in 0.060142 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

返回顶部