Alex Rivera | Logout

Multiple SUM using LINQ

Asked 2009-11-09T22:05:39.520
11

I have a loop like the following, can I do the same using multiple SUM?

foreach (var detail in ArticleLedgerEntries.Where(pd => pd.LedgerEntryType == LedgerEntryTypeTypes.Unload &&
                                                                pd.InventoryType == InventoryTypes.Finished))
{
     weight += detail.GrossWeight;
     length += detail.Length;
     items  += detail.NrDistaff;
}
Edit
Report

2 Answers

8

Technically speaking, what you have is probably the most efficient way to do what you are asking. However, you could create an extension method on IEnumerable<T> called Each that might make it simpler:

public static class EnumerableExtensions
{
    public static void Each<T>(this IEnumerable<T> col, Action<T> itemWorker)
    {
        foreach (var item in col)
        {
            itemWorker(item);
        }
    }
}

And call it like so:

// Declare variables in parent scope
double weight;
double length;
int items;

ArticleLedgerEntries
    .Where(
        pd => 
           pd.LedgerEntryType == LedgerEntryTypeTypes.Unload &&
           pd.InventoryType == InventoryTypes.Finished
    )
    .Each(
        pd => 
        {
            // Close around variables defined in parent scope
            weight += pd.GrossWeight; 
            lenght += pd.Length;
            items += pd.NrDistaff;
        }
    );

UPDATE: Just one additional note. The above example relies on a closure. The variables weight, length, and items should be declared in a parent scope, allowing them to persist beyond each call to the itemWorker action. I've updated the example to reflect this for clarity sake.

answered 2009-11-09T23:00:11.277
3

You could also group by true - 1 (which is actually including any of the items and then have them counted or summered):

 var results = from x in ArticleLedgerEntries
                       group x by 1
                       into aggregatedTable
                       select new
                                  {
                                      SumOfWeight = aggregatedTable.Sum(y => y.weight),
                                      SumOfLength = aggregatedTable.Sum(y => y.Length),
                                      SumOfNrDistaff = aggregatedTable.Sum(y => y.NrDistaff)
                                  };

As far as Running time, it is almost as good as the loop (with a constant addition).

answered 2011-10-30T05:37:36.843

Your Answer