Пошук, чи існує значення в списку об'єктів за допомогою 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.