How do you Iterate a multidimesional array without knowing the number of dimensions and elements of the array being passed to you?

StackOverflow https://stackoverflow.com/questions/1627982

Question

A SDK is returning me an array with multiple dimensions such as:

int[,,] theArray = new int[2,8,12];

I need to visit each element in the array and return the value and the position of the value. I need to do this without knowing the number of dimensions and elements of the array being passed in.

Was it helpful?

Solution

Would something like this work for you? It recurses the ranks so you can use a foreach() and get an array containing the current item's indices.

class Program
{
    static void Main(string[] args)
    {
        int[, ,] theArray = new int[2, 8, 12];
        theArray[0, 0, 1] = 99;
        theArray[0, 1, 0] = 199;
        theArray[1, 0, 0] = 299;

        Walker w = new Walker(theArray);

        foreach (int i in w)
        {
            Console.WriteLine("Item[{0},{1},{2}] = {3}", w.Pos[0], w.Pos[1], w.Pos[2], i);
        }

        Console.ReadKey();
    }

    public class Walker : IEnumerable<int>
    {
        public Array Data { get; private set; }
        public int[] Pos { get; private set; }

        public Walker(Array array)
        {
            this.Data = array;
            this.Pos = new int[array.Rank];
        }

        public IEnumerator<int> GetEnumerator()
        {
            return this.RecurseRank(0);
        }

        private IEnumerator<int> RecurseRank(int rank)
        {
            for (int i = this.Data.GetLowerBound(rank); i <= this.Data.GetUpperBound(rank); ++i)
            {
                this.Pos.SetValue(i, rank);

                if (rank < this.Pos.Length - 1)
                {
                    IEnumerator<int> e = this.RecurseRank(rank + 1);
                    while (e.MoveNext())
                    {
                        yield return e.Current;
                    }
                }
                else
                {
                    yield return (int)this.Data.GetValue(this.Pos);
                }
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.RecurseRank(0);
        }
    }
}

OTHER TIPS

Use for loops:

for (int i=theArray.GetLowerBound(0);i<=theArray.GetUpperBound(0);++i)
{
    for (int j=theArray.GetLowerBound(1);j<=theArray.GetUpperBound(1);++j)
    {
        for (int k=theArray.GetLowerBound(2);k<=theArray.GetUpperBound(2);++k)
        {
           // do work, using index theArray[i,j,k]
        }
    }
}

If you don't know the number of dimensions in advance, you can use Array.Rank to determine that.

I'm not sure I understand your question about "return the position[n,n,n]", but if you're trying to return more than one value from a method, there are a couple of ways to do it.

• Useoutor reference parameters (e.g.,Int) that get set to the returned values before returning from the method.

• Pass in an array, e.g., an array of three ints, the elements of which get set by the method before it returns.

• Return an array of values, e.g., an array of three ints.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top