【C#】实现Json转Lua (Json2Lua)

news2024/12/23 22:23:19

关键词: C#、JsonToLua、Json2Lua、对象序列化Lua

前提需引入NewtonsofJson,引入方法可先在Visual Studio 2019

将Newtonsoft.Json.dll文件导入Unity的Plugins下。
Json格式字符串转Lua格式字符串,效果如下:

json字符串

{
	"1": "asd",
	"2": true,
	"3": 1.5,
	"4": 123,
	"a": {
		"b": "c",
		"d": [1, 2, 3]
	}
}

lua字符串 (.lua文件一般直接return {}表 故会加上 "return " 如果不需要可以自行修改代码。)

return {
	[1] = "asd",
	[2] = true,
	[3] = 1.5,
	[4] = 123,
	a = {
		b = "c",
		d = { 1, 2, 3 }
	}
}

 使用方法:

string json = "{\"1\":\"asd\",\"2\":true,\"3\":1.5,\"4\":123,\"a\":{\"b\":\"c\",\"d\":[1,2,3]}}";
string lua = Milk.Json.MilkJsonUtility.Json2Lua(json, true);

类说明:

LuaObject:封装Json基础类型对象,核心GetString方法返回对象的字符串形式。
LuaTable:封装JsonArray或JsonObject类型对象,主要是将数组或对象内的成员封装为LuaObject存储起来,数组存储于list,对象成员存储于map,核心GetString方法返回表的字符串形式。
LuaTable类静态方法:public static LuaTable CreateFromJson(string json)
        由该方法进行转化json为lua,使用JObject.Parse(json)转为Json对象,后经过判断是数组还是对象类型进行使用不同函数转化(JsonArray2LuaTable、JsonObject2LuaTable)
JsonArray2LuaTable:将Json数组成员一一转化为LuaTable
JsonObject2LuaTable:将Json对象成员一一转化为LuaTable

