Tìm kiếm nếu giá trị tồn tại trong danh sách các đối tượng sử dụng Linq


228

Nói rằng tôi có một lớp học Customercó một tài sản FirstName. Rồi tôi có một List<Customer>.

LINQ có thể được sử dụng để tìm xem danh sách có khách hàng Firstname = 'John'trong một tuyên bố không .. bằng cách nào?

Câu trả lời:


459

LINQ định nghĩa một phương thức mở rộng hoàn hảo để giải quyết vấn đề chính xác này:

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

đảm bảo bạn tham khảo System.Core.dll, đó là nơi LINQ sống.


24
Bất kỳ là tốt, tôi tự hỏi có bao nhiêu nhà phát triển sử dụng Count khi họ nên sử dụng Any?
RichardOD

12
Bạn cũng có thể thực hiện tìm kiếm không phân biệt chữ hoa chữ thường: cus => cus.FirstName.Equals ("John", StringComparison.CienCARMIgnoreCase)
jmservera

1
Tôi biết đây là một câu hỏi cũ nhưng tại sao chúng ta không sử dụng phương pháp Exists? Xem như nó được thực hiện để xem nếu mọi thứ tồn tại.
Blackunknown

6
Bởi vì không phải tất cả các bộ sưu tập đều có Tồn tại và nó không có biểu thức lambda, mà là đối tượng chúng ta đang tìm kiếm.
zvolkov

1
@zvolkov, Mọi ý kiến ​​tại sao người chia sẻ lại của tôi đề nghị tôi sử dụng bool has = list.All (cus => cus.FirstName! = "John"); Đây có phải là tối ưu hơn?
Gullu

105

Câu trả lời của zvolkov là câu trả lời hoàn hảo để tìm hiểu xem có khách hàng nào như vậy không. Nếu bạn cần sử dụng khách hàng sau đó, bạn có thể làm:

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

Tôi biết đây không phải là những gì bạn đang hỏi, nhưng tôi nghĩ rằng tôi đã đặt trước một câu hỏi tiếp theo :) (Tất nhiên, điều này chỉ tìm thấy khách hàng đầu tiên như vậy ... để tìm tất cả trong số họ, chỉ cần sử dụng một wheremệnh đề bình thường .)


7
Tôi chỉ ra rằng bạn có thể đánh giá cao việc thực hiện việc này sau khi sửa lỗi, nếu bạn thấy mình đột nhiên tò mò khách hàng nào phù hợp với tiêu chí đó.
mqp

1
Chỉ cần trả lời câu trả lời này lên một cos tôi thích cách cộng đồng SO đi thêm bước nữa để thêm nhiều hơn vào câu hỏi / câu trả lời.
barneymc

1
cảm ơn nó đã giúp tôi, nhưng đôi khi tôi chỉ muốn nhận được boolkết quả, vậy trong trường hợp đó .Anyhay .FindIndexđược sử dụng ở đây thì nhanh không?
shaijut

1
@stom: Cả hai đều là O (N), về cơ bản ... chúng chỉ là các tìm kiếm tuyến tính.
Jon Skeet

va chạm này lên. Tôi thích cách bạn sử dụng cú pháp của list.FirstOrDefault thay vì thực hiện một danh sách.Where (). FirstOrDefault.
GunWanderer

25

Một tùy chọn cho câu hỏi tiếp theo (làm thế nào để tìm một khách hàng có thể có bất kỳ số lượng tên nào):

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

hoặc để lấy khách hàng từ csv của danh sách tương tự

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

10

Sử dụng Linq bạn có nhiều khả năng, ở đây một khả năng mà không cần sử dụng lambdas:

//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")

Điều này không trả lời câu hỏi "nếu" một mục như vậy tồn tại; nó chỉ liệt kê các giá trị nếu chúng tồn tại. Một bước bổ sung là cần thiết để xác định xem bảng liệt kê này là không trống.
jason

Sau đó thay đổi Where thành Any. Có lẽ nhiều triết lý cho tôi. Tôi hiếm khi cần biết nếu không quan tâm họ là ai. @jmservera: bạn đã đúng. Tôi đã từ bỏ LINQ một thời gian trước và bây giờ chỉ sử dụng Lambda.
Chris Brandma

Tôi không có ý định phạm pháp khi tôi nói rằng sử dụng các cuộc gọi lambda về mặt kỹ thuật vẫn sử dụng LINQ. (Cụ thể, bạn đang sử dụng LINQ-to-Object.) Bạn chỉ đang sử dụng các cuộc gọi phương thức chứ không phải từ khóa ngôn ngữ.
Judah Gabriel Himango

Câu trả lời này khác với zvolkov như thế nào?
dotnetN00b

4

Kỹ thuật tôi đã sử dụng trước khi khám phá .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");

john sẽ là null nếu không có khách hàng tồn tại với tên đầu tiên của "John".


2
Điều đó sẽ ném một ngoại lệ nếu có nhiều hơn một khách hàng được gọi là John.
Jon Skeet

1
Cảm ơn các bình luận. Tôi sẽ để lại câu trả lời như một ví dụ đúng một phần.
M4N

Nó vẫn hợp lệ trong một kịch bản khi bạn chắc chắn có 1 và bạn muốn một ngoại lệ được nêu ra nếu có nhiều hơn một, vì vậy tôi nghĩ thật tốt khi bạn không xóa nó.
RichardOD

1

Khả năng khác

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

4
Nó 'thích hợp hơn để sử dụng Bất kỳ trong kịch bản này.
RichardOD

1

Hãy thử điều này, tôi hy vọng nó sẽ giúp bạn.

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

4
Đó giống như câu trả lời được chấp nhận từ hơn 8 năm trước. Hãy chắc chắn rằng câu trả lời của bạn là duy nhất trong số tất cả các câu trả lời.
Tony_Henrich
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.