C# 多维数组行
Posted
技术标签:
【中文标题】C# 多维数组行【英文标题】:C# rows of multi-dimensional arrays 【发布时间】:2012-03-24 07:29:02 【问题描述】:在C#编程语言中,如何传递一行多维数组?例如,假设我有以下内容:
int[,] foo;
foo = new int[6,4];
int[] least;
least = new int[6];
for(int i = 0; i < 6; i++)
least[i] = FindLeast(ref foo[i]); //How do I pass the ith row of foo???
另外,谁能向我解释在 C# 中使用矩形和锯齿状数组的好处?这是否发生在其他流行的编程语言中? (爪哇?) 感谢所有的帮助!
【问题讨论】:
【参考方案1】:不能传一行的矩形数组,必须使用交错数组(数组的数组):
int[][] foo = new int[6][];
for(int i = 0; i < 6; i++)
foo[i] = new int[4];
int[] least = new int[6];
for(int i = 0; i < 6; i++)
least[i] = FindLeast(foo[i]);
编辑 如果您发现使用锯齿状数组非常烦人,并且迫切需要一个矩形数组,那么一个简单的技巧将拯救您:
int FindLeast(int[,] rectangularArray, int row)
【讨论】:
我可以将一个矩形数组传递给一个接受交错数组的函数吗? @CodeKingPlusPlus:不,你不能 所以基本上这不是一个解决方案:)【参考方案2】:你没有,像这样的rectangular array。这是一个单一的对象。
相反,您需要使用jagged array,如下所示:
// Note: new int[6][4] will not compile
int[][] foo = new int[6][];
for (int i = 0; i < foo.Length; i++)
foo[i] = new int[4];
那么你可以传递每个“子”数组:
int[] least = new int[foo.Length];
for(int i = 0; i < 6; i++)
least[i] = FindLeast(foo[i]);
请注意,没有必要通过引用传递foo[i]
1,而且最好在声明时分配局部变量值,如果可以的话。 (它使您的代码更紧凑,更易于理解。)
1如果您对此不确定,不妨阅读我在parameter passing in C# 上的文章。
【讨论】:
你秒杀我! :P 我可以将矩形数组作为锯齿状数组传递吗? 在我看来,这似乎不是一个解决方案。矩形阵列的情况下可以做什么? @NielsAbildgaard:基本上没什么。问题的答案是“你不能那样做”。这可能不是 OP 想听到的答案,但它是正确的答案。 @NielsAbildgaard:您不能将其作为数组传递,而这正是 OP 似乎正在寻找的。您可以创建自己的包装器类型,但没有迹象表明这会对 OP 有所帮助。但是,如果您认为自己有更好的答案,为什么不自己添加呢?【参考方案3】:更新:正如 Jon Skeet 正确指出的那样,这不会提供对行的引用,而是创建一个新副本。如果您的代码需要更改一行,则此方法不起作用。我已重命名该方法以明确这一点。
更新 2:如果您希望能够编辑字段,并让父数组也发生更改,您可以使用我在 this library I maed 中提供的包装器。结果行 foo.Row(i)
不是一个数组,而是实现了 IList
,所以如果您需要传递一个数组,这也不是一个解决方案。
此扩展方法将允许您查询多维数组的行。应该注意的是,这计算量很大(不是高效),如果有可能你应该在这些情况下使用锯齿状数组。但是,如果您发现自己无法使用交错数组,这可能会很有用。
public static T[] CopyRow<T>(this T[,] arr, int row)
if (row > arr.GetLength(0))
throw new ArgumentOutOfRangeException("No such row in array.", "row");
var result = new T[arr.GetLength(1)];
for (int i = 0; i < result.Length; i++)
result[i] = arr[row, i];
return result;
您的代码现在可以重写:
int[,] foo;
foo = new int[6,4];
int[] least;
least = new int[6];
for(int i = 0; i < 6; i++)
least[i] = FindLeast(ref foo.CopyRow(i));
【讨论】:
那是在复制数组内容,但不会做同样的事情。特别是,如果FindLeast
修改 数组,则该修改将不会在结果中可见。此外,foo.Row(i)
的结果不属于变量,因此无法编译代码。您只是不能将矩形数组视为锯齿状数组 - 数组不能那样工作。
我不明白您对编译的评论。代码运行并编译。
你完全正确!这不会传递对行的引用(无法完成)。假设 FindLeast
没有修改该行,这应该可以工作。不过,我将重命名该方法:)
它可以解决 OP 的 FindLeast
示例,但它没有解决将矩形数组的单行作为一维数组传递的更普遍的问题,这是(我一直在说)不可能的。
老实说,我认为这是隐含的。 “传递一行多维数组”和“传递一行多维数组的副本”是两个不同的东西。我认为说“你不能通过一行”比声称你可以,实际上只是通过一个副本要清楚得多。我仍然认为对 OP 问题的最佳答案是“你不能”。以上是关于C# 多维数组行的主要内容,如果未能解决你的问题,请参考以下文章