2010-04-23 26 views
5

Tôi có một danh sách các phần tử và muốn lấyKhi tổng (hoặc bất kỳ tập hợp các phần tử nào) thỏa mãn một điều kiện nhất định. Đoạn mã sau thực hiện công việc, nhưng tôi khá chắc chắn đây không phải là một vấn đề bất thường mà một mẫu thích hợp nên tồn tại.LINQ TakeWhile tùy thuộc vào tổng (hoặc tổng hợp) của các phần tử

var list = new List<int> { 1, 2, 3, 4, 5, 6, 7 }; 
int tmp = 0; 
var listWithSum = from x in list 
        let sum = tmp+=x 
        select new {x, sum}; 
int MAX = 10; 
var result = from x in listWithSum 
      where x.sum < MAX 
      select x.x; 

Có ai biết cách giải quyết tác vụ theo cách đẹp hơn, có thể kết hợp TakeWhile và Tổng hợp thành một truy vấn?

Thx

+0

Tôi cũng nhận thức được rằng người ta không nên sửa đổi các biến như là một tác dụng phụ của một truy vấn. Nếu listWithSum được sử dụng hai lần, nó sẽ dẫn đến các kết quả khác nhau nếu tmp không được khởi tạo ở giữa. Đó là một trong những lý do, tại sao tôi tin rằng giải pháp này là một trong những xấu! –

+0

var list = new List {1, 2, 3, 4, 5, 6, 7}; int tmp = 0; int MAX = 10; var result2 = list.TakeWhile (x => { tmp + = x; trả về tmp

+0

thx Nick. Trong khi đây là một phiên bản ngắn hơn (và do đó đẹp hơn), nó có cùng một vấn đề với một tác dụng phụ. –

Trả lời

2

Dường như với tôi rằng bạn muốn một cái gì đó giống như phương pháp Scan từ Reactive Extensions (phần System.Interactive) - nó giống như Aggregate, nhưng mang lại một chuỗi thay vì một kết quả duy nhất. Sau đó bạn có thể làm:

var listWithSum = list.Scan(new { Value = 0, Sum = 0 }, 
     (current, next) => new { Value = next, 
            Sum = current.Sum + next }); 

var result = listWithSum.TakeWhile(x => x.Sum < MaxTotal) 
         .Select(x => x.Value); 

(MoreLINQsimilar operator, btw - nhưng hiện tại nó không ủng hộ ý kiến ​​của chuỗi ắc và đầu vào không phải là cùng loại.)

+0

Điều đó có vẻ là một giải pháp thích hợp - tránh tác dụng phụ trên biến tmp. Tôi không biết về Tiện ích mở rộng phản ứng. Một vấn đề khác mà tôi không đề cập ở trên là bằng cách giới thiệu kết quả trung gian (loại ẩn danh) kết quả chứa giá trị hạt giống của tổng hợp/quét, mà không phải là một phần của danh sách ban đầu. –

+0

@martinweser: Nếu bạn cần bỏ qua kết quả đầu tiên, thật dễ dàng để thực hiện - nhưng tôi không * nghĩ * bạn cần phải quét. –

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