290

Say I have a class Customer which has a property FirstName. Then I have a List<Customer>.

Can LINQ be used to find if the list has a customer with Firstname = 'John' in a single statement.. how?

Selim Yildiz
  • 5,254
  • 6
  • 18
  • 28
Tony_Henrich
  • 42,411
  • 75
  • 239
  • 374

10 Answers10

563

LINQ defines an extension method that is perfect for solving this exact problem:

using System.Linq;
...
    bool has = list.Any(cus => cus.FirstName == "John");

make sure you reference System.Core.dll, that's where LINQ lives.

Andriy Volkov
  • 18,653
  • 9
  • 68
  • 83
  • 29
    Any is good, I wonder how many developers use Count when they should use Any? – RichardOD Jul 01 '09 at 20:19
  • 19
    You can also do a case insensitive search: cus => cus.FirstName.Equals("John", StringComparison.CurrentCultureIgnoreCase) – jmservera Jul 01 '09 at 20:40
  • 2
    I know this is an old question but why aren't we making use of the Exists method? Seeing as it is made to see if things exist. – Blackunknown Jul 09 '14 at 09:29
  • 8
    Because not all collections have Exists, and it does not take a lambda expression, but rather the object we are looking for itself. – Andriy Volkov Jul 09 '14 at 12:10
  • 1
    @zvolkov, Any ideas why my resharper is suggesting I use bool has = list.All(cus => cus.FirstName != "John"); Is this more optimal ? – Gullu Dec 05 '18 at 15:55
123

zvolkov's answer is the perfect one to find out if there is such a customer. If you need to use the customer afterwards, you can do:

Customer customer = list.FirstOrDefault(cus => cus.FirstName == "John");
if (customer != null)
{
    // Use customer
}

I know this isn't what you were asking, but I thought I'd pre-empt a follow-on question :) (Of course, this only finds the first such customer... to find all of them, just use a normal where clause.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 8
    I'd point out that you might appreciate having done this later when it comes to debugging, if you find yourself suddenly curious which customer it was that fit the criteria. – mqp Jul 01 '09 at 21:55
  • 1
    Just bumping this answer up one cos I love the way SO community goes the extra step to add even more to the question/answer. – barneymc May 01 '14 at 16:42
  • 1
    thanks it helped me, but sometimes i just want to get `bool` result , so in that case `.Any` or `.FindIndex` is used [here](http://stackoverflow.com/a/4937099/2218697) **which is fast** ? – Shaiju T Mar 06 '16 at 11:39
  • 1
    @stom: They're both O(N), basically... they're just linear searches. – Jon Skeet Mar 06 '16 at 12:09
29

One option for the follow on question (how to find a customer who might have any number of first names):

List<string> names = new List<string>{ "John", "Max", "Pete" };
bool has = customers.Any(cus => names.Contains(cus.FirstName));

or to retrieve the customer from csv of similar list

string input = "John,Max,Pete";
List<string> names = input.Split(',').ToList();
customer = customers.FirstOrDefault(cus => names.Contains(cus.FirstName));
Unu
  • 671
  • 8
  • 17
Mike Sackton
  • 1,094
  • 7
  • 19
10

Using Linq you have many possibilities, here one without using lambdas:

//assuming list is a List<Customer> or something queryable...
var hasJohn = (from customer in list
         where customer.FirstName == "John"
         select customer).Any();
jmservera
  • 6,454
  • 2
  • 32
  • 45
7
customerList.Any(x=>x.Firstname == "John")
Carlos Landeras
  • 11,025
  • 11
  • 56
  • 82
Chris Brandsma
  • 11,666
  • 5
  • 47
  • 58
  • This does not answer the question "if" such an entry exists; it merely enumerates the values if they do exist. An extra step is needed to determine if this enumeration is nonempty. – jason Jul 01 '09 at 20:04
  • Then change the Where to Any. Probably more philosophical for me. I rarely need to know if without caring which ones they are. @jmservera: you were right. I gave up LINQ a while back and now use Lambda exclusively. – Chris Brandsma Jul 01 '09 at 21:55
  • I don't mean to be pedantic when I say that using the lambda calls is still technically using LINQ. (In particular, you're using LINQ-to-Objects.) You're just using the method calls rather than language keywords. – Judah Gabriel Himango Jul 13 '09 at 18:16
  • How does this answer differ from the zvolkov's? – dotnetN00b May 15 '12 at 20:45
4

The technique i used before discovering .Any():

var hasJohn = (from customer in list
      where customer.FirstName == "John"
      select customer).FirstOrDefault() != null;
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
3
List<Customer> list = ...;
Customer john = list.SingleOrDefault(customer => customer.Firstname == "John");

john will be null if no customer exists with a first name of "John".

M4N
  • 94,805
  • 45
  • 217
  • 260
  • 2
    That will throw an exception if *more than one* customer is called John. – Jon Skeet Jul 01 '09 at 20:02
  • 1
    Thanks for the comment. I'll leave the answer as a partially correct example. – M4N Jul 01 '09 at 20:09
  • It's still valid in a scenario when you are sure there is 1 and you want an exception to be raised if more than one, so I think it is good that you didn't delete it. – RichardOD Jul 01 '09 at 20:21
3

Try this, I hope it helps you.

 if (lstCustumers.Any(cus => cus.Firstname == "John"))
 {
     //TODO CODE
 }
  • 7
    That's the same as the accepted answer from over 8 years ago. Please make sure your answer is unique among all the answers. – Tony_Henrich Jun 14 '17 at 22:46
1

Another possibility

if (list.Count(customer => customer.Firstname == "John") > 0) {
 //bla
}
Krassi
  • 2,336
  • 3
  • 22
  • 30
0

Include using System.Linq

Use Trim() if there should be a match even with leading and trailing whitespaces.

Use StringComparison.CurrentCultureIgnoreCase if the match needs to
be case insensitive.

using System.Linq;
...
    bool has = list.Any(cus => cus.FirstName.Trim().Equals("John", StringComparison.CurrentCultureIgnoreCase));
KRM
  • 1,185
  • 2
  • 13
  • 28