2015-03-12 2 views
0

Можно ли «искать» через петлю? Основываясь на определенных условиях, я хочу сделать «продолжение на месте», чтобы ускорить переход через цикл. Как это:Как перемещать петлю вперед «на месте»?

for(var thing in things) 
{ 
    // Do stuff 

    if(something) 
    { 
    // Move iteration forward until the iteration object ("thing") meets the right condition 
    while(true) 
    { 
     // Move the iteration forward...somehow 
     [Missing code goes here] 
     if(thing.Property == somevalue) 
     { 
     break; 
     } 
    } 
    } 

    // Do more stuff on the new value of "thing" 
} 

я мог бы использовать continue, но я не хочу, чтобы вернуться к началу цикла. Я хочу пройти вперед через объекты в перечислителе, а затем просто подобрать, где я остановился.

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

+3

Не можете ли вы отфильтровать коллекцию 'things' до итерации? – zerkms

+3

Если вы можете использовать цикл 'for' вместо этого, легко (и опасно) настроить счетчик циклов в любой точке цикла. Если у вас есть 'IEnumerator', просто вызовите' MoveNext() 'до тех пор, пока ваше состояние не пострадает. – user2023861

+0

Что такое тип данных объекта 'things'. Если это набор данных или набор данных, вы можете просто использовать метод' .Select', чтобы отфильтровать то, что вам нужно, тогда вам не придется делать все запросы вперед – MethodMan

ответ

5

Рассматривали ли вы с помощью стандартного for петли вместо foreach петли вы используете?

E.g.

var thing; 
for (int i = 0; i < things.Length; i++) 
{ 
    thing = things[i]; 
    //do stuff 
    if(something) 
    { 
     while([thing doesn't meet condition] && i < things.Length - 1) 
     { 
      thing = things[++i]; 
     } 
    } 
} 

Если вы видели инкрементора до (i++), ++i может показаться странным. Все, что он делает - это приращение iдо вы используете его. Итак, если вы ввели петлю while на things[5], thing будет установлен в things[6]. Цикл while также сломается, если вы не можете загрузить больше объектов.

+2

В отличие от большинства ответов, которые начинаются с «Я не могу комментировать [так что я отвечу]», этот на самом деле является достойным ответом! Я немного почистил его. Добро пожаловать в StackOverflow. –

+0

Да, это хороший ответ. Я закончил работу с связанным списком, где каждая вещь была ссылкой на следующую вещь, поэтому я не повторялся, но скорее перескакивал по неупорядоченному ведру «вещей». Но это, по сути, то же самое - цикл 'for' похож на связанный список, в том смысле, что существует неявная ссылка на следующий инкрементный числовой индекс. – Deane

+0

@TimS. Благодаря! Я всегда забываю, что вы также можете встроить код. – tfitzger

2

фильтра вещи перед петлей

var filtered = things.Where(x => x.Property == somevalue); 
foreach (var thing in filtered) 
{ 
    if (something) 
     // Do more stuff on the new value of "thing" 
} 
+0

Это будет запускать код в совсем другом порядке. Если эти операции можно переупорядочить, не затрагивая их, то это хорошо, но если эти операции не могут быть переупорядочены таким образом, это не является допустимым преобразованием. – Servy

0

Вы можете «восстановить» логику foreach. Обратите внимание на using (потому что foreach распоряжается перечислитель)

using (var enu = things.GetEnumerator()) 
{ 
    bool success; 

    while (success = enu.MoveNext()) 
    { 
     // Current value (always "valid"): enu.Current; 

     if (something) 
     { 
      while (success = enu.MoveNext()) 
      { 
       // Current value (always "valid"): enu.Current; 

       if (enu.Current == someValue) 
       { 
        break; 
       } 
      } 
     } 

     // Current value (check success before using it): enu.Current; 
     if (success) 
     { 
      // Do more stuff on the new value of "thing" 
     } 
    } 
} 

if (res) необходим потому, что внутренний while может «выхлоп» перечислитель.