3

次のように 3 つの要素をループしたいとします。

for(int i=0; i<3; i++)
{
    doSomething();
}

もちろん、これは次のように言っているのと同じです: doSomething(); doSomething(); doSomething();.

さて、これをコーディングしているかのように、各反復の間に何かをしたいとしましょう: doSomething(); doBetween(); doSomething(); doBetween(); doSomething();

doSomething()が 3 回呼び出されているのに、 2 回呼び出されていることに注意してくださいdoBetween()

現在、ループでこれを行う方法を知っている唯一の方法は次のとおりです。

for(int i=0; i<3; i++)
{
    doSomething();
    if(i<2)
        doBetween();
}

私には、その条件をループ内で実行するのは効率が悪いように思えます。また、プログラミングの意図を理解するために、2 回見なければならなくなります。さらに、「for」ヘッダーの「3」を別のものに変更すると、特にロジックが大きくなるにつれて、条件の変更を簡単に忘れてしまう可能性があります。それだけでなく、最後の反復を実行しているかどうかを簡単に検出する方法がないため、このトリックは foreach ループでは機能しません。

パフォーマンス、可読性、保守性、または foreach ループを向上させる方法で、このようなことを行うためのヒントはありますか?

4

7 に答える 7

3
for(int i = 0; i < 3; i++) {
    if(i > 0) {
        doBetween();
    }
    doSomething();
}
于 2012-09-09T22:11:58.433 に答える
3

シンプルなものはどうですか?

for(int i = 0; i < 3; i++) {
    doSomething();
    doBetween();
}
doSomething();
于 2012-09-09T22:15:56.140 に答える
1

再利用可能な関数をいつでも作成できますが、これを何度も再利用する必要がない限り、これが良いアイデアかどうかはわかりません

    public static IEnumerable<TSource> ForEach<TSource>(this System.Collections.Generic.IEnumerable<TSource> source, Action<TSource> action, Action<TSource> between)
    {
        bool first = true;
        foreach (TSource item in source)
        {
            if (first) first = false; else between();
            action(item);
        }
        return source;
    }

これは次のように呼び出されます。

myList.ForEach(i => DoSomething(), i => DoBetween());

または

Enumerable.Range(0, 3).ForEach(i => DoSomething(), i => DoBetween());
于 2012-09-09T22:23:49.717 に答える
1

foreach で繰り返し処理する対象に対して "doSomething" と "doBetween" を実行するとします。

bool firstComplete = false;

foreach(Item i in ItemList)
{
   if (firstComplete)
   {
      doBewteen(i);
   }
   else
   {
      firstComplete = true;
   }

   doSomething(i);
}
于 2012-09-09T22:17:11.537 に答える
1
{
    int i=0;

    if(i<3){
        while(true){
            doSomething();
            i++;
            if(i<3){
                doBetween();
            }
            else{
                break;
            }

        }
    }
}

確かに、それは最もあいまいに見えますが、両方のステートメントは 1 回しか書かれておらず、反復ごとに 1 つの比較しかありません。最初に条件が満たされない場合、何も起こらず、ヘルパー変数も使用しません。条件を 2 回記述するだけです。

于 2019-08-27T18:35:42.940 に答える
0

これにより、ループに入る前に始点と終点を定義できます...

int start = 0;
int limit = 3;
for (int i == start; i < limit; i++) {
    doSomething();
    if (i > start && i < limit - 1) {
        doBetween();
    }
}
于 2012-09-10T00:52:55.133 に答える
0

そのために組み込まれているものは何もありません。間に何かを呼び出す独自のカスタム列挙子を作成することもできますが、それを呼び出すだけでも同じように複雑になります。

どのように解決しても、反復ごとにチェックを行うことはできません。このような単純なチェックでは、パフォーマンスが損なわれることはほとんどありません。

通常、これにはブール値フラグを使用します。

bool first = true;
for (int i = 0; i < 3; i++) {
  if (first) {
    first = false;
  } else {
    doBetween();
  }
  doSomething();
}

1 つの繰り返しをループの外に移動することも検討できます。

doSomething();
for (int i = 1; i < 3; i++) {
  doBetween();
  doSomething();
}

ただし、ループが空 (ゼロ項目) になる可能性がある場合は、最初にそれを確認する必要があります。

于 2012-09-09T22:17:31.490 に答える