Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# chunking two-dimensional array into batches

I have a two-dimensional object[,] array which contains a matrix of rows and columns (object[nRows, nColumns]).

I would like to chunk this into a batch of rows - e.g. batches of 1,000 rows each which I can enumerate over.

In summary, I am looking for C# code that does the following but for two dimensional arrays (source):

private IEnumerable<T[]> SplitArray<T>(T[] sourceArray, int rangeLength)
{
    int startIndex = 0;

    do
    {
        T[] range = new T[Math.Min(rangeLength, sourceArray.Length - startIndex)];
        Array.Copy(sourceArray, startIndex, range, 0, range.Length);
        startIndex += rangeLength;
        yield return range;
    }
    while (startIndex < sourceArray.Length);            
}

This attempt at adapting the code for [,] arrays fails - rows/columns begin to get jumbled-up after the first iteration:

        private IEnumerable<T[,]> SplitArray<T>(T[,] sourceArray, int rangeLength)
        {
            int startIndex = 0;

            do
            {
                T[,] range = new T[Math.Min(rangeLength, sourceArray.GetLength(0) - startIndex), sourceArray.GetLength(1)];
                Array.Copy(sourceArray, startIndex, range, 0, range.Length);
                startIndex += rangeLength;
                yield return range;
            }
            while (startIndex < sourceArray.GetLength(0));
        }
like image 477
JDR Avatar asked Jul 17 '26 02:07

JDR


1 Answers

This will solve your code issues. As Array.Copy threats the array as a single dimensional, you have to multiply by the number of columns to get the total amount of elements in some places:

private IEnumerable<T[,]> SplitArray<T>(T[,] sourceArray, int rangeLength)
{
    int startIndex = 0;
    do
    {
        T[,] range = new T[Math.Min(rangeLength, sourceArray.GetLength(0) - startIndex/sourceArray.GetLength(1)), sourceArray.GetLength(1)];
        Array.Copy(sourceArray, startIndex, range, 0, range.Length);
        startIndex += rangeLength*sourceArray.GetLength(1);
        yield return range;
    }
    while (startIndex < sourceArray.Length);
}
like image 110
Magnetron Avatar answered Jul 19 '26 17:07

Magnetron



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!