从3D数组中获取子数组

时间:2014-02-18 01:19:42

标签: c# arrays

如果我有一个数组:

int[,,] mainArray = new int[10,10,3];

如何获得子数组:

int[] sub = mainArray[0,1]; // Unfortunately this doesn't work

其中sub包含3个元素

sub[0] = mainArray[0,1,0];
sub[1] = mainArray[0,1,1];
sub[2] = mainArray[0,1,2];

写一个方法来做这个很容易,但是有内置的方法吗?

3 个答案:

答案 0 :(得分:2)

我认为你可以使用这样的扩展方法:

public static class MyExtensions
{
    public static int[] GetValues(this Array source, int x, int y)
    {
        var length = source.GetUpperBound(2);
        var values = new int[length+1];
        for (int i = 0; i < length+1; i++)
        {
            values[i] = (int)source.GetValue(x, y, i);
        }
        return values;
    }
}

用法:

int[,,] mainArray = new int[10,10,3];
int[] sub = mainArray.GetValues(0, 1);

答案 1 :(得分:2)

您可以使用嵌套数组。

// Initialization
int[][][] mainArray = new int[10][][];
for (int i = 0; i < mainArray.Length; i++)
{
    mainArray[i] = new int[10][];
    for (int j = 0; j < mainArray[i].Length; j++)
    {
        mainArray[i][j] = new int[3];
    }
}

// Usage
int[] sub = mainArray[0][1];

是的,初始化有点复杂,但除此之外它们都是一样的。嵌套数组甚至有better performance(但你不应该关心数组性能,除非你的分析器告诉过你)。


这是我写的一个帮助类,用于帮助初始化嵌套数组。

public static class NestedArray
{
    public static Array Create<T>(params int[] lengths)
    {
        Type arrayType = typeof(T);
        for (int i = 0; i < lengths.Length - 1; i++)
            arrayType = arrayType.MakeArrayType();

        return CreateArray(arrayType, lengths[0], lengths.Skip(1).ToArray());
    }

    private static Array CreateArray(Type elementType, int length, params int[] subLengths)
    {
        Array array = Array.CreateInstance(elementType, length);

        if (subLengths.Length > 0)
        {
            for (int i = 0; i < length; i++)
            {
                Array nestedArray = CreateArray(elementType.GetElementType(), subLengths[0], subLengths.Skip(1).ToArray());
                array.SetValue(nestedArray, i);
            }
        }

        return array;
    }
}

用法:

int[][][] mainArray = (int[][][])NestedArray.Create<int>(10, 10, 3);

可以找到完整注释的源代码in this gist

答案 2 :(得分:1)

如果你总是想要最后一个维度,你可以使用Buffer.BlockCopy和一些数学:

Buffer.BlockCopy(mainArray, (D2*i+j)*D3*sizeof(TYPE), sub, 0, D3*sizeof(TYPE));

会将mainArray[i,j,]放入sub,其中D1D2D3是您的维度,TYPE是{{1}}的类型数组元素。

相关问题