如何获取对C#中多维数组的一维的引用?
我遇到了一个问题,我想创建一个数组表。这是一个二维数组,在需要创建表之前,在运行时已知行数和列数。所有行的列数相同 一旦创建了数组,我只想对该数组的1维进行操作。可能传递对方法的引用 下面是一个虚构的例子:如何获取对C#中多维数组的一维的引用?,c#,arrays,multidimensional-array,jagged-arrays,C#,Arrays,Multidimensional Array,Jagged Arrays,我遇到了一个问题,我想创建一个数组表。这是一个二维数组,在需要创建表之前,在运行时已知行数和列数。所有行的列数相同 一旦创建了数组,我只想对该数组的1维进行操作。可能传递对方法的引用 下面是一个虚构的例子: // Create a table 3x3 table. int[,] DistanceTable = new int[3, 3]; DistanceTable[0, 0] = 0; DistanceTable[1, 1] = 0; DistanceTable[2, 2] = 0; Dis
// 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(数组的数组),它可以让我这样做。但我不需要JaggedArray,因为我的多维数组每行的列数总是相同的
有可能这样做吗?如果不是,为什么
谢谢这是不可能的;多维数组不是这样工作的 通常,您应该始终使用锯齿阵列;它们更快。
(抖动将生成原始内存访问指令而不是方法调用)只有一个数组对象具有多维数组,而锯齿数组是多个不同数组对象的嵌套。没有1-1匹配或提取方法(不涉及使用包装器)。没有。多维数组与锯齿数组的不同之处在于,它们是按顺序存储在一个内存块中,使用 因此,拉出一列数据需要跳过才能拉出 另一方面,交错数组是对第二个数组的引用数组。这使得从锯齿状阵列中提取单个“阵列”变得很容易 但我不需要JaggedArray,因为我的多维数组每行的列数总是相同的
NET中的交错阵列有一些巨大的性能优化。它们的性能通常优于多维数组。这就是为什么大多数代码分析例程会建议将二维数组转换为锯齿数组的原因。即使您不“需要”它,也值得考虑这个问题。您可以在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);
IntArrayExt中的公共静态类
{
公共静态int[]行(此int[,]数组,int行)
{
int[]newArray=newint[3];
for(int i=0;i
如果您想获得一个列,可以使用另一个扩展方法。很抱歉,这应该是对的注释,但我还不允许评论 无论如何,在经过一些解释之后,我们很容易理解为什么锯齿状数组的性能更好:让我们检查一个多维数组: {{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=>0。之后,我们可以继续进行实际读取。如果我们想读整行,我们必须一遍又一遍地做这个数学题 相反,请看一个锯齿状数组,它在内存中存储如下内容: a:{0,1,2} b:{3,4,5} c:{6,7,8} {ref:a,ref:b,ref:c} 假设我们想要访问[0][0],我们将在内存中的什么位置读取?首先,让我们获取对数组[0]的引用。然后得到单元格[0]的内容。完成。如果我们想读取整行,我们只需要将指针增加一个 如果我们要遍历整个“数组”,而不是仅仅遍历一行,那么对于交错数组来说,它仍然具有相同的性能优势 但有一个例外:迭代列。这对锯齿状阵列非常不利,因为我们将为每次访问执行相对昂贵的内存读取。不太好
如果你觉得这是一个问题,还有一种方法:一维数组!在本例中,我们使用多维数组背后的理论(y*rowLength+x),并使用一些非常简单的数学;迭代行:只需按1递增,迭代列:只需按行长递增。您需要一个锯齿状数组。不要传球,没有他们不要收200美元。有趣。我本以为多维数组会更有效(因此我希望使用它们)。谢谢你的解释!是锯齿阵@贾斯汀:是的,这很违反直觉。@Justin:Jagged通常更快,但确实占用了更多内存。为什么抖动对多维数组不起作用?计算偏移量似乎很简单(当然不会比间接查找更昂贵);我怀疑性能的提高是由于更好的缓存命中率、特定的优化案例和使用模式,这也可能与这两种方法如何“提取”常见的迭代模式有关。欢迎使用SO:-)在大多数应用程序中,这是很简单的,但是,当您迭代大数组时,执行的不多,需要性能。但是,当然,不要过度……)谢谢:)