使用 LINQ 拆分数组
本文关键字:数组 拆分 LINQ 使用 | 更新日期: 2023-09-27 18:35:54
>我有一个像这样的单维集合:
[1,2,4,5.....n]
我想将该集合转换为二维集合,如下所示:
[[1,2,3],
[4,5,6],
...]
基本上,如果您愿意,我想分组或拆分,数组成组"n"个成员
我可以使用 foreach
语句来完成,但我目前正在学习 LINQ,因此我想使用 LINQ 功能(如果适用),而不是遍历所有元素并手动创建一个新数组
是否有任何 LINQ 函数可以帮助我完成此操作?
我在GroupBy
或SelectMany
在想我不知道他们是否会帮助我,但他们可能会
任何帮助将不胜感激=) :**
您可以按索引除以批大小进行分组,如下所示:
var batchSize = 3;
var batched = orig
.Select((Value, Index) => new {Value, Index})
.GroupBy(p => p.Index/batchSize)
.Select(g => g.Select(p => p.Value).ToList());
使用 MoreLinq.Batch
var result = inputArray.Batch(n); // n -> batch size
例
var inputs = Enumerable.Range(1,10);
var output = inputs.Batch(3);
var outputAsArray = inputs.Batch(3).Select(x=>x.ToArray()).ToArray(); //If require as array
你想要Take()
和Skip()
。 这些方法将允许您拆分IEnumerable
。 然后你可以用Concat()
再次把它们拍在一起。
下面的示例
将数组拆分为每组 4 个项目。
int[] items = Enumerable.Range(1, 20).ToArray(); // Generate a test array to split
int[][] groupedItems = items
.Select((item, index) => index % 4 == 0 ? items.Skip(index).Take(4).ToArray() : null)
.Where(group => group != null)
.ToArray();
它不是一个纯粹的 LINQ,但它旨在与它一起使用:
public static class MyEnumerableExtensions
{
public static IEnumerable<T[]> Split<T>(this IEnumerable<T> source, int size)
{
if (source == null)
{
throw new ArgumentNullException("source can't be null.");
}
if (size == 0)
{
throw new ArgumentOutOfRangeException("Chunk size can't be 0.");
}
List<T> result = new List<T>(size);
foreach (T x in source)
{
result.Add(x);
if (result.Count == size)
{
yield return result.ToArray();
result = new List<T>(size);
}
}
}
}
它可以从您的代码中用作:
private void Test()
{
// Here's your original sequence
IEnumerable<int> seq = new[] { 1, 2, 3, 4, 5, 6 };
// Here's the result of splitting into chunks of some length
// (here's the chunks length equals 3).
// You can manipulate with this sequence further,
// like filtering or joining e.t.c.
var splitted = seq.Split(3);
}
它就像:
static class LinqExtensions
{
public static IEnumerable<IEnumerable<T>> ToPages<T>(this IEnumerable<T> elements, int pageSize)
{
if (elements == null)
throw new ArgumentNullException("elements");
if (pageSize <= 0)
throw new ArgumentOutOfRangeException("pageSize","Must be greater than 0!");
int i = 0;
var paged = elements.GroupBy(p => i++ / pageSize);
return paged;
}
}
我基于Jeremy Holovacs的答案的解决方案,并使用Take()和Skip()来创建子数组。
const int batchSize = 3;
int[] array = new int[] { 1,2,4,5.....n};
var subArrays = from index in Enumerable.Range(0, array.Length / batchSize + 1)
select array.Skip(index * batchSize).Take(batchSize);
从 .NET 6 开始,有System.Linq.Enumerable.Chunk(this IEnumerable<TSource>, int size)
扩展方法。它返回一个IEnumerable<TSource[]>
其中每个项目都是size
元素的数组,但最后一个项目除外,最后一个项目可能更少。
像这样编写代码:
using System;
using System.Collections.Generic;
using System.Linq;
int[] input = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int[]> chunks = input.Chunk(3);
foreach (int[] chunk in chunks)
{
foreach (int i in chunk)
{
Console.Write($"{i} ");
}
Console.WriteLine();
}
输出
1 2 3
4 5 6
7 8 9
10