views:

194

answers:

4

I'm a bit surprised to find the results of the following code, where I simply want to remove all 3s from a sequence of ints:

var sequence = new [] { 1, 1, 2, 3 };
var result = sequence.SkipWhile(i => i == 3); // Oh noes! Returns { 1, 1, 2, 3 }

Why isn't 3 skipped?

My next thought was, OK, the Except operator will do the trick:

var sequence = new [] { 1, 1, 2, 3 };
var result = sequence.Except(i => i == 3); // Oh noes! Returns { 1, 2 }

In summary,

  • Except removes the 3, but also removes non-distinct elements. Grr.
  • SkipWhile doesn't skip the last element, even if it matches the condition. Grr.

Can someone explain why SkipWhile doesn't skip the last element? And can anyone suggest what LINQ operator I can use to remove the '3' from the sequence above?

+6  A: 
var result = sequence.Where(i => i != 3);
erikkallen
or TakeWhile(i => i != 3)
Nagg
@Nagg `TakeWhile` would return nothing on a sequence that started with 3, such as `{3,1,2,3}`. The desired result is to filter out all 3s, which is what `Where` is for.
Ahmad Mageed
Uhh, wow, it's Friday alright. Where operator will do the trick, of course. [duh]. Still, doesn't answer why SkipWhile doesn't work as expected.
Judah Himango
+8  A: 

It's not broken. SkipWhile will only skip items in the beginning of the IEnumerable<T>. Once that condition isn't met it will happily take the rest of the elements. Other elements that later match it down the road won't be skipped.

int[] sequence = { 3, 3, 1, 1, 2, 3 };
var result = sequence.SkipWhile(i => i == 3); 
// Result: 1, 1, 2, 3
Ahmad Mageed
Ah, now I understand. Thank you, Ahmad.
Judah Himango
+1  A: 

Ahmad already answered your question, but here's another option:

var result = from i in sequence where i != 3 select i;
Gabe
+1  A: 

The SkipWhile and TakeWhile operators skip or return elements from a sequence while a predicate function passes (returns True). The first element that doesn’t pass the predicate function ends the process of evaluation.

//Bypasses elements in a sequence as long as a specified condition is true and returns the remaining elements.

ligaoren