![](/img/trans.png)
[英]Multiple Grouping with IQueryable and returning a list of objects in C# linq query
[英]LinQ C# - Grouping a list of objects depending on strings contained in their List<string> property
我对字符串列表进行分组有问题。
我的类“ Post”包含一个称为“标签”的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) ...
显然是针对标签列表,而不是单个标签。
有什么建议么?
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个-加入标签和帖子。 加入条件-帖子中应包含标签。 结果集合将包含所有可能的帖子对及其标签。 分组将以某种方式将这些对分组,即gr的键将是一个标签,gr将是具有该标签的所有帖子的集合。 我习惯了字典并编写了一个代码,以后可以通过调用ToDictionary(g => g.Key, g => g.ToList())
将其转换为Dictionary<string, List<Post>>
。 如果要查找,则不需要组部分:
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);
您首先需要获得一个独特的标签列表。 假设帖子在这样的列表中:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.