• 【nlohmann/json】树节点的序列化和反序列化


    nlohmann/json官方网站
    https://github.com/nlohmann/json
    https://json.nlohmann.me/api/basic_json/

    背景

    2022.09

    nlohmann/json官方序列化,提供了宏NLOHMANN_DEFINE_TYPE_INTRUSIVE;
    它支持多层嵌套,但对于指针无法序列化;
    实际上这个宏定义就是在class中增加了to_json和from_json函数,我们可以自己去实现一下即可;
    在这里插入图片描述

    示例

    TreeNode.hpp

    class TreeNode;
    
    using TreeNodePtr = std::shared_ptr<TreeNode>;
    
    using ShaJson = nlohmann::json;
    
    class TreeNode {
    public:
        std::string id;
        std::string name;
        std::list<TreeNodePtr> children;
    
        friend void to_json(nlohmann::json& nlohmann_json_j, const TreeNode& nlohmann_json_t)
        {
            nlohmann_json_j["id"] = nlohmann_json_t.id;
            nlohmann_json_j["name"] = nlohmann_json_t.name;
            nlohmann_json_j["children"] = nlohmann::json::array();
    
            for(TreeNodePtr x : nlohmann_json_t.children)
            {
                std::cout << x->name << std::endl;
    
                nlohmann::json jsonTemp;
    
                to_json(jsonTemp, *x);
    
                nlohmann_json_j["children"].push_back(jsonTemp);
            }
        }
    
        friend void from_json(const nlohmann::json& nlohmann_json_j, TreeNode& nlohmann_json_t)
        {
            nlohmann_json_t.id = nlohmann_json_j.at("id");
            nlohmann_json_t.name = nlohmann_json_j.at("name");
            nlohmann::json arrayTemp =  nlohmann::json::array();
            arrayTemp = nlohmann_json_j.at("children");
    
            for (nlohmann::json& el : arrayTemp) {
                TreeNodePtr treeNode(new TreeNode());
                from_json(el, *treeNode);
                nlohmann_json_t.children.push_back(treeNode);
            }
        }
    };
    

    测试代码

    
    int main() {
        std::cout << "Hello, World!" << std::endl;
    
        TreeNodePtr treeNode(new TreeNode());
        treeNode->name = "node1";
        TreeNodePtr treeNode2(new TreeNode());
        treeNode2->name = "node2";
        TreeNodePtr treeNode3(new TreeNode());
        treeNode3->name = "node3";
    
        treeNode->children.push_back(treeNode2);
        treeNode2->children.push_back(treeNode3);
    
        ShaJson json = *treeNode;
    
        std::cout << json.dump(4) << std::endl;
    
        json = ShaJson::parse(json.dump());
    
        TreeNodePtr temp(new TreeNode());
    
        *temp = json.get<TreeNode>();
    
        std::cout << json.dump(4) << std::endl;
    
        return 0;
    }
    

    智能指针支持

    FuncInfo.hpp

    实体类

    class FuncInfo {
    public:
        std::string funcId;
        std::string funcName;
        std::string parentId;
    };
    
    using FuncInfoPtr = std::shared_ptr<FuncInfo>;
    

    FuncTreeNode.hpp

    
    class FuncTreeNode;
    
    using FuncTreeNodePtr = std::shared_ptr<FuncTreeNode>;
    
    class FuncTreeNode {
    public:
        std::string funcId;
        std::string funcName;
        std::string parentId;
        std::vector<FuncTreeNodePtr> childFuncs;
    
        static FuncTreeNodePtr createTree(std::vector<FuncInfoPtr> &funcInfos, FuncTreeNodePtr root){
            std::vector<FuncTreeNodePtr> children;
    
            for(FuncInfoPtr x : funcInfos){
                if(x->parentId == root->funcId){
                    children.push_back(createTree(funcInfos, x));
                }
            }
    
            root->childFuncs = children;
    
            return root;
        }
    
        static std::vector<FuncTreeNodePtr> createForest(std::vector<FuncInfoPtr> funcInfos) {
            // 存放多个根节点
            std::vector<FuncTreeNodePtr> rootList;
    
            // 找到根节点,并放到rootList中
            for (int i = 0; i < funcInfos.size(); i++) {
                bool hasParent = false;
                for (int j = 0; j < funcInfos.size(); j++) {
                    if (funcInfos[i]->parentId == funcInfos[j]->funcId) {
                        hasParent = true;
                        break;
                    }
                }
                if (hasParent == false) {
                    FuncTreeNodePtr root(new FuncTreeNode());
                    root->funcId = funcInfos[i]->funcId;
                    root->parentId = funcInfos[i]->parentId;
                    root->funcName = funcInfos[i]->funcName;
    
                    rootList.push_back(root);
                }
            }
    
            // 从每个根节点开始构建树
            for(FuncTreeNodePtr root : rootList){
                createTree(funcInfos, root);
            }
    
            return rootList;
        }
    
        // 序列化
        friend void to_json(nlohmann::json& nlohmann_json_j, const FuncTreeNode& nlohmann_json_t)
        {
            nlohmann_json_j["funcId"] = nlohmann_json_t.funcId;
            nlohmann_json_j["funcName"] = nlohmann_json_t.funcName;
            nlohmann_json_j["childFuncs"] = nlohmann::json::array();
    
            for(FuncTreeNodePtr x : nlohmann_json_t.childFuncs)
            {
                nlohmann::json jsonTemp;
    
                to_json(jsonTemp, *x);
    
                nlohmann_json_j["childFuncs"].push_back(jsonTemp);
            }
        }
    
        friend void from_json(const nlohmann::json& nlohmann_json_j, FuncTreeNode& nlohmann_json_t)
        {
            nlohmann_json_t.funcId = nlohmann_json_j.at("funcId");
            nlohmann_json_t.funcName = nlohmann_json_j.at("funcName");
            nlohmann::json arrayTemp =  nlohmann::json::array();
            arrayTemp = nlohmann_json_j.at("childFuncs");
    
            for (nlohmann::json& el : arrayTemp) {
                FuncTreeNodePtr treeNode(new FuncTreeNode());
                from_json(el, *treeNode);
                nlohmann_json_t.childFuncs.push_back(treeNode);
            }
        }
    
        // 智能指针版本
        friend void to_json(nlohmann::json& nlohmann_json_j, const FuncTreeNodePtr nlohmann_json_t)
        {
            nlohmann_json_j["funcId"] = nlohmann_json_t->funcId;
            nlohmann_json_j["funcName"] = nlohmann_json_t->funcName;
            nlohmann_json_j["childFuncs"] = nlohmann::json::array();
    
            for(FuncTreeNodePtr x : nlohmann_json_t->childFuncs)
            {
                nlohmann::json jsonTemp;
    
                to_json(jsonTemp, *x);
    
                nlohmann_json_j["childFuncs"].push_back(jsonTemp);
            }
        }
    
        friend void from_json(const nlohmann::json& nlohmann_json_j, FuncTreeNodePtr nlohmann_json_t)
        {
            nlohmann_json_t->funcId = nlohmann_json_j.at("funcId");
            nlohmann_json_t->funcName = nlohmann_json_j.at("funcName");
            nlohmann::json arrayTemp =  nlohmann::json::array();
            arrayTemp = nlohmann_json_j.at("childFuncs");
    
            for (nlohmann::json& el : arrayTemp) {
                FuncTreeNodePtr treeNode(new FuncTreeNode());
                from_json(el, *treeNode);
                nlohmann_json_t->childFuncs.push_back(treeNode);
            }
        }
    };
    

    测试代码

    森林

    int main() {
        std::cout << "Hello, World!" << std::endl;
    
        //StringUtils::test20220925();
        FuncTreeNodePtr ptr1(new FuncTreeNode());
        ptr1->funcName = "node1";
        FuncTreeNodePtr ptr2(new FuncTreeNode());
        ptr2->funcName = "node2";
        FuncTreeNodePtr ptr3(new FuncTreeNode());
        ptr3->funcName = "node3";
    
        ptr1->childFuncs.push_back(ptr2);
        ptr2->childFuncs.push_back(ptr3);
    
        ShaJson json = *ptr1;
    
        //std::cout << json.dump() << std::endl;
    
        std::vector<FuncInfoPtr> funcInfos;
        FuncInfoPtr funcInfoPtr1(new FuncInfo());
        funcInfoPtr1->funcId = "1";
        funcInfoPtr1->parentId = "-1";
        FuncInfoPtr funcInfoPtr2(new FuncInfo());
        funcInfoPtr2->funcId = "2";
        funcInfoPtr2->parentId = "-1";
        FuncInfoPtr funcInfoPtr3(new FuncInfo());
        funcInfoPtr3->funcId = "3";
        funcInfoPtr3->parentId = "2";
        FuncInfoPtr funcInfoPtr4(new FuncInfo());
        funcInfoPtr4->funcId = "4";
        funcInfoPtr4->parentId = "3";
    
        funcInfos.push_back(funcInfoPtr1);
        funcInfos.push_back(funcInfoPtr2);
        funcInfos.push_back(funcInfoPtr3);
        funcInfos.push_back(funcInfoPtr4);
    
        std::vector<FuncTreeNodePtr> forest = FuncTreeNode::createForest(funcInfos);
    
        std::string str;
        str += "[";
    
        for(FuncTreeNodePtr x : forest)
        {
            ShaJson jsonOut = *x;
            str += jsonOut.dump();
            str += ",";
        }
    
        str += "]";
    
        std::cout << str << std::endl;
    
        ShaJson jsonx = forest;
    
        std::cout << jsonx.dump() << std::endl;
    
        return 0;
    }
    

    输出
    Hello, World!
    [{“childFuncs”:[],“funcId”:“1”,“funcName”:“”},{“childFuncs”:[{“childFuncs”:[{“childFuncs”:[],“funcId”:“4”,“funcName”:“”}
    ],“funcId”:“3”,“funcName”:“”}],“funcId”:“2”,“funcName”:“”},]
    [{“childFuncs”:[],“funcId”:“1”,“funcName”:“”},{“childFuncs”:[{“childFuncs”:[{“childFuncs”:[],“funcId”:“4”,“funcName”:“”}
    ],“funcId”:“3”,“funcName”:“”}],“funcId”:“2”,“funcName”:“”}]

    json结构

    [
        {
            "childFuncs":[
    
            ],
            "funcId":"1",
            "funcName":""
        },
        {
            "childFuncs":[
                {
                    "childFuncs":[
                        {
                            "childFuncs":[
    
                            ],
                            "funcId":"4",
                            "funcName":""
                        }
                    ],
                    "funcId":"3",
                    "funcName":""
                }
            ],
            "funcId":"2",
            "funcName":""
        }
    ]
    
  • 相关阅读:
    JVM调优-GC基本原理和调优关键分析
    win10安装配置ssh服务
    大规模Session-based 数据转化为邻接矩阵
    阿里云/腾讯云/华为云国际版实名账号:亚太已发展超2500个本地生态伙伴 超50%收入由伙伴创造
    [附源码]计算机毕业设计springboot家庭整理服务管理系统
    【数学建模】基于matlab GUI Smith画圆软件设计与演示【含Matlab源码 2195期】
    计算机毕业设计SSM成绩管理与学情分析系统【附源码数据库】
    golang pg数据库操作,insert(sql)插入一条数据后获返回当前插入数据的id --chatGPT
    SQL 专项笔记
    为什么你买店铺管理软件总是踩雷?实测市面上十几个店铺管理软件,才总结出这三个大坑,行家也难逃过!
  • 原文地址:https://blog.csdn.net/weixin_42274148/article/details/127039499