Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Combine two Sum operations into one using LINQ?

I have this code

Dim sum As Integer = scores.Sum(Function(score) score.Fraction * score.Score)
Dim count As Integer = scores.Sum(Function(score) score.Fraction)

or in C#:

var sum=scores.Sum(score=>score.Fraction * score.Score);
var count=scores.Sum(score=>score.Fraction);

How can I merge these AND achieve that the collection is only enumerated once? I did find some examples but if I am not mistaken they still iterate the collection twice.

like image 537
Dabblernl Avatar asked Sep 18 '11 12:09

Dabblernl


2 Answers

var sum = 0;
var count = 0;

foreach(var score in scores){
    sum += score.Fraction * score.Score;
    count += score.Fraction;
}

... My point is, why use LINQ at all - it's meant to make certain things easier, but this is not easier with LINQ.

like image 116
Petar Ivanov Avatar answered Oct 02 '22 15:10

Petar Ivanov


You can do it with Aggregate, although it's a bit of a pain - and creates an extra object for each iteration:

var sums = scores.Aggregate(new { Sum = 0, Count = 0 },
     (current, item) => new { Sum = current.Sum + item.Score * item.Fraction,
                              Count = current.Count  + item.Fraction });

Obviously you could make this more efficient by creating a ValueTuple<T1, T2> struct - like tuple, but as a struct.

EDIT: I agree with Petar's point - if this is all you need to do, then LINQ isn't actually helpful in this situation.

like image 40
Jon Skeet Avatar answered Oct 02 '22 14:10

Jon Skeet