如何在C#中引用多维数组的单个维度?

时间:2010-10-18 23:32:32

标签: c# arrays multidimensional-array jagged-arrays

我遇到了一个问题,我想创建一个Array表。这是一个二维数组,其中在需要创建表之前,运行时已知行数和列数。所有行的列数都相同。

创建数组后,我只想对该数组的一维进行操作。也许传递对方法的引用。

这是一个虚构的例子:

// Create a table 3x3 table.
int[,] DistanceTable = new int[3, 3];
DistanceTable[0, 0] = 0;
DistanceTable[1, 1] = 0;
DistanceTable[2, 2] = 0;

DistanceTable[0, 1] = 10;
DistanceTable[0, 2] = 40;

DistanceTable[1, 0] = 10;
DistanceTable[1, 2] = 25;

DistanceTable[2, 0] = 40;
DistanceTable[2, 1] = 25;

// Why can't I do this?
int[] twos = DistanceTable[2];

如果我使用JaggedArray(Array-of-Arrays),我可以这样做。但是我不需要JaggedArray,因为我的multidemsional数组每行的列数总是相同。

有可能这样做吗?如果不是为什么?

由于

5 个答案:

答案 0 :(得分:3)

没有。多维数组与Jagged数组的不同之处在于它们使用Row-Major ordering按顺序存储在一个内存块中。

因此,拔出一列“数据”需要跳过才能将其拉出来。

另一方面,锯齿状数组是对第二个数组的引用数组。这样可以很容易地从锯齿状阵列中拉出单个“数组”。

  

但是我不需要JaggedArray,因为我的multidemsional数组每行的列数始终相同。

.NET中的锯齿状数组有一些巨大的性能优化。它们通常优于多维数组。这就是大多数代码分析例程建议从二维数组转换为锯齿状数组的原因。即使你不“需要”它也值得考虑。

答案 1 :(得分:2)

这是不可能的;多维数组不能那样工作。

通常,您应该始终使用锯齿状数组;它们更快。
(JITter将生成原始内存访问指令而不是方法调用)

答案 2 :(得分:1)

只有一个数组对象具有多维数组,而锯齿状数组是多个不同数组对象的嵌套。没有1-1匹配或提取方法(不涉及使用包装)。

答案 3 :(得分:1)

对不起,这应该是对How do I get a reference to a single dimension of a Multidemensional Array in C#?的评论,但我还不能发表评论..

无论如何,经过一些解释之后很容易理解为什么使用锯齿状数组表现更好的原因:让我们检查一个多维数组:

{{0,1,2},  {3,4,5},  {6,7,8}}

在内存中它存储的内容如下:{0,1,2,3,4,5,6,7,8}。

现在,假设您要访问[0,0],我们将在内存中读取哪些内容?我们必须计算地址:y * 3 + x => 0 * 3 + 0 =>在那之后,我们可以继续进行实际阅读。如果我们想要阅读整行,我们必须一遍又一遍地做这个数学。

相反,看看一个锯齿状的数组,在内存中它存储的内容如下:

a:{0,1,2} b:{3,4,5} c:{6,7,8} {ref:a,ref:b,ref:c}

假设我们要访问[0] [0],我们将在内存中读取哪些内容?首先,让我们获得对array [0]的引用。然后获取单元格[0]的内容。完成。如果我们想要读取整行,我们只需要将指针递增一个。

如果我们要遍历整个“数组”而不是一行,那么它对于锯齿状数组来说仍然具有相同的性能优势。

但有一个例外:迭代列。这对于锯齿状阵列来说真的很糟糕,因为我们要为每次访问做一个相对昂贵的内存读取。不好。

如果您认为这是一个问题,那么还有一种方法:一维数组!在这种情况下,我们使用多维数组背后的理论(y * rowLength + x),并使用一些非常简单的数学;迭代一行:只需递增1,迭代一列:只需按行长度增加。

答案 4 :(得分:0)

您可以在DictionaryTable对象上创建一个允许您指定行的扩展方法吗?

public static class IntArrayExt
{
    public static int[] Row(this int[,] array, int row)
    {
        int[] newArray = new int[3];
        for (int i = 0; i < array.Length; i++)
        {
            newArray[i] = array[row, i];
        }
        return newArray;
    }
}

int[,] distanceTable = new int[3, 3];
distanceTable[0, 0] = 0;
distanceTable[1, 1] = 0;
distanceTable[2, 2] = 0;

distanceTable[0, 1] = 10;
distanceTable[0, 2] = 40;

distanceTable[1, 0] = 10;
distanceTable[1, 2] = 25;

distanceTable[2, 0] = 40;
distanceTable[2, 1] = 25;

int[] twos = distanceTable.Row(2);

如果要获取列,可以使用另一种扩展方法。