8

In the C# programming language, how do I pass a row of a multi-dimensional array? For example, suppose I have the following:

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!

3 Answers 3

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)
Sign up to request clarification or add additional context in comments.

3 Comments

Can I pass a rectangular array to a function that accepts jagged arrays?
@CodeKingPlusPlus: No, you can't
So basically this isn't a solution :)
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.)


1 If you're not sure about this, you might want to read my article on parameter passing in C#.

7 Comments

You've beaten me by seconds! :P
Can I pass a rectangular array as a jagged array?
This, to me, seems like a non-solution. What can be done in the case of a rectangular array?
@NielsAbildgaard: Nothing, basically. The answer to the question is "you can't do that". It may not be an answer the OP wants to hear, but it's the correct answer.
@NielsAbildgaard: You can't pass it as an array, which is what the OP appeared to be looking for. You could create your own wrapper type, but there's no indication that that would help the OP. However, if you think you have a better answer, why not add it yourself?
|
-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.

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.


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));
}

8 Comments

That's copying the array contents though, which doesn't do the same thing. In particular, if FindLeast modifies the array, then that modification won't be visible in the result. Additionally, the result of foo.Row(i) isn't classified as a variable, so the code won't compile. You simply can't treat a rectangular array as if it were a jagged array - arrays just don't work like that.
I do not understand your comment about compilation. The code runs and compiles.
You are absolutely right! This not passing a reference to a row (which cannot be done). Assuming that FindLeast does not modify the row, this should work. I will rename the method, though :)
It may solve the OP's FindLeast example, but it doesn't address the more general question of passing a single row of a rectangular array as a single-dimensional array, which is (as I keep saying) impossible.
I think that is implicit, to be honest. "Pass a row of a multi-dimensional array" and "pass a copy of a row of a multi-dimensional array" are two different things. I think it's a lot clearer to say "You can't pass a row" than to claim that you can, and actually just pass a copy. I still maintain that the best answer to the OP's question is "you can't".
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.