In the C# programming language, how do I pass a row of a multi-dimensional array? For example, suppose I have the following:
在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???
}
Also, could anyone explain to me the benefit of having rectangular and jagged arrays in C#? Does this occur in other popular programming languages? (Java?) Thanks for all the help!
另外,有人可以向我解释在C#中使用矩形和锯齿状阵列的好处吗?这是否会出现在其他流行的编程语言中? (Java?)感谢所有的帮助!
3 个解决方案
#1
8
You can't pass a row of a rectangular array, you have to use a jagged array (an array of arrays):
你不能传递一行矩形数组,你必须使用锯齿状数组(数组数组):
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]);
EDIT
If you find it so annoying to use a jagged array and desperately need a rectangular one, a simple trick will save you:
编辑如果您发现使用锯齿状阵列非常烦人并且迫切需要一个矩形阵列,一个简单的技巧将为您节省:
int FindLeast(int[,] rectangularArray, int row)
#2
4
You don't, with a rectangular array like that. It's a single object.
你没有,像这样的矩形阵列。这是一个单一的对象。
Instead, you'd need to use a jagged array, like this:
相反,你需要使用锯齿状数组,如下所示:
// 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];
}
Then you can pass each "sub"-array:
然后你可以传递每个“子” - 阵列:
int[] least = new int[foo.Length];
for(int i = 0; i < 6; i++)
{
least[i] = FindLeast(foo[i]);
}
Note that there's no need to pass foo[i]
by reference1, and also it's a good idea to assign local variables values at the point of declaration, when you can. (It makes your code more compact and simpler to understand.)
请注意,不需要通过reference1传递foo [i],并且最好在声明时分配局部变量值,如果可以的话。 (它使您的代码更紧凑,更易于理解。)
1 If you're not sure about this, you might want to read my article on parameter passing in C#.
1如果您对此不确定,可能需要阅读我在C#中传递参数的文章。
#3
-1
Update: As Jon Skeet rightly points out, this does not provide a reference to the row, but rather creates a new copy. If your code needs to change a row, this method doesn't work. I have renamed the method to make this clear.
更新:正如Jon Skeet正确指出的那样,这不会提供对该行的引用,而是创建一个新副本。如果您的代码需要更改行,则此方法不起作用。我已经重命名了这个方法,以明确这一点。
Update 2: If you want to be able to edit the fields, and have the changes happen to the parent array, too, you can use the wrapper I provide in this library I maed. The resulting row foo.Row(i)
is not an array, but instead implements IList
, so if you need to pass an array this is not a solution, either.
更新2:如果您希望能够编辑字段,并且也对父数组进行了更改,则可以使用我在此库中提供的包装器。生成的行foo.Row(i)不是数组,而是实现IList,因此如果需要传递数组,这也不是解决方案。
This extension method will allow you to query a multi-dimensional array for rows. It should be noted that this is computationally heavy (not efficient) and if it is possible you should use a jagged array for these situations. If, however, you find yourself in a situation where you cannot use a jagged array, this might be useful.
此扩展方法将允许您查询行的多维数组。应该注意的是,这在计算上很重(效率不高),如果有可能,你应该在这些情况下使用锯齿状数组。但是,如果您发现自己处于无法使用锯齿状阵列的情况,则可能会有用。
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;
}
Your code can now be rewritten:
您的代码现在可以重写:
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));
}
#1
8
You can't pass a row of a rectangular array, you have to use a jagged array (an array of arrays):
你不能传递一行矩形数组,你必须使用锯齿状数组(数组数组):
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]);
EDIT
If you find it so annoying to use a jagged array and desperately need a rectangular one, a simple trick will save you:
编辑如果您发现使用锯齿状阵列非常烦人并且迫切需要一个矩形阵列,一个简单的技巧将为您节省:
int FindLeast(int[,] rectangularArray, int row)
#2
4
You don't, with a rectangular array like that. It's a single object.
你没有,像这样的矩形阵列。这是一个单一的对象。
Instead, you'd need to use a jagged array, like this:
相反,你需要使用锯齿状数组,如下所示:
// 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];
}
Then you can pass each "sub"-array:
然后你可以传递每个“子” - 阵列:
int[] least = new int[foo.Length];
for(int i = 0; i < 6; i++)
{
least[i] = FindLeast(foo[i]);
}
Note that there's no need to pass foo[i]
by reference1, and also it's a good idea to assign local variables values at the point of declaration, when you can. (It makes your code more compact and simpler to understand.)
请注意,不需要通过reference1传递foo [i],并且最好在声明时分配局部变量值,如果可以的话。 (它使您的代码更紧凑,更易于理解。)
1 If you're not sure about this, you might want to read my article on parameter passing in C#.
1如果您对此不确定,可能需要阅读我在C#中传递参数的文章。
#3
-1
Update: As Jon Skeet rightly points out, this does not provide a reference to the row, but rather creates a new copy. If your code needs to change a row, this method doesn't work. I have renamed the method to make this clear.
更新:正如Jon Skeet正确指出的那样,这不会提供对该行的引用,而是创建一个新副本。如果您的代码需要更改行,则此方法不起作用。我已经重命名了这个方法,以明确这一点。
Update 2: If you want to be able to edit the fields, and have the changes happen to the parent array, too, you can use the wrapper I provide in this library I maed. The resulting row foo.Row(i)
is not an array, but instead implements IList
, so if you need to pass an array this is not a solution, either.
更新2:如果您希望能够编辑字段,并且也对父数组进行了更改,则可以使用我在此库中提供的包装器。生成的行foo.Row(i)不是数组,而是实现IList,因此如果需要传递数组,这也不是解决方案。
This extension method will allow you to query a multi-dimensional array for rows. It should be noted that this is computationally heavy (not efficient) and if it is possible you should use a jagged array for these situations. If, however, you find yourself in a situation where you cannot use a jagged array, this might be useful.
此扩展方法将允许您查询行的多维数组。应该注意的是,这在计算上很重(效率不高),如果有可能,你应该在这些情况下使用锯齿状数组。但是,如果您发现自己处于无法使用锯齿状阵列的情况,则可能会有用。
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;
}
Your code can now be rewritten:
您的代码现在可以重写:
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));
}