I have the following class called "Person".
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Hobby { get; set; }
}
I created a list with the following data:
List<Person> users = new List<Person>()
{
new Person {Id= 1, Name = "Silva", Hobby = "Football" },
new Person {Id= 2, Name = "Bob", Hobby = "Golf"},
new Person {Id= 2, Name = "Bob", Hobby = "Tennis"},
new Person {Id= 1, Name = "Silva", Hobby = "Sleeping"},
new Person {Id= 3, Name = "Sue", Hobby = "Drinking"}
new Person {Id= 1, Name = "Silva", Hobby = "Handball"},
new Person {Id= 3, Name = "Sue", Hobby = "Football"},
};
Now I need to create a new list called "usersHobbies" that when called returns the following result.
Id Name Hobby
1 Silva Football, Sleeping, Handball
2 Bob Golf, Tennis
3 Sue Drinking, Football
CodePudding user response:
If you want to return a new Person
instead of an anonymous type, just update the Select
:
.Select(g => new Person
{
Id = g.Key,
Name = g.First().Name,
Hobby = string.Join(", ", g.Select(u => u.Hobby))
})
Update from your comment:
is it possible instead of string.join() to return a list or array
Yes, it is. Using an anonymous type:
var result = users.GroupBy(u => u.Id) // group by Id
.Select(g => new // select values
{
Id = g.Key,
Name = g.First().Name,
Hobbies = g.Select(u => u.Hobby).ToList()
})
.ToList();
Which returns a List<string>
for Hobbies
.
CodePudding user response:
.GroupBy()
has an override that lets you define a key selector, an element selector and the result selector (docs), which could suit your use case:
var result = users
.GroupBy(
u => new { u.Id, u.Name }, // key selector
u => u.Hobby, // element selector
(user, hobbies) => new Person {
Id = user.Id,
Name = user.Name,
Hobby = string.Join(", ", hobbies) })
.ToList();
Here, (user, hobbies)
are referencing the key selector and the element selector, respectively.
What happens is:
- the users are grouped into unique users based on the combination of
Id
andName
(key selector) - the hobbies of each unique user are collected into an
IEnumerable<string>
(element selector) - for each unique user, a
Person
object is created and populated with all of the users hobbies.