使用NlohmannJson写JSON保留插入顺序
1. 正文
nlohmann/json是一个C++的读写JSON的组件,号称使用现代C++范式写的。简单看了一下,这个组件确实包含了很多cpp11以上的特性,在vs2015及一下的版本甚至没办法正常编译。要正常使用需要vs2017及以上版本才行。
在使用过程中,遇到了一个问题是没办法保持插入的顺序,每个插入的键值对会按照字符串的顺序排列的,因为其内部用到了std:map。查看了github的主页说明,是这么说的:
By default, the library does not preserve the insertion order of object elements. This is standards-compliant, as the JSON standard defines objects as "an unordered collection of zero or more name/value pairs". If you do want to preserve the insertion order, you can specialize the object type with containers like tsl::ordered_map (integration) or nlohmann::fifo_map (integration).
这段话的意思是JSON标准的定义是零个或多个键值对对的无序集合,如果要保证插入顺序,可以使用tsl::ordered_map(integration)或nlohmann::fifo_map(integration)等容器专门化对象类型。nlohmann::fifo_map同样在github上找到,“专门化对象类型”的意思是nlohmann/json组件内部用到了很多std容器,只需要将其替换成可以保存插入顺序的容器就可以了,也就是nlohmann::fifo_map。
重新找了一些英文资料,最终找到的解决方案如下:
#include "json.hpp"
#include "fifo_map.hpp"
#include <iostream>
using namespace nlohmann;
// A workaround to give to use fifo_map as map, we are just ignoring the 'less' compare
template<class K, class V, class dummy_compare, class A>
using my_workaround_fifo_map = fifo_map<K, V, fifo_map_compare<K>, A>;
using my_json = basic_json<my_workaround_fifo_map>;
int main()
{
my_json j;
j["f"] = 5;
j["a"] = 2;
my_json j2 = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {
{"everything", 42}
}},
{"list", {1, 0, 2}},
{"object", {
{"currency", "USD"},
{"value", 42.99}
}}
};
std::cout << j.dump(4) << std::endl;
std::cout << j2.dump(4) << std::endl;
return 0;
}
运行结果如下所示,可以看到输出的JSON不再是字符串顺序而是插入顺序:

2. 参考
[1] nlohmann/json主页介绍
[2] nlohmann/json关于保留插入顺序的讨论
使用NlohmannJson写JSON保留插入顺序的更多相关文章
- 如何保持json序列化的顺序性?
说到json,相信没有人会陌生,我们天天都在用.那么,我们来讨论个问题,json有序吗?是谁来决定的呢?如何保持? 说到底,json是框架还是啥?实际上它只是一个数据格式,一个规范标准,它永远不会限制 ...
- java中的TreeMap如何顺序按照插入顺序排序
java中的TreeMap如何顺序按照插入顺序排序 你可以使用LinkedHashMap 这个是可以记住插入顺序的. 用LinkedHashMap吧.它内部有一个链表,保持插入的顺序.迭代的时候,也 ...
- Unity的Json解析<二>–写Json文件
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/50378805 作者:car ...
- 2. 妈呀,Jackson原来是这样写JSON的
没有人永远18岁,但永远有人18岁.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众 ...
- JAVA写JSON的三种方法,java对象转json数据
JAVA写JSON的三种方法,java对象转json数据 转自:http://www.xdx97.com/#/single?bid=5afe2ff9-8cd1-67cf-e7bc-437b74c07a ...
- 从写json作业谈起
json的数据格式我经常见到,但是真正的写json的处理时,我又不会了,com.alibaba.fast.json. com.jackson.看了网上的博客,我可以写出简单java对象转换为json字 ...
- JavaScript 元素的插入顺序以及动态加载js
*****************记录下今天的心得***************** 1.元素的插入顺序 需求:异步从后台读取两个数据a和b,并动态加载到父容器x中,要求a必须在b的左边 实际情况:一 ...
- 3. 懂了这些,方敢在简历上说会用Jackson写JSON
你必须非常努力,才能看起来毫不费力.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众 ...
- python 解码json数据并在一个OrderdDict中保留其顺序
一般来讲,JSON 解码会根据提供的数据创建dicts 或lists.如果你想要创建其他类型的对象,可以给json.loads() 传递object_pairs_hook 或object_hook 参 ...
随机推荐
- springboot内置的定时任务简单使用
直接上图:搞定(一定要加@EnableScheduling(开启定时任务)这个注解@Component(让spring扫描到)),下面是每五秒执行一次 结果:
- Altium Designer中,将多个工程下的原理图和PCB合并在一起
TDD双向放大器的设计分为三部分:LNA部分.PA部分和控制开关部分.为了调试方便,已经在三个Altium工程里面分别设计了三部分.现在需要合并成一个板子,为了保留已有的布局布线的工作量,采用这个办法 ...
- nrm 源管理器
什么是nrm nrm 是一个 npm 源管理器,允许你快速地在 npm 源间切换. 安装nrm 在命令行执行命令,npm install -g nrm,全局安装nrm. 使用 执行命令nrm ls查看 ...
- swift4之String与NSString的区别与使用
String是结构体,NSString是类,这是它们的根本区别. 在 Swift 中,结构体struct是值类型,String是结构体,所以也是值类型.值类型被赋予给一个变量.常量或者被传递给一个函数 ...
- sdfsdsf
1 $('.advert-title').each(function(){ 2 var TXTlength = $(this).text().length; // 当前文本的长度 3 if(TXTle ...
- CMake查找第三方库路径
问题 一直都有一个问题,就是基于Windows下使用CMake构建VS工程时,CMake是如何查找到第三方库所在的路径的呢? 答案 今天重新想起这个问题,就拿构建Vtk的VS工程测试了一下, 才发现是 ...
- C# WinForm 自定义控件,DataGridView背景透明,TabControl背景透明
注意: 以下代码,属性直接赋值的语法糖要vs2015以上才支持. using System.ComponentModel; using System.Drawing; using System. ...
- 用sql删除数据库重复的数据的方法
/***********************************************两个意义上的重复记录:1.是完全重复的记录,也即所有字段均重复的记录,2.是部分关键字段重复的记录, ...
- (转)Dom4j中的中文编码问题
一.“中文问题没商量”之Dom4j中的编码问题 本文主要讲述的是Dom4j在把Document保存到文件过程中出现的一个中文问题,本文跟<80前>一文一样,以Spring项目无关,请“春 ...
- Windows编程常用api
转载网络 黑客常用WIN API函数整理 一.进程 创建进程: CreateProcess (,,,,,,,&si,&pi); WinExec("notepad", ...