-6

Having the following for loop:

        for (var i = list.Count - 1; i >= list.OrderBy(x => x).First(); i--)
            if (list.Contains(i))
                list.RemoveAt(i);
  1. Does list.Count() get checked every iteration?
  2. Does list.OrderBy(x => x.Key).First() get executed every iteration
  3. Should this be thread safe? because of adding/removing?

What I'm driving at is that, during the for loop execution items may be added to the list (elsewhere-in a different method)

BobSwanson
  • 423
  • 2
  • 5
  • 18
  • 7
    Step through the code with a debugger and see *exactly* what gets called and when. (That said, you don't call `list.Count()` anywhere in the snippet you've shown, so it doesn't get called *at all*.) – Servy Apr 27 '17 at 14:03
  • 1
    the first part of a `for` loop is executed once the other two parts are executed once per iteration. – juharr Apr 27 '17 at 14:05
  • yes the orderby will get executed. – Daniel A. White Apr 27 '17 at 14:06
  • @Servy, the first part of the `for` loop is `var i = list.Count() - 1`. – juharr Apr 27 '17 at 14:06
  • @juharr Look at the revision history. They edited the code after I commented. – Servy Apr 27 '17 at 14:06
  • @HimBromBeere True, fixed. – juharr Apr 27 '17 at 14:07
  • please take the time to create some actually working example. List does not have a method ContainsKey(). Perhaps you are thinking of Dictionary, but Dictionary does not have a method RemoveAt() – HugoRune Apr 27 '17 at 14:08
  • What are you actually trying to achieve here? Remove every time except the one with the highest value of `Key`? And as for is it thread safe, probably not. If items are removed, you can't guarantee that `i` is within bounds anymore. – Matt Burland Apr 27 '17 at 14:11
  • I see you attempted to fix the errors in your code I pointed out, but it seems to still contain further errors. Please try to compile this yourself. – HugoRune Apr 27 '17 at 14:12

1 Answers1

0

1: No because it is only the starting value. This part will be visited only once at the start of the loop

2: Yes because the linq expression has to be evaluated to get the result value. If you want to avoid it execute the linq expression once before the loop and save it into a separate value:

int end = list.OrderBy(x => x.Key).First(); 
for (var i = list.Count() - 1; i >= end; i--) 
    if (list.ContainsKey(i))
        list.RemoveAt(i)

EDIT:

If your list might change dynamically, then of course the way you use it now would be a preferable solution, since you could accommodate to the changes.

as for question 3: this Answer says that the Add method is not thread safe

Community
  • 1
  • 1
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
  • That's the thing, list may be removed from/added to elsewhere DURING the for iteration. That's the reason I do not wish to save it in the variable – BobSwanson Apr 27 '17 at 14:09
  • @BobSwanson then you could accommodate to the changes online, the way you are using it now. Is `list` a `Dictionary` ? – Mong Zhu Apr 27 '17 at 14:12
  • @BobSwanson: You aren't going to make this thread safe without some kind of locking. – Matt Burland Apr 27 '17 at 14:14