Поиск, если значение существует в списке объектов, используя Linq


228

Скажем, у меня есть класс, у Customerкоторого есть свойство FirstName. Тогда у меня есть List<Customer>.

Можно ли использовать LINQ, чтобы узнать, есть ли в списке клиент с Firstname = 'John'одним оператором ... как?

Ответы:


459

LINQ определяет метод расширения, который идеально подходит для решения именно этой проблемы:

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

убедитесь, что вы ссылаетесь на System.Core.dll, там живет LINQ.


24
Любое хорошо, интересно, сколько разработчиков используют Count, когда они должны использовать Any?
— RichardOD

12
Вы также можете выполнить поиск без учета регистра: cus => cus.FirstName.Equals ("John", StringComparison.CurrentCultureIgnoreCase)
— jmservera

1
Я знаю, что это старый вопрос, но почему мы не используем метод Exists? Видя, как это сделано, чтобы увидеть, существуют ли вещи.
— Blackunknown

6
Потому что не во всех коллекциях есть Exists, и оно не принимает лямбда-выражения, а скорее объект, который мы ищем сам.
— Зволков

1
@zvolkov, любые идеи, почему мой резарпер предлагает использовать bool has = list.All (cus => cus.FirstName! = "John"); Это более оптимально?
— Гулу

105

Ответ Зволкова является идеальным, чтобы выяснить, есть ли такой клиент. Если вам нужно использовать клиента впоследствии, вы можете сделать:

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

Я знаю, что это не то, что вы спрашивали, но я подумал, что предпочитаю последующий вопрос :) (Конечно, это находит только первого такого клиента ..., чтобы найти их всех, просто используйте нормальное whereпредложение.)


7
Я хотел бы отметить, что вы могли бы оценить, что сделали это позже, когда дело доходит до отладки, если вам вдруг стало любопытно, какой именно клиент соответствует этим критериям.
— MQP

1
Просто поднимите этот ответ, потому что мне нравится, как сообщество SO делает дополнительный шаг, чтобы добавить еще больше к вопросу / ответу.
— barneymc

1
спасибо, это помогло мне, но иногда я просто хочу получить boolрезультат, так что в этом случае .Anyили .FindIndexиспользуется здесь, что быстро ?
— Shaijut

1
@stom: Они оба O (N), в основном ... это просто линейные поиски.
— Джон Скит

натыкаясь на это. Мне нравится, как вы используете синтаксис list.FirstOrDefault вместо того, чтобы делать list.Where (). FirstOrDefault.
— GunWanderer

25

Один из вариантов ответа на вопрос (как найти клиента, который может иметь любое количество имен):

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

или получить клиента из csv аналогичного списка

string input = "John,Max,Pete";
List<string> names = input.Split(',').ToList();
customer = customers.FirstOrDefault(cus => names.Contains(cus.FirstName));

10

Используя Linq, у вас есть много возможностей, в том числе без лямбд:

//assuming list is a List<Customer> or something queryable...
var hasJohn = (from customer in list
         where customer.FirstName == "John"
         select customer).Any();

5
customerList.Any(x=>x.Firstname == "John")

Это не отвечает на вопрос «если» такая запись существует; он просто перечисляет значения, если они существуют. Дополнительный шаг необходим, чтобы определить, является ли это перечисление непустым.
— Джейсон

Затем измените «Куда-нибудь». Наверное, более философски для меня. Мне редко нужно знать, не заботясь о том, кто они. @jmservera: ты был прав. Я отказался от LINQ некоторое время назад и теперь использую исключительно Lambda.
— Крис Брэндсма

Я не хочу быть педантичным, когда говорю, что использование лямбда-вызовов по-прежнему технически использует LINQ. (В частности, вы используете LINQ-to-Objects.) Вы просто используете вызовы методов, а не ключевые слова языка.
— Иуда Габриэль Химанго

Чем этот ответ отличается от ответа Золькова?
— dotnetN00b

4

Техника, которую я использовал перед открытием .Any():

var hasJohn = (from customer in list
      where customer.FirstName == "John"
      select customer).FirstOrDefault() != null;

3
List<Customer> list = ...;
Customer john = list.SingleOrDefault(customer => customer.Firstname == "John");

Джон будет нулевым, если не существует ни одного клиента с именем «Джон».


2
Это создаст исключение, если более одного клиента зовут Джон.
— Джон Скит

1
Спасибо за комментарий. Я оставлю ответ как частично правильный пример.
— M4N

Это все еще действует в сценарии, когда вы уверены, что есть 1, и вы хотите, чтобы было сгенерировано исключение, если их больше одного, поэтому я думаю, это хорошо, что вы не удалили его.
— RichardOD

1

Другая возможность

if (list.Count(customer => customer.Firstname == "John") > 0) {
 //bla
}

4
В этом сценарии предпочтительнее использовать Any.
— RichardOD

1

Попробуйте это, я надеюсь, это поможет вам.

 if (lstCustumers.Any(cus => cus.Firstname == "John"))
 {
     //TODO CODE
 }

4
Это так же, как принятый ответ более 8 лет назад. Пожалуйста, убедитесь, что ваш ответ уникален среди всех ответов.
— Tony_Henrich
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.