我有一个Publication对象列表:
public class Publication
{
public List<string> Authors { get; set; }
}
我想使用LINQ将作者的发布对象分组。 我的解决方案使用字典,如下所示:
var dict = new Dictionary<string, List<Publication>>();
foreach (var publication in list)
{
foreach(var author in publication.Authors)
{
if (dict.ContainsKey(author))
{
dict[author].Add(publication);
}
else
{
dict.Add(author, new List<Publication> { publication });
}
}
}
然而这对我来说似乎很难看。对于这个问题,必须有一个简单而优雅的单行,但我无法直截了当。我还尝试使用Authors属性上的selectmany来压缩列表,然后将它们分组,但它只删除了作者字符串,并且发布对象消失了。
答案 0 :(得分:3)
使用LINQ,您可以这样做:
var groupedByAuthor = list
.SelectMany(publication =>
publication.Authors.Select(author => new { author, publication }))
.GroupBy(arg => arg.author, keyValue => keyValue.publication)
.ToArray();
但这会慢一些。
答案 1 :(得分:0)
您可以使用Linq和一些匿名类:
return getField(thisPath, field.children)
答案 2 :(得分:0)
如果你更关心干净和富有表现力的代码,你可能想尝试创建一个扩展方法而不是强制一个丑陋的linq查询。代码应如下所示。
class Program
{
static void Main(string[] args)
{
List<Publication> test = new List<Publication>();
Dictionary<string, List<Publication>> publicationsByAuther = test.GroupByAuthor();
}
}
public static class Extensions
{
public static Dictionary<string, List<Publication>> GroupByAuther(this List<Publication> publications)
{
Dictionary<string, List<Publication>> dict = new Dictionary<string, List<Publication>>();
foreach (var publication in publications)
{
foreach (var author in publication.Authors)
{
if (dict.ContainsKey(author))
{
dict[author].Add(publication);
}
else
{
dict.Add(author, new List<Publication>
{
publication
});
}
}
}
return dict;
}
}
答案 3 :(得分:0)
您可能会考虑将添加新作者与添加发布的情况分开。将代码转换成类似的东西:
var dict = new Dictionary<string, List<Publication>>();
foreach (var publication in list)
{
foreach (var author in publication.Authors)
{
if (!dict.ContainsKey(author))
dict.Add(author, new List<Publication>());
dict[author].Add(publication);
}
}
这不是LINQ而不是一个新的解决方案,但也许它可以帮助关于优雅
答案 4 :(得分:-1)
你也可以这样做:
var dict = pubs.SelectMany(p => p.Authors)
.ToDictionary(
a => a,
a => pubs.Where(p => p.Contains(a)).ToList())
);
未经测试,但您明白了。