namespace Milk.Json
{
    public static class MilkJsonUtility
    {
        /// <summary>
        /// 将Json格式字符串转成Lua表形式字符串
        /// </summary>
        /// <param name="json"></param>
        /// <param name="indented">是否缩进</param>
        /// <returns></returns>
        public static string Json2Lua(string json, bool indented = false)
        {
            var table = LuaTable.CreateFromJson(json);
            return $"return {table.GetString(indented)}";
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace Milk.Json
{
    public enum LuaValueType
    {
        Table,
        String,
        Num,
        Boolean,
        nil
    }
}
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json.Linq;

namespace Milk.Json
{
    public class LuaTable
    {
        //存放table中的有序部分
        private List<LuaObject> list = new List<LuaObject>();

        //存放table中的无序部分
        private Dictionary<string, LuaObject> map = new Dictionary<string, LuaObject>();

        //所在层级
        private int layer = 0;

        public LuaTable(int _layer)
        {
            layer = _layer + 1;
        }

        #region 有序数组添加

        /// <summary>
        /// [有序]添加string value
        /// </summary>
        /// <param name="value"></param>
        public void AddItem(string value)
        {
            list.Add(new LuaObject(value));
        }

        /// <summary>
        /// [有序]num value
        /// </summary>
        /// <param name="value"></param>
        public void AddItem(int value)
        {
            list.Add(new LuaObject(value));
        }

        /// <summary>
        /// [有序]num value
        /// </summary>
        /// <param name="value"></param>
        public void AddItem(float value)
        {
            list.Add(new LuaObject(value));
        }

        /// <summary>
        /// [有序]bool value
        /// </summary>
        /// <param name="value"></param>
        public void AddItem(bool value)
        {
            list.Add(new LuaObject(value));
        }

        public void AddItem(LuaTable value)
        {
            list.Add(new LuaObject(value));
        }

        /// <summary>
        /// 加入nil
        /// </summary>
        public void AddItemNil()
        {
            list.Add(new LuaObject());
        }

        #endregion


        #region Key_Value添加

        public void AddItem(string key, string value)
        {
            //查重
            if (!map.ContainsKey(key))
            {
                map.Add(key, new LuaObject(value));
            }
        }

        public void AddItem(string key, int value)
        {
            //查重
            if (!map.ContainsKey(key))
            {
                map.Add(key, new LuaObject(value));
            }
        }

        public void AddItem(string key, float value)
        {
            //查重
            if (!map.ContainsKey(key))
            {
                map.Add(key, new LuaObject(value));
            }
        }

        public void AddItem(string key, bool value)
        {
            //查重
            if (!map.ContainsKey(key))
            {
                map.Add(key, new LuaObject(value));
            }
        }

        public void AddItem(string key, LuaTable value)
        {
            //查重
            if (!map.ContainsKey(key))
            {
                map.Add(key, new LuaObject(value));
            }
        }

        public void AddItemNil(string key)
        {
            //查重
            if (!map.ContainsKey(key))
            {
                map.Add(key, new LuaObject());
            }
        }

        #endregion

        private bool IsNumeric(string str)
        {
            int number;
            return int.TryParse(str, out number);
        }

        private string IndentedLayer(string str, bool indented, int change = 0)
        {
            if (indented)
            {
                for (int i = 0; i < layer + change; i++)
                {
                    str = "\t" + str;
                }
            }
            return str;
        }

        public string GetString(bool indented = false)
        {
            string str = "{";
            bool hasList = list.Count > 0;
            bool hasMap = map.Count > 0;
            bool isNeedIndented = false;
            if (indented && (hasList || hasMap))
            {
                isNeedIndented = true;
                if (hasList)
                {
                    LuaValueType type = list[0].GetLuaValueType();
                    if (type == LuaValueType.Boolean || type == LuaValueType.Num)
                    {
                        isNeedIndented = false;
                    }
                }
                if (isNeedIndented)
                    str += "\n";
            }
            if (hasList)
            {
                int count = 0;
                foreach (var item in list)
                {
                    count++;
                    if (!isNeedIndented)
                    {
                        if (indented && count == 1)
                            str += " ";
                        str += item.GetString(indented);
                        if (count < list.Count)
                            str += ",";
                        if (indented)
                            str += " ";
                    }
                    else
                    {
                        str += IndentedLayer(item.GetString(indented), indented);
                        if (count < list.Count)
                            str += ",";
                        if (indented)
                            str += "\n";
                    }
                }
            }

            if (hasMap)
            {
                int count = 0;
                foreach (var item in map)
                {
                    count++;
                    var key = item.Key.Replace('$', '_');
                    if (IsNumeric(key))
                    {
                        key = $"[{key}]";
                    }
                    if (indented)
                        str += IndentedLayer($"{key} = {item.Value.GetString(indented)}", indented);
                    else
                        str += IndentedLayer($"{key}={item.Value.GetString(indented)}", indented);
                    if (count < map.Count)
                        str += ",";
                    if (indented)
                        str += "\n";
                }
            }

            if (!isNeedIndented)
            {
                str += "}";
            }
            else
            {
                str += IndentedLayer("}", indented, -1);
            }

            return str;
        }

        public static LuaTable CreateFromJson(string json)
        {
            var jsonObject = JObject.Parse(json);
            if (jsonObject.Type == JTokenType.Array)
            {
                return JsonArray2LuaTable(jsonObject.ToObject<JArray>(), 0);
            }
            else
            {
                return JsonObject2LuaTable(jsonObject, 0);
            }
        }

        /// <summary>
        /// 递归方法
        /// </summary>
        static LuaTable JsonObject2LuaTable(JObject jsonObj, int layer)
        {
            var curLuaTable = new LuaTable(layer);

            //构建无序Table(lua表 key-value形式)
            foreach (var item in jsonObj)
            {
                switch (item.Value.Type)
                {
                    case JTokenType.Boolean:
                        curLuaTable.AddItem(item.Key, (bool)item.Value);
                        break;
                    case JTokenType.Array:
                        curLuaTable.AddItem(item.Key, JsonArray2LuaTable(item.Value.ToObject<JArray>(), layer + 1));
                        break;
                    case JTokenType.String:
                        curLuaTable.AddItem(item.Key, (string)item.Value);
                        break;
                    case JTokenType.Date: //转成string
                        curLuaTable.AddItem(item.Key, (string)item.Value);
                        break;
                    case JTokenType.Float:
                        curLuaTable.AddItem(item.Key, (float)item.Value);
                        break;
                    case JTokenType.Integer:
                        curLuaTable.AddItem(item.Key, (int)item.Value);
                        break;
                    case JTokenType.None:
                        curLuaTable.AddItemNil(item.Key);
                        break;
                    case JTokenType.Null:
                        curLuaTable.AddItemNil(item.Key);
                        break;
                    case JTokenType.Object:
                        curLuaTable.AddItem(item.Key, JsonObject2LuaTable(item.Value.ToObject<JObject>(), layer + 1));
                        break;
                    case JTokenType.TimeSpan:
                        curLuaTable.AddItem(item.Key, (float)item.Value);
                        break;
                }
            }

            return curLuaTable;
        }

        static LuaTable JsonArray2LuaTable(JArray jsonArray, int layer)
        {
            var curLuaTable = new LuaTable(layer);
            //构建有序Table(lua表)
            foreach (var item in jsonArray)
            {
                //检查子项类型
                switch (item.Type)
                {
                    case JTokenType.Boolean:
                        curLuaTable.AddItem((bool)item);
                        break;
                    case JTokenType.Array:
                        curLuaTable.AddItem(JsonArray2LuaTable(item.ToObject<JArray>(), layer + 1));
                        break;
                    case JTokenType.String:
                        curLuaTable.AddItem((string)item);
                        break;
                    case JTokenType.Object:
                        curLuaTable.AddItem(JsonObject2LuaTable(item.ToObject<JObject>(), layer + 1));
                        break;
                    case JTokenType.Date:
                        curLuaTable.AddItem((string)item);
                        break;
                    case JTokenType.Float:
                        curLuaTable.AddItem((float)item);
                        break;
                    case JTokenType.Integer:
                        curLuaTable.AddItem((int)item);
                        break;
                    case JTokenType.None:
                        curLuaTable.AddItemNil();
                        break;
                    case JTokenType.Null:
                        curLuaTable.AddItemNil();
                        break;
                    case JTokenType.TimeSpan:
                        curLuaTable.AddItem((float)item);
                        break;
                }
            }

            return curLuaTable;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace Milk.Json
{
    public class LuaObject
    {
        private LuaValueType type;

        private float valueNumber;
        private string valueString;
        private bool valueBoolean;
        private LuaTable valueTable;

        public LuaObject(string value)
        {
            type = LuaValueType.String;
            valueString = value;
        }

        public LuaObject(float value)
        {
            type = LuaValueType.Num;
            valueNumber = value;
        }

        public LuaObject(int value)
        {
            type = LuaValueType.Num;
            valueNumber = value;
        }

        public LuaObject(bool value)
        {
            type = LuaValueType.Boolean;
            valueBoolean = value;
        }

        public LuaObject(LuaTable value)
        {
            type = LuaValueType.Table;
            valueTable = value;
        }

        public LuaObject()
        {
            type = LuaValueType.nil;
        }

        public string GetString(bool indented = false)
        {
            switch (type)
            {
                case LuaValueType.Table:
                    return valueTable.GetString(indented);
                //break;
                case LuaValueType.Boolean:
                    if (valueBoolean)
                    {
                        return "true";
                    }
                    else
                    {
                        return "false";
                    }
                //break;
                case LuaValueType.Num:
                    return valueNumber.ToString();
                //break;
                case LuaValueType.String:
                    return "\""+ valueString+"\"";
                case LuaValueType.nil:
                    return "nil";
                default:
                    return "";
            }
        }

        public LuaValueType GetLuaValueType()
        {
            return type;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2264432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GM_T 0039《密码模块安全检测要求》题目

单项选择题 根据GM/T 0039《密码模块安全检测要求》,送检单位的密码模块应包括()密码主管角色。 A.一个 B.两个 C.至少一个 D.至少两个 正确答案:C 多项选择题 根据GM/T 0039《密码模块安全检测要求》,关于非入侵式安全,以下属于安全三级密码模块要求的是()。 …

在 Ubuntu 上安装 Muduo 网络库的详细指南

在 Ubuntu 上安装 Muduo 网络库的详细指南 首先一份好的安装教程是非常重要的 C muduo网络库知识分享01 - Linux平台下muduo网络库源码编译安装-CSDN博客 像这篇文章就和shit一样&#xff0c;安装到2%一定会卡住&#xff0c;如果你不幸用了这个那真是遭老罪了 环境&#xf…

MySQL存储引擎-数据文件

InnoDB数据文件存储结构 分为一个ibd数据文件–>Segment&#xff08;段&#xff09;–>Extent&#xff08;区&#xff09;–>Page&#xff08;页&#xff09;–>Row&#xff08;行&#xff09; Tablesapce 表空间&#xff0c;用于存储多个ibd数据文件&#xff…

医药垃圾分类管理系统|Java|SSM|JSP|

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html 5⃣️数据库可…

深度学习之目标检测篇——残差网络与FPN结合

特征金字塔多尺度融合特征金字塔的网络原理 这里是基于resnet网络与Fpn做的结合&#xff0c;主要把resnet中的特征层利用FPN的思想一起结合&#xff0c;实现resnet_fpn。增强目标检测backone的有效性。代码实现如下&#xff1a; import torch from torch import Tensor from c…

多协议视频监控汇聚/视频安防系统Liveweb搭建智慧园区视频管理平台

智慧园区作为现代化城市发展的重要组成部分&#xff0c;不仅承载着产业升级的使命&#xff0c;更是智慧城市建设的重要体现。随着产业园区竞争的逐渐白热化&#xff0c;将项目打造成完善的智慧园区是越来越多用户关注的内容。 然而我们往往在规划前期就开始面临众多难题&#…

【WPF】把DockPanel的内容生成图像

要在WPF中将一个 DockPanel 的内容生成为图像并保存&#xff0c;可以按照与之前类似的步骤进行&#xff0c;但这次我们将专注于 DockPanel 控件而不是整个窗口。 DockPanel的使用 WPF&#xff08;Windows Presentation Foundation&#xff09;中的 DockPanel 是一种布局控件&…

【电商推荐】平衡效率与效果:一种优化点击率预测的LLM融合方法

【电商推荐】平衡效率与效果&#xff1a;一种优化点击率预测的LLM融合方法 目录 文章目录 【电商推荐】平衡效率与效果&#xff1a;一种优化点击率预测的LLM融合方法目录文章摘要研究背景问题与挑战如何解决创新点算法模型多级知识蒸馏模块&#xff08;MKDM&#xff09;多级知识…

Y3编辑器教程6:触发器进阶案例

文章目录 一、地形制作1.1 地形制作流程1.2 关卡白盒1.3 场景美化1.4 优化场景 二、触发结构三、玩家指引&#xff08;函数封装&#xff09;3.1 项目拆解3.2 功能实现3.2.1 绘制UI界面3.2.2 UI的读取显示和刷新3.2.3 交互功能3.2.4 最终实现 四、NPC对话系统4.1 项目拆解4.2 UI…

2024年11月 蓝桥杯青少组 STEMA考试 Scratch真题

2024年11月 蓝桥杯青少组 STEMA考试 Scratch真题&#xff08;选择题&#xff09; 题目总数&#xff1a;5 总分数&#xff1a;50 选择题 第 1 题 单选题 Scratch运行以下程宇后&#xff0c;小兔子会&#xff08; &#xff09;。 A. 变小 B. 变大 C. 变色 D. …

ZED-OpenCV项目运行记录

项目地址&#xff1a;GitCode - 全球开发者的开源社区,开源代码托管平台 使用 ZED 立体相机与 OpenCV 进行图像处理和深度感知 • 使用 ZED 相机和 OpenCV 库捕获图像、深度图和点云。 • 提供保存并排图像、深度图和点云的功能。 • 允许在不同格式之间切换保存的深度图和点云…

Nacos 3.0 考虑升级到 Spring Boot 3 + JDK 17 了!

Nacos 由阿里开源&#xff0c;是 Spring Cloud Alibaba 中的一个重要组件&#xff0c;主要用于发现、配置和管理微服务。 由于 Spring Boot 2 的维护已于近期停止&#xff0c;Nacos 团队考虑升级到 Spring Boot 3 JDK 17&#xff0c;目前正在征求意见和建议。 这其实是一件好…

(css)鼠标移入或点击改变背景图片

(css)鼠标移入或点击改变背景图片 html <div class"mapTip"><divv-for"(item, index) of legendList":key"index"class"mapTipOne":class"{ active: change index }"click"legendHandle(item, index)"…

Grad-CAM-模型可视化分析方法

模型的可视化分析对于理解模型的行为有很好的辅助作用&#xff0c;能够让人们更容易理解神经网络的决策过程。 Grad-CAM&#xff08;Gradient-weighted Class Activation Mapping&#xff09;是一种用于解释卷积神经网络&#xff08;CNN&#xff09;决策过程的方法&#xff0c;…

常见八股文03

35.autowired、qualifier和Resource区别 Autowired&#xff1a;基于类型的注入 Qualifier&#xff1a;基于名称进行注入 Resource:按名称装配注入&#xff0c;如果找不到与名称匹配的bean&#xff0c;则按类型装配注入&#xff0c;可以用于字段和方法上 36.代理模式 动态代…

Pytorch | 利用NI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用NI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集NI-FGSM介绍背景算法流程 NI-FGSM代码实现NI-FGSM算法实现攻击效果 代码汇总nifgsm.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器&#xff1a; Pytorch | 从零构建AlexNet对CIFAR10进行…

redis开发与运维-redis02-redis数据类型与命令总结

文章目录 【README】【1】redis通用命令与数据结构【1.1】通用命令【1.2】数据结构与内部编码【1.3】redis单线程架构【1.3.1】redis单线程优缺点 【2】字符串&#xff08;值的类型为字符串&#xff09;【2.1】常用命令【2.1.1】设置值【2.1.2】获取值【2.1.3】批量设置值【2.1…

机器学习《西瓜书》学习笔记《待续》

如果说&#xff0c;计算机科学是研究关于“算法”的学问&#xff0c;那么机器学习就是研究关于“学习算法”的学问。 目录 绪论引言基本术语 扩展向量的张成-span使用Markdown语法编写数学公式希腊字母的LaTex语法插入一些数学的结构插入定界符插入一些可变大小的符号插入一些函…

电脑开机提示error loading operating system怎么修复?

前一天电脑还能正常运行&#xff0c;但今天启动时却显示“Error loading operating system”&#xff08;加载操作系统错误&#xff09;。我已经仔细检查了硬盘、接线、内存、CPU和电源&#xff0c;确认这些硬件都没有问题。硬盘在其他电脑上可以正常使用&#xff0c;说明不是硬…

git企业开发的相关理论(一)

目录 一.初识git 二.git的安装 三.初始化/创建本地仓库 四.配置用户设置/配置本地仓库 五.认识工作区、暂存区、版本库 六.添加文件__场景一 七.查看 .git 文件/添加到本地仓库后.git中发生的变化 1.执行git add后的变化 index文件&#xff08;暂存区&#xff09; lo…