Пошук, чи існує значення в списку об'єктів за допомогою 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 ("Джон", StringComppare.CurrentCultureIgnoreCase)
— jmservera

1
Я знаю, що це старе питання, але чому ми не використовуємо метод Exists? Бачачи, як це зроблено, щоб побачити, чи існують речі.
— Blackunknown

6
Тому що не у всіх колекціях є Existi, і це не сприймає лямбда-вираз, а швидше предмет, який ми шукаємо сам.
— zvolkov

1
@zvolkov, Будь-які ідеї, чому мій переробник пропонує запропонувати використовувати bool has = list.All (cus => cus.FirstName! = "John"); Це більш оптимально?
— Гуллу

105

Відповідь zvolkov є ідеальною, щоб дізнатися, чи є такий замовник. Якщо згодом вам потрібно скористатися клієнтом, ви можете:

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

Я знаю, що це не те, про що ви питали, але я подумав, що я попередньо скасую наступне запитання :) (Звичайно, це лише той перший клієнт, який знайде ... щоб знайти їх усіх, просто використовуйте нормальне whereзастереження.)


7
Я зазначу, що ви могли б оцінити, що ви зробили це пізніше, коли справа доходить до налагодження, якщо вам раптом стане цікаво, який саме клієнт відповідає таким критеріям.
— mqp

1
Тільки стикаючись з цією відповіддю вгору, тому що мені подобається, як СУ спільноти робить додатковий крок, щоб додати ще більше запитання / відповіді.
— barneymc

1
дякую, що це допомогло мені, але іноді я просто хочу отримати boolрезультат, тому в такому випадку .Anyабо .FindIndexвикористовується тут, який швидко ?
— shaijut

1
@stom: Вони обидва O (N), в основному ... це просто лінійні пошуки.
— Джон Скіт

наткнувшись на це. Мені подобається, як ви використовуєте синтаксис list.FirstOrDefault замість того, щоб робити список.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.) Ви просто використовуєте виклики методів, а не мовні ключові слова.
— Іуда Габріель Хіманго

Чим ця відповідь відрізняється від zvolkov's?
— 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
У цьому сценарії бажано використовувати будь-яке.
— 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.