Miguel Moura
Miguel Moura

Reputation: 39364

Sum property values from different objects

I have the following class:

public class Data {
  public Decimal DataValueA { get; set; }
  public Decimal DataValueB { get; set; }
  public Decimal DataValueC { get; set; }
  public Decimal DataValueD { get; set; }
} // Data

And I have a List<Data>. I need to create a new Data object:

Data total = new Data();

Where the DataValueA is the sum of all DataValueAs in Data items of List<Data>.

The same for DataValueB, DataValueC, etc.

I was trying to do this with Linq but now sure how.

Upvotes: 0

Views: 559

Answers (3)

Jamiec
Jamiec

Reputation: 136094

You could use Sum but that will cause a number of iterations over the list:

var total = new Data
{
    DataValueA = list.Sum(x => x.DataValueA),
    DataValueB = list.Sum(x => x.DataValueB),
    DataValueC = list.Sum(x => x.DataValueC),
    DataValueD = list.Sum(x => x.DataValueD),
};

Or you could us Aggregate which will only iterate the list once:

var data = new[]{
            new Data{DataValueA=1,DataValueB=2,DataValueC=3,DataValueD=4},
            new Data{DataValueA=1,DataValueB=2,DataValueC=3,DataValueD=4},
            new Data{DataValueA=1,DataValueB=2,DataValueC=3,DataValueD=4},
            new Data{DataValueA=1,DataValueB=2,DataValueC=3,DataValueD=4},
        };

var result = data.Aggregate(new Data(),(a,b) => {
    a.DataValueA += b.DataValueA; 
    a.DataValueB += b.DataValueB;
    a.DataValueC += b.DataValueC;
    a.DataValueD += b.DataValueD;
    return a;
});

Live example: http://rextester.com/ODL27846

More info: LINQ Aggregate algorithm explained

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726499

If multiple enumerations of the collection are OK with you, you could use list.Sum(item => item.Property) several times. If it is critical that you go through the list only once, for example, because it is generated through deferred execution of filters, you could use Aggregate instead:

var totals = list.Aggregate(new Data(), (prev, item) => {
     prev.DataValueA += item.DataValueA;
     prev.DataValueB += item.DataValueB;
     ...
     return prev;
});

Upvotes: 1

James
James

Reputation: 82096

var total = new Data
{
    DataValueA = list.Sum(x => x.DataValueA),
    DataValueB = list.Sum(x => x.DataValueB),
    ...
};

Upvotes: 2

Related Questions