سؤال

Say you want to loop through 3 elements like this:

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

Of course, this is the same as saying: doSomething(); doSomething(); doSomething();.

Now, let's say you want to do something BETWEEN each iteration, as if you are coding this: doSomething(); doBetween(); doSomething(); doBetween(); doSomething();

Notice how doSomething() is called 3 times, but doBetween() is called 2 times.

Right now, the only way I know how to do this in a loop is:

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

To me, it seems inefficient to run that conditional within a loop. It also makes you have to look at it twice in order to understand the programming intention. Plus, if you change the "3" to something else in the "for" header, you could easily forget to change the conditional, especially as the logic grows. Not only that, but this trick won't work in a foreach loop because there is no easy way to detect whether we are running the last iteration.

What tips do you have for doing something like this in a way that gives you better performance, better readability, better maintainability, or in a foreach loop?

هل كانت مفيدة؟

المحلول

You could always write a reusable function, not sure this would be a good idea unless you needed to reuse this a lot

    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;
    }

This would be called like so:

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

Or

Enumerable.Range(0, 3).ForEach(i => DoSomething(), i => DoBetween());

نصائح أخرى

What about something simple?

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

Assuming you want to "doSomething" and "doBetween" on whatever you're iterating over in a foreach:

bool firstComplete = false;

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

   doSomething(i);
}
{
    int i=0;

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

        }
    }
}

Granted, it looks the most obscure BUT both statements are written only once and there is only one comparison per iteration. If the condition isn't met initially then nothing happens and it does also not use any helper variables. You only have to write the condition twice.

There isn't anything built in for that. You could do your own custom enumerator that would call something inbetween, but then it would be just as complicated just to call it.

No matter how you solve it, you can't get around doing a check for each iteration. A simple check like that is hardly going to hurt the performance.

I usually use a boolean flag for this:

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

You could also consider moving one iteration out of the loop:

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

However, if the loop could ever be empty (zero items), you would have to check for that first.

This would allow you to define the start and endpoints before entering the loop...

int start = 0;
int limit = 3;
for (int i == start; i < limit; i++) {
    doSomething();
    if (i > start && i < limit - 1) {
        doBetween();
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top