2013-01-20 19 views
8

Tôi hiện đang sử dụngCó đối diện với phương pháp LINQ's All không?

a_list.All(item => !(item.field_is_true == true)) 

mà hoạt động tốt, nhưng tôi muốn biết nếu có một phương pháp LINQ thích hợp để làm điều ngược lại của tất cả.

+1

Nó có được gọi là Không? –

+0

@JonathanWood LINQ không có phương thức 'None()'. – JLRishe

+2

Tôi biết, nhưng nó sẽ là tầm thường để viết một. Chỉ cần trả lại một tập trống. Quan điểm của tôi là, không phải là Không đối lập với Tất cả? –

Trả lời

18

Tất cả() kiểm tra xem một Predicate đã cho trả về có đúng cho tất cả các mục hay không. Về mặt phát triển khung, sẽ không có ý nghĩa gì khi viết một phương thức riêng biệt để kiểm tra xem một Predicate đã cho trả về false cho tất cả các mục, vì nó không dễ dàng "không" là một vị từ. Tuy nhiên, bạn có thể viết phương pháp khuyến nông của riêng bạn:

public static bool None<T>(this IEnumerable<T> source, Func<T, bool> predicate) 
{ 
    return !source.Any(predicate); 
} 
+3

Bạn cũng có thể sử dụng 'Func ' thay vì 'Predicate ' – SWeko

6

Đối diện chính xác của All() về cơ bản là None, nhưng vì LINQ không có phương thức None(), bạn có thể thực hiện cùng một kết quả qua !set.Any().

!a_list.Any(item => !(item.matches == true)) 

này sẽ sản xuất true nếu không ai trong số các mục trong a_list có giá trị matches đó không phải là sự thật.

Đó đôi tiêu cực là một chút bối rối, vì vậy để cung cấp một ví dụ đơn giản:

names.All(item => item.StartsWith("R")) 

là đúng nếu tất cả của các mục trong names bắt đầu với R (như bạn đã biết).

!names.Any(item => item.StartsWith("R")) 

là đúng nếu none của các mục trong names bắt đầu với R.

Dựa trên nhận xét của bạn dưới đây, có vẻ như bạn chỉ có thể được tìm kiếm một cách để đạt được kết quả tương tự như của bạn đoạn mã hiện tại, nhưng theo một cách khác. Điều này sẽ cung cấp các kết quả tương tự như mã hiện tại của bạn, nhưng không có ! trong ngữ:

!a_list.Any(item => item.matches == true) 

Điều này có thể đơn giản hơn nữa để:

!a_list.Any(item => item.matches) 

Tôi muốn tưởng tượng của bạn có thể được đơn giản hóa cũng , như thế này:

a_list.All(item => !item.matches) 

có hiếm khi một lý do chính đáng để so sánh một cách rõ ràng một giá trị boolean với true hoặc false.

+0

Giả sử '.matches' luôn là' true', bạn sẽ không muốn cái '!' thứ hai, không có cái đầu tiên? – TankorSmash

+1

@TankorSmash Tôi không chắc chắn. Bạn đã không giải thích đầy đủ những gì bạn đang cố gắng làm. Tôi đã cho bạn hoàn toàn trái ngược với ví dụ của bạn. Bạn đang cố gắng xác định, cụ thể là gì? – JLRishe

1

Thay vì phủ nhận điều kiện Tất cả(), chỉ cần sử dụng Any() với vị cùng và điều trị boolean trở một cách thích hợp.

Vì vậy, chứ không phải là:

bool conditionDoesntExist = a_list.All(item => !(item.field_is_true == true)); 

bạn có thể có

bool conditionDoesExist = a_list.Any(item => item.field_is_true == true) 

Lưu ý sự thay đổi trong tên của lá cờ. (Tất nhiên tôi nhìn những thứ ngữ nghĩa như vị ngữ ban đầu có thể được viết là item => item.field_is_true == false hoặc đơn giản là item => !item.field_is_true).

Nếu bạn muốn giữ lại tên cờ giống nhau thì vẫn sử dụng Any() nhưng phủ nhận nó:

bool conditionDoesntExist = !a_list.Any(item => item.field_is_true == true); 
+1

không được cho là có sự khác biệt về hiệu suất khi sử dụng ** linq to object **. xem [link] (http://stackoverflow.com/a/9027666/1219182) –

2

bạn đã viết:

a_list.All(item => !(item.field_is_true == true)) 

rằng cũng giống như thực hiện:

a_list.All(item => item.flag== false) // more readable to me... 
     //return true if all of the items have a **flase** value on their flag 

bạn cũng có thể sử dụng .any() để đạt được kết quả tương tự:

!a_list.Any(item => item.flag==true) 

như đối với các vấn đề performence: Bất cứ() vs .all() - cả sẽ có hiệu suất giống hệt (khi LINQ to đối tượng được sử dụng), tìm thêm ở đây: LINQ: Not Any vs All Don't

Các vấn đề liên quan