簡體   English   中英

LinQ C#-根據對象列表中包含的字符串對對象列表進行分組 <string> 屬性

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM