Bob
Bob

Reputation: 99804

How can a large Array be split into smaller arrays?

Given a large array how can it be split into smaller arrays with the size of the smaller arrays specified as an argument of the method?

For instance, given numbers, what would Split's implementation be?

int[] numbers = new int[7845];

int[][] sectionedNumbers = numbers.Split(1000);

sectionedNumbers.Length; //outputs 8
sectionedNumbers[7].Length; //outputs 845

Upvotes: 4

Views: 6024

Answers (3)

stevemegson
stevemegson

Reputation: 12103

This isn't necessarily a good idea, but here's an implementation that generalises this splitting operation to IEnumerable<T>, returning an IEnumerable<IEnumerable<T>>.

public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> input, int size)
{
    return input.Select((a, i) => new { Item = a, Index = i })
                .GroupBy( b => (b.Index / size))
                .Select(c => c.Select(d => d.Item));
}

Upvotes: 7

MusiGenesis
MusiGenesis

Reputation: 75346

Reed beat me to it, but here's my method anyway:

public int[][] Split(int[] source, int size)
{
    int fullArrayCount = source.Length / size;
    int totalArrayCount = fullArrayCount;
    int remainder = source.Length - (fullArrayCount * size);
    if (remainder > 0)
    {
        totalArrayCount++;
    }
    int[][] output = new int[totalArrayCount][];
    for (int i = 0; i < fullArrayCount; i++)
    {
        output[i] = new int[size];
        Array.Copy(source, i * size, output[i], 0, size);
    }
    if (totalArrayCount != fullArrayCount)
    {
        output[fullArrayCount] = new int[remainder];
        Array.Copy(source, fullArrayCount * size,
            output[fullArrayCount], 0, remainder);
    }

    return output;
}

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564641

You can do it with an extension method:

using System;

static class Program
{
    static T[][] Split<T>(this T[] arrayIn, int length)
    {
        bool even = arrayIn.Length%length == 0;
        int totalLength = arrayIn.Length/length;
        if (!even)
            totalLength++;

        T[][] newArray = new T[totalLength][];
        for (int i = 0; i < totalLength;++i )
        {
            int allocLength = length;
            if (!even && i == totalLength - 1)
                allocLength = arrayIn.Length % length;

            newArray[i] = new T[allocLength];
            Array.Copy(arrayIn, i * length, newArray[i], 0, allocLength);
        }
        return newArray;
    }

    static void Main(string[] args)
    {
        int[] numbers = new int[8010];
        for (int i = 0; i < numbers.Length; ++i)
            numbers[i] = i;

        int[][] sectionedNumbers = numbers.Split(1000);

        Console.WriteLine("{0}", sectionedNumbers.Length);
        Console.WriteLine("{0}", sectionedNumbers[7].Length);
        Console.WriteLine("{0}", sectionedNumbers[1][0]);
        Console.WriteLine("{0}", sectionedNumbers[7][298]);
        Console.ReadKey();
    } 
}

This prints:

9
1000
1000
7298

Upvotes: 8

Related Questions