1

これは本当に単純で、イテレータと.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
    }
}

私が与える2番目の魚が次のループで繰り返されないように、これはどのように機能しますか?

また、これをトリッキーにするために、人が大小の魚を手に入れるのは不公平なので、小魚がいるときはいつでも、反復から別の小魚をつかんで続行したくありません。

したがって、注文が

Small
Big
Big
Small
Big
Small

最初の「ループ」の後、彼は2つの小さな値(インデックス0と3)を取得し、残りの部分を次のように繰り返します。

Big
Big
Big
Small

コンパイラは、反復中にそのように反復が変更されると、気に入らないようです。

4

5 に答える 5

2

反復は、設計上、このように機能することを意図したものではありません。より柔軟な動作が必要な場合は、forループを使用する必要があります。

于 2012-11-13T12:15:11.000 に答える
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;                    
        }
    }
}
于 2012-11-13T12:21:21.510 に答える
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);
}

スタックでも機能します。

于 2012-11-13T12:28:13.003 に答える
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.
}
于 2012-11-13T13:02:18.233 に答える
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);
    }    
}
于 2012-11-13T12:35:17.010 に答える