使用 Linq 反转层次结构
Inverting a Hierarchy with Linq
鉴于 class
public class Article
{
public string Title { get; set; }
public List<string> Tags { get; set; }
}
和
List<Article> articles;
如何使用 Linq 从单个标签(可能与 1 篇或多篇文章相关联)创建 "map"?
Dictionary<string, List<Article>> articlesPerTag;
我知道我可以select所有这样的标签
var allTags = articlesPerTag.SelectMany(a => a.Tags);
但是,我不确定如何将每个 selected 标签关联回其来源的文章。
我知道我可以按照
的方式写这个
Dictionary<string, List<Article>> map = new Dictionary<string, List<Article>>();
foreach (var a in articles)
{
foreach (var t in a.Tags)
{
List<Article> articlesForTag;
bool found = map.TryGetValue(t, out articlesForTag);
if (found)
articlesForTag.Add(a);
else
map.Add(t, new List<Article>() { a });
}
}
但我想了解如何使用 Linq 完成此操作。
还有一种使用 GroupBy 的方法。虽然有点复杂。
articles.SelectMany(article => article.Tags)
.Distinct()
.GroupBy(tag => tag, tag => articles.Where(a => a.Tags.Contains(tag)))
.ToDictionary(group => group.Key,
group => group.ToList().Aggregate((x, y) => x.Concat(y).Distinct()));
如果您特别需要它作为从标签到文章的字典,您可以使用类似这样的东西。
var map = articles.SelectMany(a => a.Tags.Select(t => new { t, a }))
.GroupBy(x => x.t, x => x.a)
.ToDictionary(g => g.Key, g => g.ToList());
虽然使用查找会更有效,但这正是您要构建的内容。
var lookup = articles.SelectMany(a => a.Tags.Select(t => new { t, a }))
.ToLookup(x => x.t, x => x.a);
鉴于 class
public class Article
{
public string Title { get; set; }
public List<string> Tags { get; set; }
}
和
List<Article> articles;
如何使用 Linq 从单个标签(可能与 1 篇或多篇文章相关联)创建 "map"?
Dictionary<string, List<Article>> articlesPerTag;
我知道我可以select所有这样的标签
var allTags = articlesPerTag.SelectMany(a => a.Tags);
但是,我不确定如何将每个 selected 标签关联回其来源的文章。
我知道我可以按照
的方式写这个Dictionary<string, List<Article>> map = new Dictionary<string, List<Article>>();
foreach (var a in articles)
{
foreach (var t in a.Tags)
{
List<Article> articlesForTag;
bool found = map.TryGetValue(t, out articlesForTag);
if (found)
articlesForTag.Add(a);
else
map.Add(t, new List<Article>() { a });
}
}
但我想了解如何使用 Linq 完成此操作。
还有一种使用 GroupBy 的方法。虽然有点复杂。
articles.SelectMany(article => article.Tags)
.Distinct()
.GroupBy(tag => tag, tag => articles.Where(a => a.Tags.Contains(tag)))
.ToDictionary(group => group.Key,
group => group.ToList().Aggregate((x, y) => x.Concat(y).Distinct()));
如果您特别需要它作为从标签到文章的字典,您可以使用类似这样的东西。
var map = articles.SelectMany(a => a.Tags.Select(t => new { t, a }))
.GroupBy(x => x.t, x => x.a)
.ToDictionary(g => g.Key, g => g.ToList());
虽然使用查找会更有效,但这正是您要构建的内容。
var lookup = articles.SelectMany(a => a.Tags.Select(t => new { t, a }))
.ToLookup(x => x.t, x => x.a);