繁体   English   中英

如何在C#中将double [] [](锯齿状数组)转换为double [,](矩阵)

[英]How to convert a double [][] (jagged array) to a double[,] (matrix) in C#

以下代码用于将“锯齿状数组”(即double [] [])转换为矩阵double [,]。

static T[,] To2D<T>(T[][] source)
{
    try
    {
        int FirstDim = source.Length;
        int SecondDim = source.GroupBy(row => row.Length).Single().Key; //     throws InvalidOperationException if source is not rectangular

        var result = new T[FirstDim, SecondDim];
        for (int i = 0; i < FirstDim; ++i)
            for (int j = 0; j < SecondDim; ++j)
                result[i, j] = source[i][j];

        return result;
    }
    catch (InvalidOperationException)
    {
        throw new InvalidOperationException("The given jagged array is not   rectangular.");
    } 
}

我想知道如何进行逆运算,即从double [,]转换为double [] []。

第一步,您只能创建第一级数组。 然后,您需要一个一个地创建第二级数组:

var result = new T[FirstDim][];
for (int i = 0; i < FirstDim; i++) {
    var a = new T[SecondDim];
    result[i] = a;
    for (int j = 0; j < SecondDim; j++) {
        a[j] = source[i,j];
    }
}

即使所得的锯齿状数组为矩形,此过程也没有捷径,因为理论上每一行都可以指向不同长度的数组(甚至为null )。 这就是为什么它被称为锯齿状数组的原因。

请注意,使用new T[size][]创建数组时,每个result[i]都会初始化为null

Se还: 锯齿状数组(C#编程指南)

这是优化的扩展:

static class extensions
{
    public static T[][] toJagged<T>(this T[,] source)
    {
        int rows = source.GetLength(0);
        int columns = source.GetLength(1);
        int size = System.Runtime.InteropServices.Marshal.SizeOf<T>();
        var result = new T[rows][];

        for (int r = 0; r < rows; r++)
        {
            var temp = new T[columns];
            Buffer.BlockCopy(source, r * columns * size, temp, 0, columns * size);
            result[r] = temp;
        }
        return result;
    }

    public static T[,] to2D<T>(this T[][] source)
    {
        int rows = source.Length;
        int columns = source.Select(i => i == null ? 0 : i.Length).Max(); // the longest row
        var result = new T[rows, columns];
        int size = System.Runtime.InteropServices.Marshal.SizeOf<T>();

        int offset = 0;
        foreach(var row in source)
        {
            if (row != null)
                Buffer.BlockCopy(row, 0, result, offset * size, row.Length * size);

            offset += columns;
        }
        return result;
    }
} // end of class extensions

样品使用和测试:

double[,] d2 = { { 1, 2, 3 }, { 4, 5, 6 } };
double[][] dj = d2.toJagged();
Debug.Print(string.Join(", ", dj.SelectMany(i => i))); // 1, 2, 3, 4, 5, 6

int[][] ij = { new[] { 1, 2 }, new[] { 3, 4, 5 }, new[] { 6, 7, 8, 9 } };
int[,] i2 = ij.to2D();
Debug.Print(string.Join(", ", i2.Cast<int>())); // 1, 2, 0, 0, 3, 4, 5, 0, 6, 7, 8, 9

这些工作无需使用pinvoke:

   static T[][] ToJag<T>(T[,] source)
    {
        try
        {
            int FirstDim = source.GetLength(0);  // rows
            int SecondDim = source.GetLength(1); // cols

            var result = new T[FirstDim][];   // only acceptable syntax ???
            for (int i = 0; i < FirstDim; ++i)
            {
                result[i] = new T[source.GetLength(1)];  // just for columns
                for (int j = 0; j < SecondDim; ++j)
                {
                    result[i][j] = source[i, j];
                }
            }

            return result;
        }
        catch (InvalidOperationException)
        {
            throw new InvalidOperationException("Invalid operation error.");
        }
    }
    static T[,] To2D<T>(T[][] source)
    {
        try
        {
            int FirstDim = source.Length;
            int SecondDim = source.GroupBy(row => row.Length).Single().Key; // throws InvalidOperationException if source is not rectangular

            var result = new T[FirstDim, SecondDim];
            for (int i = 0; i < FirstDim; ++i)
                for (int j = 0; j < SecondDim; ++j)
                    result[i, j] = source[i][j];

            return result;
        }
        catch (InvalidOperationException)
        {
            throw new InvalidOperationException("The given jagged array is not rectangular.");
        }
    }

注意:需要使用System.Linq才能使T [,] To2D(T [] []源)正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM