Question

I am confused by the groupby behavior in LINQ to objects. Lets assume for this I have the following class;

public class person
{
   public string name { get; set; }
   public int age { get; set; }
}

Lets say I have a list or type person; List<person> people

Now, I want to produce an IEnumerable<T> with an IGrouping or anonymous type that has two properties 1) the name (the key) and 2) the sum of all of the ages for people with that name.

Here are a couple of examples of things I've tried (unsuccessfully);

people.GroupBy(x => x.name, x => x, (key, value) => value.Aggregate((c, n) => c + n));

That won't compile with the error cannot convert type "int" to "namespace.person"

Before that I was trying something more along the lines of;

people.GroupBy(x => x.name).Select(g => new { g.Key, g.Aggregate((c, n) => c + n)) } );

Which essentially gives the same error. I'm basically struggling to understand what the value returned by GroupBy really is. At first I thought that basic overload was giving me a key value pair where x.Key was the key I specified with my delegate and x.Value would be an IEnumerable<T> where the typeof T would be the type of x. Of course, if that were the case my second example would work like a charm. My question is somewhat open ended but can someone explain 2 things, firstly; How do I accomplish my end goal with LINQ? And Secondly, why isn't the result of GroupBy more along the lines of what I describe here? What is it? I feel like a key value pair where the value is a collection of objects that match that key is far more intuitive than what is actually returned.

Was it helpful?

Solution

 var grouped = people.GroupBy(x => x.name)
                                .Select(x => new
                                    {
                                        Name = x.Key,
                                        Age = x.Sum(v => v.age),
                                        Result = g.Aggregate(new Int32(), (current, next) => next.age + next.age)
                                    });

If you want you can group the result of that again by Name and it will be a grouping with Key as the name and Age as the value

OTHER TIPS

you can do it with expression syntax

var results = from p in persons
              group p.car by p.name into g
              select new { name = g.Key, age = g.Sum(c=>.age };
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top