如何将具有相同值的多行列表连接成单行

How to concatenate multiple rows list with same value into single row

我有以下 class 称为“人”。

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }    
    public string Hobby { get; set; }
}

我创建了一个包含以下数据的列表:

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"},
};

现在我需要创建一个名为“usersHobbies”的新列表,调用时 returns 会出现以下结果。

Id    Name        Hobby 
1     Silva       Football, Sleeping, Handball   
2     Bob         Golf, Tennis
3     Sue         Drinking, Football             

您可以使用 GroupBy() 来实现。按第一组中的 Id、select 和 Name 分组,使用 string.Join() 将兴趣爱好合并为一个字符串:

var result = users.GroupBy(u => u.Id)  // group by Id
                  .Select(g => new     // select values
                  { 
                      Id = g.Key, 
                      Name = g.First().Name, 
                      Hobbies = string.Join(", ", g.Select(u => u.Hobby)) 
                  })
                  .ToList();

输出:

如果您想 return 一个新的 Person 而不是匿名类型,只需更新 Select:

 .Select(g => new Person
  { 
      Id = g.Key, 
      Name = g.First().Name, 
      Hobby = string.Join(", ", g.Select(u => u.Hobby)) 
  })

根据您的评论更新

is it possible instead of string.join() to return a list or array

是的,是的。使用匿名类型:

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();

其中 return 是 List<string> for Hobbies

.GroupBy() 有一个覆盖,可让您定义键选择器、元素选择器和结果选择器 (docs),这可能适合您的用例:

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();

这里,(user, hobbies)分别引用键选择器和元素选择器。

发生的事情是:

  • 根据 IdName(键选择器)的组合将用户分组为唯一用户
  • 每个独特用户的爱好被收集到一个IEnumerable<string>(元素选择器)
  • 对于每个唯一用户,都会创建一个 Person 对象并填充所有用户的爱好。