3

I used List.Select(condition).Count() and found the result to be inappropriate and then I tried List.FindAll(condition).Count() and it worked fine.

How does List.Select(condition).count work ?

user2864740
  • 60,010
  • 15
  • 145
  • 220
Dotnay Tupperson
  • 172
  • 1
  • 10

5 Answers5

6

You see different results because

list.Select(condition)

transforms the list into a sequence of True and False values with the length that is always equal to the number of items in the list. If you use Where instead of Select, you will get matching results.

However, a shorter way to get the result is to pass the condition to Count, like this:

var res = list.Count(condition);
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

List.Select Invokes a transform function on each element in the sequence and returns the transformed collection. In general, using this will return the same Count as the original collection.

List.FindAll takes a predicate (similar to List.Where) and so will only return elements matching it, giving a different count from the original.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
2

Your code or way to filter out list is fundamentally wrong. What you are trying to do is:

 list.Select(mylist => mylist.key == "somevalue").Count();

This will return the same count as length of List. The resulting collection will be true/false for each item.

You need Enumerable.Where like:

 list.Select(mylist => mylist.key == "somevalue").Count();

This will give you the same count as you are finding in FindAll method.

You can even pass the predicate to Count like:

var count = list.Count(mylist => mylist.Key == "somevalue");

FindAll is different from Enumerable.Where in a way that FindAll constructs a new list, whereas Enumerable.Where returns an IEnumerable<T>. You can read this question for more info: C# FindAll VS Where Speed

Community
  • 1
  • 1
Habib
  • 219,104
  • 29
  • 407
  • 436
1

Using Select performs a mapping operation, not a filter operation. This means you'll always get the same number of items out of the query as you had in the original list. In your case, you projected the list from a List<T> to an IEnumerable<bool> (with the original number of true or false responses).

Use .Where to filter a list.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
0

This line:

List.select(mylist => mylist.key == "somevalue")

creates a list of values "true" and "false" but does not filter the output. Therefore the count is the same as without select.

List.select(mylist => mylist.key == "somevalue").count() 

is the same as

List.count();

And

List.where(mylist => mylist.key == "somevalue").count()

works the way you want.

keiv.fly
  • 3,343
  • 4
  • 26
  • 45