Как выполнить итерацию многомерного массива, не зная количества измерений и элементов передаваемого вам массива? - PullRequest
0 голосов
/ 27 октября 2009

SDK возвращает мне массив с несколькими измерениями, такими как:

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

Мне нужно посетить каждый элемент в массиве и вернуть значение и позицию значения. Мне нужно сделать это, не зная количества измерений и элементов передаваемого массива.

Ответы [ 3 ]

3 голосов
/ 27 октября 2009

Использование для петель:

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]
        }
    }
}

Если вы не знаете количество измерений заранее, вы можете использовать Array.Rank , чтобы определить это.

2 голосов
/ 27 октября 2009

Хотелось бы что-нибудь подобное для вас? Он повторяет ранги, чтобы вы могли использовать foreach () и получать массив, содержащий индексы текущего элемента.

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);
        }
    }
}
0 голосов
/ 27 октября 2009

Я не уверен, что понимаю ваш вопрос о "вернуть позицию [n, n, n]" , но если вы пытаетесь вернуть более одного значения из метода, есть пара способов сделать это.

& бык; Используйте out или опорные параметры (например, Int), которые устанавливаются на возвращаемые значения перед возвратом из метода.

& бык; Передайте массив, например, массив из трех целых, элементы которого устанавливаются методом до его возврата.

& бык; Возвращает массив значений, например, массив из трех целых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...