2

I have a function that returns index of an 2d array like this

public int[] getIndex()
{
    return new int[2] { i, j };
}

I want to be able to use this function to directly access the value of the 2d array, so for example

var val = array[getIndex()]

But the getIndex() throws an error. Is there any other way I can return a key for a 2d array? or do I have to manually specify

 var val = array[getIndex()[0], getIndex()[1]]
John
  • 23
  • 4
  • Does this answer your question? [Why tuple type is not accepted as a multidimensional array index?](https://stackoverflow.com/questions/53454372/why-tuple-type-is-not-accepted-as-a-multidimensional-array-index) – OfirD Jan 27 '21 at 09:35
  • @OfirD so I have to have a separate class? there isn't any other way? – John Jan 27 '21 at 09:39
  • Yap :) or use a dictionary instead, which already supports indexing with tuples, but note that [it comes with a performance cost](https://stackoverflow.com/questions/48986130/dictionary-with-tuple-key-slower-than-nested-dictionary-why). – OfirD Jan 27 '21 at 09:41

3 Answers3

3

You can use Array.GetValue():

int element = (int)array.GetValue(getIndex());

Note that this needs a cast. I have used int in this example, but you would need to use the correct type for your array.

If you don't like having to cast, you could write an extension method:

public static class Array2DExt
{
    public static T At<T>(this T[,] array, int[] index)
    {
        return (T) array.GetValue(index);
    }
}

Which you would call like this:

var element = array.At(getIndex());
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
2

If you left with your solution manually specifying the indexes I suggest to use the code below instead. Assuming you getIndex() does more than returning some internal variables this code will perform better.

var requiredItemIndex = getIndex();
var val = array[requiredItemIndex[0], requiredItemIndex[1]];
Soul
  • 121
  • 3
1

I would consider creating a custom 2D array instead, and use a value tuple or a custom point-type to describe the index. For example:

public class My2DArray<T>{

    public int Width { get; }
    public int Height { get; }
    public T[] Data { get; }
    public My2DArray(int width, int height)
    {
        Width = width;
        Height = height;
        Data = new T[width * height];
    }

    public T this[int x, int y]
    {
        get => Data[y * Width + x];
        set => Data[y * Width + x] = value;
    }
    public T this[(int x, int y) index]
    {
        get => Data[index.y * Width + index.x];
        set => Data[index.y * Width + index.x] = value;
    }
}

An advantage with this approach is that you can directly access the backing array. So if you just want to process all items, without caring about their location, you can just use a plain loop.

JonasH
  • 28,608
  • 2
  • 10
  • 23