You are here
Home > Programming > TakeWhile Extension Method in C#

TakeWhile Extension Method in C#

Fallback Image

TakeWhile Extension Method – I am amazed at how the C# language can teach me something new. I have come to the conclusion that it is basically impossible for a developer to know all there is about a given programming language (unless you are Jon Skeet of course). We learn as we need. I need to do xyz in code, so I research and find a way. Therefore I learn something new. The next time I will know how to do this. That is how we learn more about a particular language. Today I had a requirement to loop through a List<int> and stop the loop if the value in the list equaled zero. The TakeWhile Extension Method was the perfect fit.

TakeWhile Extension Method

So what would you do to ensure that while looping through a list of integers, that an integer equal to zero will stop the processing? I might have done something like this:

TakeWhile Extension Method

My requirement was slightly different though. I has been working on some legacy code and for some reason, the value zero was being added to the end of a permissions list. This permissions list was a list of user ID’s. Needless to say, zero was not a user ID that existed. I could implement the above foreach loop, but there is a better way and one that would probably speed up the loop (although I haven’t tested this). Go ahead and add the using statement to System.Linq if you don’t have it already.

TakeWhile Extension Method

Now you can add the TakeWhile Extension Method to your list right there in the foreach statement. This is much nicer and cleaner code than the alternative if condition above.

TakeWhile Extension Method

The lambda expression in the TakeWhile Extension method basically processes only the values not equal to zero. If it finds a zero, it will exit the foreach loop. Being a lambda expression, you can get very creative with your expression. Also remember, if you are using Visual Studio 2015, you can now debug lambda expressions! I thought this was just such a nice solution, one that I had to share. I hope someone can find it useful.

For more on this, have a look at the Enumerable.TakeWhile Method on MSDN as well as James Michael Hare’s excellent C#/.NET Little Wonders: Skip() and Take() article.

Edit: 15 Aug 2015

I have edited the article to clear up confusion regarding my requirement which was not to process all items not equal to zero, but to stop the loop if the value of zero was found. The list always contained a zero as the last integer in the permissions list and I needed to avoid processing a zero value. Thank you for all the comments.

Dirk Strauss
Dirk is a Software Developer and Microsoft MVP from South Africa. He loves all things Technology and is slightly addicted to Twitter and Jimi Hendrix. Apart from writing code, he also enjoys writing human readable articles. "I love sharing knowledge and connecting with people from around the world. It's the diversity that makes life so beautiful." Dirk feels very strongly that pizza is simply not complete without Tabasco, that you can never have too much garlic, and that cooking the perfect steak is an art he has yet to master.

Similar Articles

  • Wojciech Gebczyk

    Filtering list can be done with “Where(i=>i>0)”.
    TakeWhile for array [1,2,-1,2] will return [1,2] only.
    The results will be same when array is descending sorted.

  • M

    Hi Dirk,

    There .Where() extension achieves the effect you’re after. TakeWhile() will end the enumerable the first time your value is less than 1, rather than filter it.

    M.

  • Your explanation of what TakeWhile does isn’t quite correct – it will return items in the list **until** the first one that is positive, at that point it will stop (so negative items after a positive one will not be returned).

    The filtering function in Linq is Where – that will return all items that match the passed in predicate.

  • Saša Kajfeš

    I would just like to point out that your two examples are not equivalent. The first one will process all the elements of the list that are different from 0. However the second example will process all elements in the list until it finds a first negative one. Then it will stop processing. https://msdn.microsoft.com/en-us/library/vstudio/bb534804(v=vs.100).aspx for more info.

  • Isn’t this function going to stop taking new items once the condition is no longer met?

    So if your list is not sorted – for example 1, 2, 0, 3 – it would not take _all_ items greater than 0, but only the first two items, being 1 and 2. The .where() method would take 1, 2 and 3.

  • Mike Cattle

    One thing to note, TakeWhile() will only iterate through the collection until the lambda returns False, at which point it stops processing the rest of the collection. Any elements after that point are not processed, even if the integers are greater than zero. So, if the first integer in the iList is zero, then none of the elements get processed.

    To work like your original code, you’d have to use the .Where() extension, instead, which filters the list according to your lambda expression, but continues through the list after the lambda returns False (essentially removing all the elements with a value of zero).

  • Those two code snippets aren’t equivalent.

    TakeWhile won’t just skip non-match values, but it will STOP there.

    For example, if you iList was {1,2,3,0,4,5,6}, the if() would give you {1,2,3,4,5,6}, while the TakeWhile would just give you {1,2,3}

    To duplicate the effect of the if(), what you really want to use is Where()

    foreach(int item in iList.Where(j => j > 0))

  • Ivo Štimac

    I think those two code snippets behave differently. I think first snippet would be equivalent to using a Where extension method, whereas the the second runs until it encounters a false condition, and then breaks out of the loop?

  • Marc Gruben

    Hi Dirk, the problem is that the enumeration stops when the first item is smaller than 0. In your case you should use Where.

  • David Martin

    Do you know how this might be different from using the Where clause?

    foreach (int item in iList.Where(j => j > 0) { … }

  • Alex Bakulin

    Please check your code snippets. The LINQ-less one processes only nonzero elements, not elements greater than zero. And the one that uses TakeWhile() should really use Where() instead, otherwise it will work only if the list is sorted in descending order.

Top