xGeo
xGeo

Reputation: 2139

Sum List<T> Properties of each item in List<T>

Please refer to ff. codes:

MainObj:

public class MainObj {
    public string Name { get; set; }
    public int SomeProperty { get; set; }
    public List<SubObj> Subojects { get; set; }
}

SubObj:

public class SubObj {
    public string Description { get; set; }
    public decimal Value { get; set; }
}

QUESTION: I have a List<MainObj>. Each item has equal number of SubObj. How do I sum the values of each SubObj from MainObj A which corresponds to the same index as the SubObj in the other MainObj in the list.

To illustrate further:

Results:

{
    Name: "something....",
    Value: SUM(MainObj_A.SubObj[0], MainObj_B.SubObj[0] .... MainObj_n.SubObj[0]
},
{
    Name: "don't really care...."
    Value: SUM(MainObj_A.SubObj[1], MainObj_B.SubObj[1] .... MainObj_n.SubObj[1]
},
{
    Name: "don't really care...."
    Value: SUM(MainObj_A.SubObj[2], MainObj_B.SubObj[2] .... MainObj_n.SubObj[2]
}
.... so on and so forth

I know I can loop thru each item in MainObj then perform the sum but I was hoping that there is a simpler way using Linq.

Sorry if I can't put the right words for my question. I hope the illustrations helped.

Every help would be much appreciated. CHEERS!

Upvotes: 2

Views: 461

Answers (3)

Felix Too
Felix Too

Reputation: 11931

For flexibility and slightly boosted performance, I'd prefer a mixed LINQ-sql way as shown in my answer below.

var result = from x in list
             where x...
             group x by x.SomeProperty 
             into item
             select new {
             Id = item.Key,
             Name = item.Name,
             Value = item.SubObj.Sum(i => i.Value) 
             };

Upvotes: 2

Maksim Simkin
Maksim Simkin

Reputation: 9679

I would extend solution of Rene, to sum over all subitems:

var result = list.First().Subojects.Select((m, i) => new
{
    Name = i.ToString(),
    Value = list.Sum(t => t.Subojects[i].Value)
}).ToList();

i have used it with this values:

var list = new List<MainObj>
{
    new MainObj { Name = "A", Subojects = new List<SubObj>{new SubObj{ Value = 1}, new SubObj{ Value = 2}, new SubObj{ Value = 3}}},
    new MainObj { Name = "B", Subojects = new List<SubObj>{new SubObj{ Value = 1}, new SubObj{ Value = 2}, new SubObj{ Value = 3}}}
};

And result is:

0:2
1:4
2:6

Upvotes: 1

Ren&#233; Vogt
Ren&#233; Vogt

Reputation: 43886

As I understand the question you look for something like this:

var results = list.Select((m, i) => new 
          {
             m.Name, 
             Value = list.Sum(t => t.SubObj[i].Value)
          }).ToList();

This creates a list of an anonymous type containing the name of each main object and the sum of all subobject values with the same index as the main object.


It's not clear from your question, but if you want to sum all subojects (not only as many as there are main objects), you can do it like this:

var results = Enumerable.Range(0, list[0].SubObj.Count)
                        .Select(i => list.Sum(m => m.SubObj[i].Value)).ToList();

This gives you a list of the sums (without names, as your examples suggest that you "don't really care" about any names).

Upvotes: 6

Related Questions