450
public class ConsolidatedChild
{
    public string School { get; set; }
    public string Friend { get; set; }
    public string FavoriteColor { get; set; }
    public List<Child> Children { get; set; }
}

public class Child
{
    public string School { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Friend { get; set; }
    public string Mother { get; set; }
    public string FavoriteColor { get; set; }
}

Given the two classes above, I would like to use LINQ to create a List from the List, grouped by the School, Friend and FavoriteColor properties. Is this possible with LINQ?

Please ignore the properties, the code has been written just to help with the question.

2
  • 1
    Yes it is possible. Take a look at the sample provided in this post. Commented Mar 8, 2011 at 11:34
  • 2
    Here is another good example stackoverflow.com/questions/15605468/… Commented Aug 29, 2016 at 15:23

2 Answers 2

745
var consolidatedChildren =
    from c in children
    group c by new
    {
        c.School,
        c.Friend,
        c.FavoriteColor,
    } into gcs
    select new ConsolidatedChild()
    {
        School = gcs.Key.School,
        Friend = gcs.Key.Friend,
        FavoriteColor = gcs.Key.FavoriteColor,
        Children = gcs.ToList(),
    };

var consolidatedChildren =
    children
        .GroupBy(c => new
        {
            c.School,
            c.Friend,
            c.FavoriteColor,
        })
        .Select(gcs => new ConsolidatedChild()
        {
            School = gcs.Key.School,
            Friend = gcs.Key.Friend,
            FavoriteColor = gcs.Key.FavoriteColor,
            Children = gcs.ToList(),
        });
Sign up to request clarification or add additional context in comments.

7 Comments

Let's say I have lot's of properties in the group by, is there a cleaner way of doing this then listing all the properties?
@guiomie - I wouldn't say that there was a cleaner way. You could serialize the object into a single string and group on that, but that would require more code elsewhere. So, in my mind, this answer is the cleanest way regardless how many properties.
@Doppelganger - I rolled back your edit for two reasons. The choice of using the final comma (after FavoriteColor) is on purpose - it is legal syntax and it enables easier refactoring of code. The choice of using gcs rather than gc for the grouping variable is also on purpose - it shows me that it is a "group of many c's".
I thought for sure that wouldn't compile, but you're absolutely right. As for renaming your variable, that was just to get past the six character limit. I never like to mess with someone's variable names. Anyway, thanks again for the awesome answer!
Can you make an alternate example for method syntax?
|
274

Given a list:

var list = new List<Child>()
{
    new Child()
        {School = "School1", FavoriteColor = "blue", Friend = "Bob", Name = "John"},
    new Child()
        {School = "School2", FavoriteColor = "blue", Friend = "Bob", Name = "Pete"},
    new Child()
        {School = "School1", FavoriteColor = "blue", Friend = "Bob", Name = "Fred"},
    new Child()
        {School = "School2", FavoriteColor = "blue", Friend = "Fred", Name = "Bob"},
};

The query would look like:

var newList = list
    .GroupBy(x => new {x.School, x.Friend, x.FavoriteColor})
    .Select(y => new ConsolidatedChild()
        {
            FavoriteColor = y.Key.FavoriteColor,
            Friend = y.Key.Friend,
            School = y.Key.School,
            Children = y.ToList()
        }
    );

Test code:

foreach(var item in newList)
{
    Console.WriteLine("School: {0} FavouriteColor: {1} Friend: {2}", item.School,item.FavoriteColor,item.Friend);
    foreach(var child in item.Children)
    {
        Console.WriteLine("\t Name: {0}", child.Name);
    }
}

Result:

School: School1 FavouriteColor: blue Friend: Bob
    Name: John
    Name: Fred
School: School2 FavouriteColor: blue Friend: Bob
    Name: Pete
School: School2 FavouriteColor: blue Friend: Fred
    Name: Bob

5 Comments

For those of us who prefer the fluent interface. One tiny quibble: using the same variable "x" in both Func definitions isn't very clear for newer users. I'd recommend changing to match the one above, where "c" is the child, and "gcs" is the grouped children.
@jazmatician _ I agree with you on the point that re-using x might confuse some, but not on the choice for variable names. I'll change it to x and y to diferentiate.
The variable names aren't my choice, either. In fact, when writing that I struggled to figure out what "gcs" meant to the author. Best I could come up with was "group (of) Cs." Anyway, I only recommended it to try to make it easy for someone to make the mental map between the two syntaxes. (syntaces? I bet syntax is one of those words which is its own plural. Because this is English, why would "syntax" be subject to syntactic rules about plurals?)
to answer my own tangent: en.wiktionary.org/wiki/syntax
I disagree with this opinion Michael. In my opinion, x should be used in both places. The only time it should not is when you use a Func withing another Hunc, then you should go to y. Otherwise it becomes confusing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.