2012-11-13 39 views
1

我想這非常簡單,只需要使用迭代器和.MoveNext()方法。有條件地在每次迭代中使用不同數量的項目

但是,假設您正在迭代一個集合,您在集合上做了一些工作,但是基於每個「循環」中的某些條件,您可能必須抓取2個或更多項目,並且基本上跳過它們,然後通過它們循環。

例子:

foreach (Fish fish in ParcelOfFish) 
{ 
    GiverPersonFish(fish); 
} 

在這裏,我只是通過魚的集合迭代並將它們傳遞給方法。有些魚很小,所以我必須給這個人另一個,所以它不會餓死。

foreach (Fish fish in ParcelOfFish) 
{ 
    GiverPersonFish(fish); 

    if (fish.IsSmall) 
    { 
     GiverPersonFish(ParcelOfFish.MoveNext()); // here I want to give him the next fish 
    } 
} 

這將如何工作,使第二魚,我給在下一循環不會重複?

此外,爲了使這更棘手,一個人可能會得到一條大魚和一條小魚是不公平的,所以每當有一條小魚時,我都不想從迭代中抓另一條小魚,然後繼續前進。

因此,如果後第一個「循環」的順序是

Small 
Big 
Big 
Small 
Big 
Small 

,他將得到兩個小(索引0和3),它會通過其他像這樣的循環:

Big 
Big 
Big 
Small 

的編譯器似乎並不喜歡迭代在迭代時如此修改。

+0

由於是可解的,看來你把所有的魚給同一個人,那麼什麼是處理了先進的多每次迭代都比一條魚要多? –

+0

foreach不適合這裏。也許使用隊列更好。 –

+0

@ Y.Ecarri那麼我們真的不知道GivePersonFish()方法會發生什麼,它並不重要。 –

回答

1

實際上,它是通過Enumerator

using (var enumerator = ParcelOfFish.GetEnumerator()) 
{ 
    // Bla bla whatever you need, but remember the first call to .MoveNext(); 
    if (!enumerator.MoveNext()) 
      break; 

    // Your actions here. MoveNext() is bool and proceeds to the new item. 
    // Try using while (!condition) { } here. 
} 
2

迭代,按設計,並不意味着要這樣工作。如果你需要更靈活的行爲,你應該使用for循環。

1

而不是使用foreach循環(foreach(Foo foo in bar)),使用普通的舊for循環(for(int i = 0; i < bar.Length; i++))。

這將讓你做這樣的事情:

for (int i = 0; i < ParcelOfFish.Length; i++) 
{ 
    Fish fish = ParcelOfFish[i]; 
    GiverPersonFish(fish); 

    if (fish.IsSmall && i+1 < ParcelOfFish.Length) 
    { 
     GiverPersonFish(ParcelOfFish[++i]); // give him the next fish 
    } 
} 

使用for循環也將讓你通過你的列表中尋找另一個小魚,給它的人,並從列表中刪除(這次假設ParcelOfFish是一個列表,而不是一個數組):

for (int i = 0; i < ParcelOfFish.Count; i++) 
{ 
    Fish fish = ParcelOfFish[i]; 
    GiverPersonFish(fish); 

    if (fish.IsSmall) 
    { 
     for (int j = i+1; j < ParcelOfFish.Count; j++) 
     { 
      Fish fish2 = ParcelOfFish[j]; 
      if (fish2.IsSmall) 
      { 
       GiverPersonFish(fish2); // give him the next small fish 
       ParcelOfFish.RemoveAt(j); 
       break;      
     } 
    } 
} 
+2

這也不會給**下一個小魚** –

+0

我回答了問題的第一部分,並指出瞭如何解決問題的其餘部分,但我也爲第二部分添加了一個例子。 – cmrn

1

我想用一個隊列來代替。

var queue = new Queue<Fish>(ParcelOfFish); 
while (queue.Count > 0) 
{ 
    var fish = queue.Dequeue(); 

    if (fish.IsSmall && queue.Count > 0) 
    { 
     var fish2 = queue.Dequeue(); 

     if (fish2.IsSmall) 
      GiverPersonFish(fish); // give them the first small fish 
     else 
      queue.Enqueue(fish); // throw it back to the end of the queue 

     GiverPersonFish(fish2); 
    } 
    else 
     GiverPersonFish(fish); 
} 

也適用於堆棧。

+0

'queue.Count> 0'比'queue.Any()'更好,因爲這是枚舉集合的擴展。 – AgentFire

+0

@AgentFire這是真的!編輯。 –

0

嘗試

Enumerator<Fish> enumerator = ParcelOfFish.GetEnumerator(); 
Queue<Fish> bigFishCache = new Queue<Fish>(){ }; 
Boolean smallFishSwitch = false; 

while(enumerator.MoveNext()) 
{ 
    if(smallFishSwitch) 
    { 
     if(enumerator.Current == BigFish) 
     { 
      bigFishCache.Enqueue(enumerator.Current); 
     } 
     else 
     { 
      smallFishSwitch = false; 
      GivePersonFish(enumerator.Current); 
      ForEach(Fish fish in bigFishCache) 
      { 
        GivePersonFish(fish); 
      } 
      bigFishCache.Clear(); 
     } 
    } 
    else 
    { 
     smallFishSwitch = enumerator.Current == SmallFish; 
     GivePersonFish(enumerator.Current); 
    }  
} 
相關問題