C# 将一维数组转换为二维

C# convert 1D array to 2D

我发现自己通过执行以下操作将一维字节和单个数组转换为二维。我怀疑它可能和其他方法一样快,但也许有更简洁的范例? (Linq?)

    private static byte[,] byte2D(byte[] input, int height, int width)
    {
        byte[,] output = new byte[height, width];
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                output[i, j] = input[i * width + j];
            }
        }
        return output;
    }

    private static Single[,] single2D(byte[] input, int height, int width)
    {
        Single[,] output = new Single[height, width];
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                output[i, j] = (Single)input[i * width + j];
            }
        }
        return output;
    }

泛型函数:

private static b[,] to2D<a, b>(a source, valueAt: Func<a, int, b>, int height, int width)
{
    var result = new b[height, width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            result[i, j] = valueAt(source, i * width + j);
        }
    }
    return result;
}

var bytes = to2D<byte[], byte>([], (bytes, at) => bytes[at], 10, 20);

这无助于使方法内的代码更清晰,但我注意到您有 2 个基本相同的方法,只是类型不同。我建议使用 generics.

这样您就可以只定义一次方法。使用 where 关键字,您甚至可以限制允许您的方法处理的类型。

private static T[,] Make2DArray<T>(T[] input, int height, int width)
{
    T[,] output = new T[height, width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            output[i, j] = input[i * width + j];
        }
    }
    return output;
}

你可以像这样调用这个方法

int[] a;  //or any other array.
var twoDArray = Make2DArray(a, height, width);

Buffer.BlockCopy(input, 0, output, 0, input.Length); 更快,但最快的是根本不复制数组。

如果您真的不需要单独的二维数组,您可以像访问二维数组一样通过函数、属性 或自定义类型访问一维数组。例如:

class D2<T> {
    T[] input;
    int lenght0;
    public d2(T[] input, int lenght0) {
        this.input = input;
        this.lenght0 = lenght0;
    }
    public T this[int index0, int index1] {
        get { return input[index0 * this.lenght0 + index1]; }
        set { input[index0 * this.lenght0 + index1] = value; }
    }
}

...

byte[] input = { 1, 2, 3, 4 };
var output = new D2<byte>(input, 2);
output[1, 1] = 0;  // now input is { 1, 2, 3, 0 };

此外,在 .NET 中访问多维数组比访问交错数组慢一点

我知道我迟到了,但是如果你想像访问一个 n-dimensional 数组(不复制)一样访问一维数组、列表等,你可以使用 https://github.com/henon/SliceAndDice这样做而不复制。

// create a 2D array of bytes from a byte[]
var a = new ArraySlice<byte>( new byte[100], new Shape(10,10));
// now access with 2d coordinates
a[7,9]=(byte)56;

当然,对于简单的2d,3d,... nd卷,每个人都可以轻松完成。但是这个库还允许在不复制的情况下对 n-dimensional 数组进行切片。