2010-09-19 25 views
7

Tôi có một bộ đối tượng mô hình có thuộc tính boolean công khai IsVisible. Tất cả những gì tôi cần làm là tìm hiểu xem có ít nhất một tập hợp có giá trị được đặt thành TRUE hay không. Nói cách khác, nếu tôi có 10.000 đối tượng nhưng thứ hai là true, tôi không cần phải quay qua 9,998 khác. Tôi đã có câu trả lời.Kiểm tra đơn giản để xem ít nhất một đối tượng trong một tập có giá trị thuộc tính là TRUE

Bây giờ tôi biết tôi có thể viết chức năng lặp của riêng mình và thoát ra ở giá trị 'True' đầu tiên, nhưng tôi hy vọng đó là điều mà LINQ có thể làm. Trên thực tế, nó thậm chí không cần phải được LINQ. Mọi đề xuất đều được chào đón.

BTW, ngôn ngữ bạn chọn là C#.

Cập nhật:

Xem bài viết cuối cùng của tôi ở đây. Tôi đã thêm một số mã kiểm tra và thời gian. Dường như LINQ là khá kém hiệu suất kém khôn ngoan so với chỉ làm thử nghiệm bản thân mình. Chắc chắn nó dễ dàng hơn để viết, nhưng trong thời gian nhiệm vụ quan trọng, tôi không còn chắc chắn. Những gì tôi ngạc nhiên mặc dù hầu hết thời gian tôi đã chạy những điều này, đếm được chiến thắng và bởi một clip công bằng, nhưng vì một lý do nào đó, khi tôi quấn thử nghiệm trong nhiều lần, có vẻ như đã chuyển sang lập chỉ mục với một được lưu trong bộ nhớ cache là nhanh nhất.

Tôi cũng nhận thấy rằng nếu tôi không đặt lại mọi thứ về 'sai', tất cả các thử nghiệm còn lại/lặp lại dường như MUCH nhanh hơn. Bằng cách nào đó, hãy thiết lập lại mọi thứ thành FALSE (đã cố ý overkill để kiểm tra chính xác điều này ...) thay đổi mọi thứ.

Thú vị. Không chắc tôi sẽ đi theo cách nào. Điều này không phải là một hệ thống nhiệm vụ quan trọng vì vậy có lẽ tôi sẽ đi cho dễ đọc, nhưng vẫn còn. Hấp dẫn.

+1

Khi tối ưu hóa, bạn phải giao dịch với tốc độ thực thi so với chi phí của lập trình viên. Hầu hết các nhà quản lý dev muốn mua nhiều máy chủ hơn là trả tiền cho nhiều lập trình viên hơn - và chỉ một phần nhỏ mã chạy trong một con đường quan trọng. Thông thường mã lệnh nhanh nhất để viết và kiểm tra các chiến thắng trên mã thực hiện nhanh nhất, khi tất cả các chi phí (bao gồm chi phí dev) được tính đến. Theo kinh nghiệm của tôi, LINQ viết nhanh hơn nhiều nhưng thực thi chậm hơn. Nó vẫn chiến thắng gần như tất cả thời gian trong kinh nghiệm của tôi. – Slaggg

+0

Slagg, chưa có đủ điểm để bỏ phiếu bình luận, nhưng biết nếu tôi đã làm, bạn sẽ có được một cho điều đó. Có thể rõ ràng, nhưng tính ngắn gọn của nó thực sự nổi bật (không giống như điểm chính nó làm quá! Thông minh bạn của tôi! Rất thông minh!) – MarqueIV

Trả lời

16

Phương pháp bạn đang tìm kiếm là Enumerable.Any.

bool anyObjectsVisible = myObjects.Any(myObject => myObject.IsVisible); 

Điều này có các ngữ nghĩa ngắn mạch chính xác mà bạn đang tìm kiếm; mẫu mã cũng tương tự như:

static bool AreAnyObjectsVisible(IEnumerable<MyObject> myObjects) 
{ 
    foreach (var myObject in myObjects) 
    { 
     if (myObject.IsVisible) return true; 
    } 

    return false; 
} 
+0

Đó chính xác là những gì tôi đang tìm kiếm! (Tôi mới đến LINQ. Không thể tin rằng tôi đã bỏ lỡ điều đó!) Tôi đã thử chấp nhận câu trả lời của bạn nhưng nó nói với tôi rằng tôi phải đợi 12 phút. Tôi ít nhất đã bình chọn nó lên. BTW, GOD tốt thật nhanh! Thậm chí không một phút kể từ khi tôi đăng nó! Bạn đá! – MarqueIV

