С# 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 вызовет проблемы.