C# LINQ GroupBy to convert a List to a group with one property as List of values

11.3k Views Asked by At

I have a list of objects list1

Name Value
N1   V100 
N2   V101
N1   V102
N4   V103
N4   V104

I want to convert this into a grouped List

Name Values
N1   V100, V102 
N2   V101
N4   V103, V104

When I use GroupBy I get the whole thing, ( list1.GroupBy(key => key.Name) )

Name Values
N1
  N1   V100
  N1   V102
N2
  N2   V101
N4
  N4   V103
  N4   V104

I just want the values as a List.

2

There are 2 best solutions below

0
On BEST ANSWER

After GroupBy, use ToDictionary:

source.GroupBy(x => x.Name)
      .ToDictionary(x => x.Key, x => x.Select(e => e.Value).ToList());

This yields a Dictionary<string, List<string>> where the keys are the names and the values are lists made up of projecting each element to a string under that specific group.

I assume that Value is a string for example purposes only but in reality, it doesn't really matter as the solution remains the same.

0
On

Adding another answer here by someone, (which seems to have been deleted, I was trying that approach and got it to work too).
All credit goes to that anonymous person.

    source.GroupBy(x => x.Name, y=> y.Value)
          .Select( result => new { Name = result.Name,
                                   Values = result.Select(r=> r.Value).ToList() } );

The dictionary solution seems to be more intuitive as I can see all the transformations happening to generate the result.

EDIT:

Spent way too much time on this, here are 2 other ways to make this happen:-

source.GroupBy(grpKey => grpKey.Name, 
                   elementSelector => elementSelector,
                   (resultSelectorName, resultSelectorValues ) => new 
                   {
                     Name = resultSelectorName,
                     Values = resultSelectorValues.Select(v=>v.Value).ToList() 
                   });

2)

source.GroupBy(grpKey => grpKey.Name, 
               elementSelector => elementSelector.Value,
               (resultSelectorName, resultSelectorValue ) => new 
               {
                 Name = resultSelectorName,
                 Values = resultSelectorValue.ToList() 
               });