+0

@MarqueIV: Chúc mừng. Đây là một nguồn tài nguyên tuyệt vời để tìm hiểu LINQ: http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx – Ani

+0

Hey Ari ... theo nhận xét của bạn, tôi đã nuked thử nghiệm của tôi. NHƯNG ... nếu bạn muốn bao gồm một cái gì đó tiết như vậy nhưng nó không phải là một câu trả lời (tức là bạn muốn định dạng mã, vv), là nghi thức thích hợp để chỉnh sửa các câu hỏi ban đầu? (Có, bạn nói đúng rằng trong trường hợp này nó thực sự cần phải là một câu hỏi riêng biệt, nhưng tôi nói chung hơn.) – MarqueIV

3

Nếu bạn cần phải thực sự tìm thấy một đối tượng, chỉ cần sử dụng .First hoặc .FirstOrDefault phương pháp:

var myObject = myCollection.First(x=>x.IsVisible); 

hoặc

var myObject = myCollection.FirstOrDefault(x=>x.IsVisible); 

duy nhất sự khác biệt giữa chúng là phương thức .irst sẽ ném một ngoại lệ nếu không có đối tượng như vậy trong bộ sưu tập khi đối tượng thứ hai trả về giá trị mặc định (null trong ví dụ này).

Nếu bạn chỉ cần kiểm tra xem có bất kỳ đối tượng với bộ tài sản này, sử dụng

var thereIsVisibleObject = myCollection.Any(x=>x.IsVisible); 

Tất cả những phương pháp ngừng lặp lại thông qua việc thu thập khi đối tượng tương ứng được tìm thấy.

Hoặc, bạn nên kiểm tra xem tất cả các đối tượng đang hiển thị/ẩn, bạn có thể làm điều này:

var allTheObjectsAreVisible = myCollection.All(x=>x.IsVisible); 
var allTheObjectsAreInvisible = myCollection.All(x=>!x.IsVisible); 

Nhưng phương pháp .Tất cả sẽ liệt kê tất cả các yếu tố (đó là rõ ràng từ tên của nó).

+0

Bình chọn bạn, nhưng Ani đã nhận được 'Câu trả lời được chấp nhận' vì họ đã trả lời trong vòng 60 giây sau khi tôi đăng nó. (Ngay cả trước khi tôi có cơ hội chỉnh sửa lỗi đánh máy!) Nhưng đây cũng là một thông tin tuyệt vời nên tôi đã bình chọn cho bạn. Cảm ơn!! – MarqueIV

+0

Thực ra, tôi chỉ đọc lại nhận xét của bạn về 'Tất cả'. Sửa tôi nếu tôi sai, nhưng họ sẽ KHÔNG liệt kê tất cả các đối tượng nếu biến vị ngữ của bạn trả về false vì nó chỉ trả về false ngay lập tức, vì vậy nhận xét của bạn sẽ liệt kê mọi thứ mà tôi không chắc nếu nó đúng. Sau khi tất cả nói 'là có thể nhìn thấy' nên ngắn mạch giống như nói 'là tất cả chúng không nhìn thấy được' nếu ngay cả một là có thể nhìn thấy, chính xác? (Sự khác biệt duy nhất là một trả về đúng, sai khác.) Tất nhiên tôi dựa trên logic và không phải tài liệu nên tôi không thể nói chắc chắn. – MarqueIV

+0

Tôi chính xác. .All() lặp lại thông qua bộ sưu tập mà bạn cung cấp và trả về ngay khi biến vị ngữ của bạn là _false_. –

0

Dưới đây là một "Bất cứ()" thực hiện:

public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) 
{ 
    if (source == null) 
    { 
     throw Error.ArgumentNull("source"); 
    } 
    if (predicate == null) 
    { 
     throw Error.ArgumentNull("predicate"); 
    } 
    foreach (TSource local in source) 
    { 
     if (predicate(local)) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

Vì vậy, đây là nó, không có gì "đặc biệt" với Bất cứ(), nó chỉ là một wrapper quanh "foreach". Không có gì đặc biệt để kiểm tra ở đó và không có gì để đổ lỗi về tối ưu hóa vi vi mô.

+0

Tối ưu hóa vi mô vi mô của bạn sang một bên, nó vẫn thú vị mà mã của tôi, trông gần như giống với những gì bạn đã đăng (sans kiểm tra null) chạy lên đến 400% nhanh hơn LINQ trong một số trường hợp. Đó là những gì tôi đã đề cập đến. – MarqueIV

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