使用LINQ拆分数组

bpsygsoo  于 2022-12-15  发布在  其他
关注(0)|答案(8)|浏览(231)

我有一个像这样的一维集合:

[1,2,4,5.....n]

我想将该集合转换为二维集合,如下所示:

[[1,2,3],
[4,5,6],
...]

基本上我想分组或拆分,如果你想,数组在组'n'成员
我可以用foreach语句来完成,但我目前正在学习LINQ,因此我不想手动迭代所有元素并创建新数组,而是想使用LINQ特性(如果适用)
有什么LINQ函数可以帮助我完成这个吗?
我在想在GroupBySelectMany我不知道他们是否会帮助我虽然但他们可能会
任何帮助将真正感谢它=):**

rqcrx0a6

rqcrx0a61#

您可以按索引除以批处理大小进行分组,如下所示:

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());
ztigrdn8

ztigrdn82#

使用MoreLinq .批处理

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
bzzcjhmw

bzzcjhmw3#

您需要Take()Skip()。这些方法将允许您拆分一个IEnumerable。然后您可以使用Concat()将它们重新组合在一起。

ifmq2ha2

ifmq2ha24#

下面的示例将数组拆分为每组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();
sbtkgmzw

sbtkgmzw5#

它不是一个纯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);
}
juzqafwq

juzqafwq6#

这很简单:

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;
    }
}
bz4sfanl

bz4sfanl7#

我基于Jeremy Holovacs's答案的解决方案,并使用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);
unhi4e5o

unhi4e5o8#

从.NET 6开始,有System.Linq.Enumerable.Chunk(this IEnumerable<TSource>, int size) extension method,它返回一个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();
}

产出

相关问题