如何将表格数据重组为复杂C#对象?优化嵌套字典实现
问题描述
现有如下结构的文章多语言内容表格:
| postId | language | name | value |
|---|---|---|---|
| 1 | en | title | Post 1 title |
| 1 | en | body | This is the content for the post 1 |
| 1 | fr | title | Titre de l'article 1 |
| 1 | fr | body | Voici le contenu de l'article 1 |
| 2 | en | title | Post 2 title |
| 2 | en | body | This is the content for the post 2 |
| 3 | en | title | Post 3 title |
| 3 | en | body | This is the content for the post 3 |
| 3 | fr | title | Titre de l'article 3 |
| 3 | fr | body | Voici le contenu de l'article 3 |
| 3 | de | title | Titel von Artikel 3 |
| 3 | de | body | Lesen Sie den Inhalt von Artikel 3 |
需要将其转换为如下JSON结构的C#对象:
{ "posts":[ { "1":[ { "en":{ "title":"Post 1 title", "body":"This is the content for the post 1" } }, { "fr":{ "title":"Titre de l'article 1", "body":"Voici le contenu de l'article 1" } } ] }, { "2":[ { "en":{ "title":"Post 2 title", "body":"This is the content for the post 2" } } ] }, { "3":[ { "en":{ "title":"Post 3 title", "body":"This is the content for the post 3" } }, { "fr":{ "title":"Titre de l'article 3", "body":"Voici le contenu de l'article 3" } }, { "de":{ "title":"Titel von Artikel 3", "body":"Lesen Sie den Inhalt von Artikel 3" } } ] } ] }
当前采用三层嵌套字典+多层if判断的实现方式,代码如下:
Dictionary<string, Dictionary<string, Dictionary<string, string>>> postsDictionnary= new(); foreach(var post in postsList) { if (postsDictionnary.ContainsKey(post.postId)) { if (postsDictionnary[post.postId].ContainsKey(post.language)) { if (postsDictionnary[post.itemId][post.language].ContainsKey(post.name)) { postsDictionnary[post.itemId][post.language][post.name] = post.value; } else { postsDictionnary[post.postId][post.language].Add(post.name, post.value); } } else { postsDictionnary[post.postId].Add(post.language, new Dictionary<string, string>()); postsDictionnary[post.postId][post.language].Add(post.name, post.value); } } else { postsDictionnary.Add(post.postId, new Dictionary<string, Dictionary<string, string>>()); postsDictionnary[post.postId].Add(post.language, new Dictionary<string, string>()); postsDictionnary[post.postId][post.language].Add(post.name, post.value); } }
这种写法嵌套层级过多,不够优雅,求更优实现方式。
优化实现方案
方法1:使用LINQ分组简化逻辑
利用LINQ的GroupBy直接按层级分组,代码简洁易读,无需手动判断键是否存在:
var result = new { posts = postsList .GroupBy(p => p.postId) .Select(postGroup => new Dictionary<string, List<Dictionary<string, Dictionary<string, string>>>> { { postGroup.Key.ToString(), postGroup .GroupBy(p => p.language) .Select(langGroup => new Dictionary<string, Dictionary<string, string>> { { langGroup.Key, langGroup.ToDictionary(p => p.name, p => p.value) } }) .ToList() } }) .ToList() };
方法2:定义强类型类(提升可维护性)
通过实体类明确数据结构,代码意图更清晰,后续扩展或修改字段更方便:
// 定义文章内容实体 public class PostContent { public string Title { get; set; } public string Body { get; set; } } // 转换逻辑 var postCollection = new { posts = postsList .GroupBy(p => p.postId) .Select(postGroup => new Dictionary<string, List<Dictionary<string, PostContent>>> { { postGroup.Key.ToString(), postGroup .GroupBy(p => p.language) .Select(langGroup => new Dictionary<string, PostContent> { { langGroup.Key, new PostContent { Title = langGroup.First(p => p.name == "title").value, Body = langGroup.First(p => p.name == "body").value } } }) .ToList() } }) .ToList() };
方法3:简化字典操作逻辑
如果坚持使用字典,可利用TryGetValue方法扁平化嵌套判断,提升代码可读性:
var postsDictionary = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>(); foreach (var post in postsList) { // 获取或创建postId对应的字典 if (!postsDictionary.TryGetValue(post.postId, out var langDict)) { langDict = new Dictionary<string, Dictionary<string, string>>(); postsDictionary.Add(post.postId, langDict); } // 获取或创建language对应的字典 if (!langDict.TryGetValue(post.language, out var contentDict)) { contentDict = new Dictionary<string, string>(); langDict.Add(post.language, contentDict); } // 直接赋值(存在则覆盖,不存在则自动添加) contentDict[post.name] = post.value; }
内容的提问来源于stack exchange,提问作者A. Flouw
相关产品推荐
相关产品推荐

