С# foreach в цикле foreach

У меня нет слишком большого опыта работы с С#, поэтому, если кто-то может указать мне в правильном направлении, я бы очень признателен. У меня есть цикл foreach, который ссылается на переменную объекта. Я хочу сделать еще один цикл foreach внутри основного, который сравнивает (или выполняет действия) текущую переменную с остальными переменными в массиве объекта. У меня есть следующий код:

// Integrate forces for each body.
    foreach (RigidBodyBase body in doc.Bodies)
    {
        // Don't move background-anchored bodies.
        if (body.anchored) continue;

        // This is where we will add Each Body gravitational force 
        //  to the total force exerted on the object.

        // For each other body, get it point and it mass.

            // Find the gravitational force exterted between target body and looped body.
                // Find distance between bodies.
                    // vector addition
                // Force = G*mass1*mass2/distance^2
            // Find vector of that force.
            // Add Force to TotalGravityForce
        // loop until there are no more bodies.
        // Add TotalGravityForce to body.totalForce

    }

Ответ 1

Каждый раз, когда вы выполняете foreach (даже при их вложенности), внутренний Enumerator должен "обновлять" новый итератор для вас, не должно быть никаких проблем с этим. Проблемы возникают при добавлении или удалении элементов из коллекции, пока вы все еще выполняете итерацию...

Помните, что во внутреннем foreach, чтобы убедиться, что вы не на том же элементе, что и внешний для каждого, находится на

  foreach( RigidBodyBase body in doc.Bodies)
     foreach ( RigidBodyBase otherBody in doc.Bodies)
         if (!otherBody.Anchored && otherBody != body)  // or otherBody.Id != body.Id -- whatever is required... 
              // then do the work here

Кстати, лучшее место для размещения этого кода было бы в свойстве GravityForce класса RigidBodyBase. Тогда вы могли бы просто написать:

   foreach (RigidBodyBase body in doc.Bodies)
       body.TotalForce += body.GravityForce; 

хотя в зависимости от того, что вы здесь делаете (перемещение всех объектов?), у них может быть еще больше возможностей для рефакторинга... Я бы также подумал о том, чтобы иметь отдельное свойство для "других" сил и иметь TotalForce Собственность суммирует Силы тяжести и "другие" Силы?

Ответ 2

ИМХО это должно быть возможно, хотя вы действительно должны рассмотреть предложение Кибби. Может быть, вы тоже можете его оптимизировать (например, вот так:)

int l = doc.Bodies.Count;
for ( int i = 0; i < l; i++ )
    for ( int j = i + 1; j < l; j++ )
        // Do stuff 

Ответ 3

Я не вижу проблемы с этим, пока вы не меняете doc.Bodies внутри внутреннего цикла, так как это может привести к взрыву. Но теоретически это сработает. Что касается оптимизации, я не уверен, что это лучше, но это возможно.

Ответ 4

Ну, это алгоритм O (n ^ 2), но я думаю, у вас нет выбора здесь. Как насчет инкапсуляции большей части вашей логики в другой метод. Это делает вещь просто старой, более читаемой.

foreach (RigidBodyBase body in doc.Bodies)        
{                
   Integrateforces(ref body, Bodies);
}

...

public void Integrateforces(RigidBodyBase out body, RigidBodyBase[] Bodies)
{
  //Put your integration logic here
}

Ответ 5

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