我正在尝试做一些非常简单的事情,但出于某些原因,我无法做到有效并且看起来像我期望的那样好。
我有一组人员,我需要用逗号分隔姓名,以便那些拥有相同电子邮件的人。
我尝试使用Aggregate
函数,但它会为所有电子邮件返回一个字符串。我可以在foreach循环中完成它,但它似乎不是最好的方法。
有人可以告诉我实现这个的好方法吗?
这是数据:
var persons = new List<Person>
{
new Person
{
Email = "A@gmail.com",
Name = "Mori"
},
new Person
{
Email = "A@gmail.com",
Name = "Tori"
},
new Person
{
Email = "A@gmail.com",
Name = "Jake"
},
new Person
{
Email = "A@gmail.com",
Name = "Jove"
},
new Person
{
Email = "B@gmail.com",
Name = "John"
},
new Person
{
Email = "B@gmail.com",
Name = "James"
}
};
预期结果:
返回列表:
答案 0 :(得分:5)
以King Kings为基础回答:
var groupedByEmails = persons.GroupBy (p => p.Email)
.Select (p => new Person {
Email = p.Key,
Name = String.Join(", ", p.Select (x => x.Name))
}).ToList();
groupedByEmails.Dump(); //only in LinqPad
虽然我不建议使用Person类。我宁愿为该投影创建一个单独的视图模型。这是因为人类在这种情况下描述了一个人。使用它来存储某种人物收集是一种解决问题的方法。
输出:
在某些时候,你会想知道Person
现在是否存储了一个名称或多个名称,你会引入一些if if if(p.Name.indexOf(", ") != -1)
来处理它并且你继续堆积这些债务。只需创建一个EmailPersonCollectionVm.cs
public class EmailPersonCollectionVm
{
public string Email { get; set;}
public List<string> Names {get; set;}
}
答案 1 :(得分:3)
var res=from data in persons
group data by data.Email into groupdata
select new
{
Email=groupdata.Key,
Name=string.Join(",",groupdata.Select((x=>x.Name)).ToList())
};
答案 2 :(得分:3)
你可以试试这个:
var result = persons.GroupBy(c => c.Email).Select(c => new Person()
{
Email = c.First().Email,
Name = string.Join(", ", c.Select(b=>b.Name).ToList())
});
答案 3 :(得分:1)
Hello Misha Zaslavsky,
在这种情况下,您可以轻松使用LINQ查询和格式化输出:
var maillist = from p in persons
group p by p.Email into grp
select new { grp.Key, Names=grp.Select(g => g.Name).ToArray() };
foreach( var entry in maillist) {
Console.WriteLine($"EMail: {entry.Key} Names: {string.Join<string>(",", entry.Names)}" );
}