我在字符串列表上进行分组时遇到问题。
我的课程" Post"包含名为Tags:
的List属性public class Post
{
public string Title { get; set; }
public int Position { get; set; }
public List<string> Tags { get; set; }
}
我的代码中的其他地方我正在收集列表中的所有帖子。现在,其中许多帖子彼此共享标签。假设:
Post_1.Tags = new List<string>(){"a", "b", "c"};
Post_2.Tags = new List<string>(){"a", "d", "e"};
Post_3.Tags = new List<string>(){"b", "c", "d"};
Post_4.Tags = new List<string>(){"c", "d", "f"};
我正在尝试使用这种结构获得一个集合:
Key: a; Values: Post_1, Post_2;
Key: b; Values: Post_1, Post_3;
Key: c; Values: Post_1, Post_3, Post_4;
Key: d; Values: Post_2, Post_3, Post_4;
Key: e; Values: Post_2;
Key: f; Values: Post_4;
我想我需要使用GroupBy(),但我仍然坚持使用语法,因为:
List<Post> Posts = // all my posts
ILookup<string, Post> ByTag = Posts.GroupBy(p => p.Tags) ...
显然是针对标记列表而不是单个标记。
有什么建议吗?
答案 0 :(得分:2)
var tags = Posts.SelectMany(p => p.Tags).Distinct();
var groups = from p in Posts
from t in tags.Where(tag => p.Tags.Contains(tag))
group p by t
into gr
select gr;
<强>解释强>
SelectMany.Distinct - 使IEnumerable,包含所有帖子中没有重复的所有标签。
前2个 - 加入标签和帖子。加入条件 - 帖子应包含标签。最终的收集将是每一个可能的帖子和它的标签。
Group会以某种方式对这些对进行分组,gr的键将是一个标记,gr将是所有带有该标记的帖子的集合。我习惯了字典并编写了一段代码,以后可以通过调用Dictionary<string, List<Post>>
将其转换为ToDictionary(g => g.Key, g => g.ToList())
。如果您想要查找,则不需要组部分:
var tags = Posts.SelectMany(p => p.Tags).Distinct();
var postAndTagPairs = from p in Posts
from t in tags.Where(tag => p.Tags.Contains(tag))
select new {t, p};
var lookup = postAndTagPairs.ToLookup(pat => pat.t, pat => pat.p);
答案 1 :(得分:0)
首先需要获得一个独特的标签列表。假设帖子在这样的列表中:
var posts = new List<Post>
{
new Post { Tags = new List<string>(){"a", "b", "c"} },
new Post { Tags = new List<string>(){"a", "d", "e"} },
new Post { Tags = new List<string>(){"b", "c", "d"} },
new Post { Tags = new List<string>(){"c", "d", "f"} }
};
你得到这样的标签:
var allTags = posts.SelectMany(p => p.Tags).Distinct();
然后你可以进行分组:
var result = from p in posts
from t in allTags.Where(t => p.Tags.Contains(t))
group p by t into grp
select grp;