2011-09-29 14 views
10

Đôi khi tôi mong đợi một loạt các mục nhất định và cần thực hiện một số xác nhận để đảm bảo rằng tôi nằm trong phạm vi đó. Cách rõ ràng nhất để làm điều này là chỉ so sánh số lượng mục trong bộ sưu tập với phạm vi.Kiểm tra xem IEnumerable có ít hơn một số mục nhất định mà không gây ra bất kỳ đánh giá không cần thiết nào không?

public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max) 
{ 
    return enumerable.Count() <= max; 
} 

Mặc dù, sự hiểu biết của tôi là phương thức count count() sẽ đánh giá toàn bộ đếm trước khi trả về kết quả. Lý tưởng nhất tôi sẽ chỉ gây ra đánh giá về số lượng tối thiểu của các mục để có được kết quả của tôi.

Điều gì sẽ là cách tốt nhất để đảm bảo rằng số đếm có ít hơn một số mục nhất định mà không gây ra bất kỳ đánh giá không cần thiết nào?

Trả lời

15

Không sử dụng Count(), như bạn đã biết, toàn bộ bộ sưu tập sẽ phải được duyệt qua chung.

Bạn có thể làm điều này thay vì:

public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max) 
{ 
    return !enumerable.Skip(max).Any(); 
} 

Lưu ý bạn vẫn sẽ phải liệt kê trong max mục đầu tiên trong bộ sưu tập, đó là không thể tránh khỏi, trừ khi bạn cố gắng thực hiện một số giả định về bộ sưu tập bên dưới.


Để thực sự tối ưu hóa này hơn nữa, bạn có thể kiểm tra xem loại cơ bản là một ICollection<> hoặc ICollection để truy cập Count tài sản. Bằng cách đó bạn không phải liệt kê các vật phẩm. Nếu không dự phòng liệt kê các mục.

public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max) 
{ 
    var asCollection = enumerable as System.Collections.ICollection; 
    if (asCollection != null) return asCollection.Count <= max; 
    var asGenericCollection = enumerable as ICollection<T>; 
    if (asGenericCollection != null) return asGenericCollection.Count <= max; 
    return !enumerable.Skip(max).Any(); 
} 

Tất nhiên điều này là không chính xác miễn phí như bạn đang làm kiểm tra bổ sung, nhưng nó nhịp đập cần phải liệt kê trong bộ sưu tập nếu có thể, đặc biệt là nếu max là lớn.

7

Có một số cách khác nhau để thực hiện việc này. Có lẽ đơn giản nhất là:

public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max) 
{ 
    return enumerable.Take(max+1).Count() <= max; 
} 
1

Bạn có thể kết hợp với Count()Take().

return enumerable.Take(max + 1).Count() <= max; 
Các vấn đề liên quan