Reputation: 132
Please look at following code in Linqpad and tell me why it returns 0 items instead of 1 items.
void Main()
{
string[] strArray = {"apple", "banana", "cherry", "e"};
List<string> lst = strArray.ToList();
//count all occurences of variable alphabet "e" in LINQ
//tip is to get the occurences of letter "e" in each word
// and then total them together
var lst2 = lst.TakeWhile(c=>c.Equals("banana")).Select(c=>c);
Console.WriteLine(lst2);
}
The above code does not return 1 item in linqpad as I would expect. Instead it returns 0 items. The list with 1 item "banana" should return. Why does it not?
Upvotes: 2
Views: 3683
Reputation: 372
The TakeWhile
will take element as long as the condition is true. In your case it's false at the beginning because it's evaluate if ("apple" == "banana")
and it's not so the TakeWhile
stop.
If you put the element "banana" at beginning, it will work.
string[] strArray = {"banana", "apple", "cherry", "e"};
Plus, you can only write.
var lst2 = lst.TakeWhile(c=>c.Equals("banana"))
The select is useless.
Upvotes: 1
Reputation: 53600
This will return 1 item ("banana"):
var result = lst.Where(c => c.Equals("banana")).ToList();
Console.WriteLine(result);
As the others pointed out, no need for a TakeWhile
where a simple Where
will suffice.
EDIT: From your code comments, it looks like you might be trying to count the occurrences of 'e' in the source list. This will do that for you:
var list = new List<string> { "apple", "banana", "cherry", "e" };
var count = list
.SelectMany(x => x.ToArray()) // flatten into list of chars
.Where(x => x.Equals('e'))
.Count();
Console.Write(count);
Upvotes: 1
Reputation: 103495
arcyqwerty tell you why. He left out what you want instead:
var lst2 = lst.Where(c=>c.Equals("banana")).Select(c=>c);
Upvotes: 0
Reputation: 8163
Because it is taking while the iterated item is a banana, since the first item it arrives to is not a banana, it stops the iteration.
Upvotes: 2
Reputation: 25370
@arcyqwerty explained why you're getting your results. For your expected results, use Where
in this instance:
var lst2 = lst.Where(c=>c.Equals("banana"));
Also, no need for Select(c => c)
, it's redundant.
Upvotes: 4
Reputation: 10675
Documentation for TakeWhile
:
Returns elements from a sequence as long as a specified condition is true.
Since a List
is ordered, the first item, "apple" does not equal "banana". The condition is false and TakeWhile
exits before it reaches the "banana" item.
You may be looking to use the Where
method instead
Filters a sequence of values based on a predicate.
Upvotes: 13