You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将表格数据重组为复杂C#对象?优化嵌套字典实现

问题描述

现有如下结构的文章多语言内容表格:

postIdlanguagenamevalue
1entitlePost 1 title
1enbodyThis is the content for the post 1
1frtitleTitre de l'article 1
1frbodyVoici le contenu de l'article 1
2entitlePost 2 title
2enbodyThis is the content for the post 2
3entitlePost 3 title
3enbodyThis is the content for the post 3
3frtitleTitre de l'article 3
3frbodyVoici le contenu de l'article 3
3detitleTitel von Artikel 3
3debodyLesen 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 10:24:54