3

I have a generic multidimensional array having different dimensions. I need to loop through it in order to save for each element the relative array of indices and the relative value.

In the case of an array of two dimensions, let's say 4 and 5, it would be trivial:

        var d1 = 4;
        var d2 = 5;
        var array = Array.CreateInstance(typeof (int), new[] {d1, d2});

        //...
        // code for populating array
        //...

        for (int i = 0; i < d1; i++)
        {
            for (int j = 0; j < d2; j++)
            {
                var value = array.GetValue(new[] { i, j });
                var indices = new[] {i, j};
            }
        }

But I need to do the same thing with an array of n different dimensions. How can I achieve it? Do I need to implement a recursive function?

7
  • Are you already given an n dimensional array and just need to write the code for iterating over it? Commented Mar 4, 2015 at 23:46
  • Yes, the n dimensional array is given. I need to iterate over it, independently from the number and the size of its dimensions. Commented Mar 4, 2015 at 23:54
  • Given an n dimensional array, you can just do a flat iteration through the array and use modulo operators to figure out what index you're at. Commented Mar 5, 2015 at 0:03
  • Thanks Asad for the answer. Could you please write an example? I am not sure how to use modulo operators for getting both the value and the index. Commented Mar 5, 2015 at 0:10
  • 1
    Can I assume that the lower bound in each dimension is 0 and the upper bound is simply the dimension? Commented Mar 5, 2015 at 0:33

1 Answer 1

5

Visiting all elements in a multidimensional array is not difficult. You can simply do a flat iteration through the entire array with a single index. The tricky part is mapping this single index to the corresponding multidimensional coordinates.

In general, given a matrix with size vector D, the ith single indexed element of this matrix has a coordinate vector C_i, such that:

enter image description here

For 0 <= n < size(D).

Implementing this, the IndexToCoordinates method is:

static int[] IndexToCoordinates(int i, Array arr)
{
    var dims = Enumerable.Range(0, arr.Rank)
        .Select(arr.GetLength)
        .ToArray();

    Func<int, int, int> product = (i1, i2) => i1 * i2;

    return dims.Select((d, n) => (i/dims.Take(n).Aggregate(1, product))%d).ToArray();
}

Now, for example, if you wanted to visit every item in a multidimensional array and output its coordinates, you could do:

static void OutputAllArrayIndices(Array arr)
{
    var i = 0;

    foreach (int item in arr)
    {
        var coords = IndexToCoordinates(i++, arr);
        Console.WriteLine(string.Join(", ", coords));
    }
}

Running OutputAllArrayIndices(new int[3, 2, 4]) then produces:

0, 0, 0
1, 0, 0
2, 0, 0
3, 0, 0
0, 1, 0
1, 1, 0
2, 1, 0
3, 1, 0
0, 0, 1
1, 0, 1
2, 0, 1
3, 0, 1
0, 1, 1
1, 1, 1
2, 1, 1
3, 1, 1
0, 0, 2
1, 0, 2
2, 0, 2
3, 0, 2
0, 1, 2
1, 1, 2
2, 1, 2
3, 1, 2
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Asad. Your code is really fine, even if I think the dimensions should not be reversed, because the array of the coordinates is wrongly reversed. You can also notice this behavior in the output you posted.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.