我想这很简单,只是使用了迭代器和.MoveNext()方法。
但是假设你正在迭代一个集合,你在集合上做了一些工作但是基于每个“循环”中的某些条件你可能必须抓住2个或更多项并且基本上跳过它们所以你不循环通过他们接下来。
示例:
foreach (Fish fish in ParcelOfFish)
{
GiverPersonFish(fish);
}
这里我只是迭代一堆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 :(得分:2)
根据设计,迭代不应该像这样工作。如果您需要更灵活的行为,则应使用for循环。
答案 1 :(得分: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 :(得分: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);
}
也适用于堆栈。
答案 3 :(得分: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.
}
答案 4 :(得分: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);
}
}