121

I want to get a difference between TakeWhile & Where LINQ methods .I got the following data from MSDN .But It didn't make sense to me

Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>) 

Filters a sequence of values based on a predicate.

TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)

Returns elements from a sequence as long as a specified condition is true.

All opinions are welcomed.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Mohammed Thabet
  • 21,387
  • 7
  • 27
  • 43
  • 1
    Good question - the Intellisense on TakeWhile still says "Returns elements ... as long as a specified condition is true". This could very well be interpreted to be the same as a Where. The wording should rather be something like "Returns elements ... until the condition evaluates as false". – Peter Jul 17 '18 at 14:55

6 Answers6

201

TakeWhile stops when the condition is false, Where continues and find all elements matching the condition

var intList = new int[] { 1, 2, 3, 4, 5, -1, -2 };
Console.WriteLine("Where");
foreach (var i in intList.Where(x => x <= 3))
    Console.WriteLine(i);
Console.WriteLine("TakeWhile");
foreach (var i in intList.TakeWhile(x => x <= 3))
    Console.WriteLine(i);

Gives

Where
1
2
3
-1
-2
TakeWhile
1
2
3
Neuron
  • 5,141
  • 5
  • 38
  • 59
Albin Sunnanbo
  • 46,430
  • 8
  • 69
  • 108
39

Where can examine the whole sequence looking for matches.

Enumerable.Range(1, 10).Where(x => x % 2 == 1)
// 1, 3, 5, 7, 9

TakeWhile stops looking when it encounters the first non-match.

Enumerable.Range(1, 10).TakeWhile(x => x % 2 == 1)
// 1
Neuron
  • 5,141
  • 5
  • 38
  • 59
Amy B
  • 108,202
  • 21
  • 135
  • 185
10

Say you have an array that contains [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]. Now:

var whereTest = array.Where(i => i <= 5); will return [1, 3, 5, 0, 2, 4].

var whileTest = array.TakeWhile(i => i <= 5); will return [1, 3, 5].

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
10

MSDN says

Enumerable.TakeWhile Method

Returns elements from a sequence as long as a specified condition is true, and then skips the remaining elements.

Enumerable.Where

Filters a sequence of values based on a predicate.

The difference is that Enumerable.TakeWhile skips the remaining elements from the first non-match whether they match the condition or not

naveen
  • 53,448
  • 46
  • 161
  • 251
8

While the existing answers are correct, none of them point out why you'd want to use TakeWhile if the results would be the same: Performance. Suppose you have an ordered list with 2 billion items in it, and you want the ones that (probably 10 or 15 items) less than a given vallue. The Where clause will examine all 2 billion items, while the TakeWhile will stop as soon as it finds a value equal or greater than your supplied value

jmoreno
  • 12,752
  • 4
  • 60
  • 91
7

The order of the sequence passed is absolutely critical with TakeWhile, which will terminate as soon as a predicate returns false, whereas Where will continue to evaluate the sequence beyond the first false value.

A common usage for TakeWhile is during the lazy evaluation of large, expensive, or even infinite enumerables where you may have additional knowledge about the ordering of the sequence.

e.g. Given the sequence:

IEnumerable<BigInteger> InfiniteSequence()
{
    BigInteger sequence = 0;
    while (true)
    {
        yield return sequence++;
    }
}

A .Where will result in an infinite loop trying to evaluate part of the enumerable:

var result = InfiniteSequence()
    .Where(n => n < 100)
    .Count();

Whereas a .TakeWhile, and armed with the knowledge that the enumerables is ascending, will allow the partial sequence to be evaluated:

var result = InfiniteSequence()
    .TakeWhile(n => n < 100)
    .Count();
StuartLC
  • 104,537
  • 17
  • 209
  • 285