clinton
clinton

Reputation: 132

C# Linq List<string> takewhile

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

Answers (6)

F&#233;lix LD
F&#233;lix LD

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

Nate Barbettini
Nate Barbettini

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

James Curran
James Curran

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

maraaaaaaaa
maraaaaaaaa

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

Jonesopolis
Jonesopolis

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

arcyqwerty
arcyqwerty

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

Related Questions