2010-04-23 16 views
5

öğelerinin toplamına (veya bir araya getirilmesine) bağlı olarak bir öğe listesi var ve almak istiyorumSadece bir öğenin toplamını (veya öğelerin bir araya toplanmasını) karşılayın. Aşağıdaki kod iş yapar, ancak bunun uygun bir modelin olması gerektiği sıra dışı bir sorun olmadığından eminim.Linq TakeWhile

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; 

birileri muhtemelen bir sorguya TakeWhile ve Agrega birleştirerek, daha güzel bir şekilde görev çözmek için nasıl biliyor mu?

Thx

+0

Bunun farkındayım: Daha sonra yapabileceği biri değişkenleri bir sorgunun yan etkisi olarak değiştirmemelidir. ListWithSum iki kez kullanılırsa, tmp aralarında başlatılmamışsa farklı sonuçlara yol açacaktır. Bu nedenlerden biri, neden bu çözüm kötü biri olduğuna inanıyorum! –

+0

var list = yeni Liste {1, 2, 3, 4, 5, 6, 7}; int tmp = 0; int MAX = 10; var result2 = list.TakeWhile (x => { tmp + = x; dönüş tmp

+0

thx Nick. Bu daha kısa (ve dolayısıyla daha güzel) bir versiyon olsa da, bir yan etki ile aynı sorunu vardır. –

cevap

2

Size Reactive Extensions den Scan yönteme gibi bir şey (System.Interactive parçası) istemek geliyor bana - bu Aggregate gibi, ama yerine tek sonuç dizisini verir. (Btw, MoreLINQ bir similar operator var - ama şu anda akümülatör ve giriş sekansı aynı tip olmama fikrini desteklemez.)

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); 

+0

Bu uygun bir çözüm gibi görünüyor - tmp değişkenindeki yan etkiden kaçınmak. Reaktif Uzantılar farkında değildim. Yukarıda bahsetmediğim bir diğer problem, ara sonucu (anonim tip) tanıtmak suretiyle, sonuç, ilk listenin parçası olmayan toplama/taramanın tohum değerini içerir. –

+0

@martinweser: İlk sonucu atlamanız gerekiyorsa, bunu yapmak çok kolay - ama ben düşünmüyorum * Scan ile ihtiyacınız var. –