如何在 Qt 中合并两个 QJsonObjects?
How to merge two QJsonObjects in Qt?
我有:
QJsonObject obj1({"bla" : "lab"})
QJsonObject obj2({"bla2" : "lab2"})
我需要:
QJsonObject obj3({"bla" : "lab", "bla2" : "lab2"})
或在JSON中:
{
"bla" : "lab"
}
{
"bla2" : "lab2"
}
我需要:
{
"bla" : "lab",
"bla2" : "lab2"
}
如何实现?
QJsonObject obj3(obj1);
for (auto it = obj2.constBegin(); it != obj2.constEnd(); it++) {
obj3.insert(it.key(), it.value());
}
您可以遍历所有需要合并的 json,然后遍历它们的元素并将它们插入新的 json:
QJsonObject obj1({{"bla1", "lab1"}});
QJsonObject obj2({{"bla2", "lab2"}});
QJsonObject obj34({{"bla3", "lab3"}, {"bla4", "lab4"}});
QJsonObject result;
for (const auto& json : {obj1, obj2, obj34})
{
for (auto it = json.begin(); it != json.end(); it++)
{
result.insert(it.key(), it.value());
}
}
for (auto it = result.begin(); it != result.end(); it++)
{
qDebug() << it.key() << ": " << it.value();
}
不过可能不是最有效的。
解决方案
我更喜欢避免显式循环,所以我的解决方案是使用转换 to 和 from QVariantMap
,又名 QMap<QString, QVariant>
:
使用QJsonObject::toVariantMap
将所有JSON对象转换为QVariantMap
使用QMap::insert
将所有地图插入一个
使用QJsonObject::fromVariantMap
将生成的地图转换回JSON对象
注意: 如果所有 JSON 对象都包含唯一键,建议的解决方案将最有效,因为 documentation 状态:
If map contains multiple entries with the same key then the final value of the key is undefined.
例子
这是我为您准备的一个简单示例,用于演示如何实施建议的解决方案:
QJsonObject json1{{"foo_key", "foo_value"}};
QJsonObject json2{{"moo_key", "moo_value"}, {"boo_key", "boo_value"}};
QVariantMap map = json1.toVariantMap();
map.insert(json2.toVariantMap());
qDebug() << QJsonObject::fromVariantMap(map);
结果
此示例产生以下结果:
QJsonObject({"boo_key":"boo_value","foo_key":"foo_value","moo_key":"moo_value"})
扩展版本,它还合并同名对象并添加数组元素(如果两个对象中存在同名):
void mergeJson(QJsonObject& src, const QJsonObject& other)
{
for(auto it = other.constBegin(); it != other.constEnd(); ++it)
{
if(src.contains(it.key()))
{
if(src.value(it.key()).isObject() && other.value(it.key()).isObject())
{
QJsonObject one(src.value(it.key()).toObject());
QJsonObject two(other.value(it.key()).toObject());
mergeJson(one, two);
src[it.key()] = one;
}
else if(src.value(it.key()).isArray() && other.value(it.key()).isArray())
{
QJsonArray arr = other.value(it.key()).toArray();
QJsonArray srcArr = src.value(it.key()).toArray();
for(int i = 0; i < arr.size(); i++)
srcArr.append(arr[i]);
src[it.key()] = srcArr;
}
}
else
src[it.key()] = it.value();
}
}
如果src
和other
有同名字段(数组和对象除外,见顶部),将使用src。
来源:
{
"arr":[
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
}
],
"fieldOne":"dqwd",
"fieldTwo":"dqwd2",
"two":{
"fieldOne":"dwqwfw",
"fieldTwo":"grew",
"fregtegergwedffe":{
"sdqqwd":"wdqfrg"
}
}
}
其他:
{
"arr":[
{
"fieldOne":"dwqwfw",
"fieldTwo":"kjhgf",
"qwdqwd":"grew"
}
],
"fieldOne":"rfgwef",
"grege":"gfewrfew",
"grwefege":"fewfgrew",
"two":{
"fieldOne":"dwqwfw",
"fieldTwo":"kjhgf",
"qwdqwd":"grew"
}
}
merged/src 调用后:
{
"arr":[
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dwqwfw",
"fieldTwo":"kjhgf",
"qwdqwd":"grew"
}
],
"fieldOne":"dqwd",
"fieldTwo":"dqwd2",
"grege":"gfewrfew",
"grwefege":"fewfgrew",
"two":{
"fieldOne":"dwqwfw",
"fieldTwo":"grew",
"fregtegergwedffe":{
"sdqqwd":"wdqfrg"
},
"qwdqwd":"grew"
}
}
我有:
QJsonObject obj1({"bla" : "lab"})
QJsonObject obj2({"bla2" : "lab2"})
我需要:
QJsonObject obj3({"bla" : "lab", "bla2" : "lab2"})
或在JSON中:
{
"bla" : "lab"
}
{
"bla2" : "lab2"
}
我需要:
{
"bla" : "lab",
"bla2" : "lab2"
}
如何实现?
QJsonObject obj3(obj1);
for (auto it = obj2.constBegin(); it != obj2.constEnd(); it++) {
obj3.insert(it.key(), it.value());
}
您可以遍历所有需要合并的 json,然后遍历它们的元素并将它们插入新的 json:
QJsonObject obj1({{"bla1", "lab1"}});
QJsonObject obj2({{"bla2", "lab2"}});
QJsonObject obj34({{"bla3", "lab3"}, {"bla4", "lab4"}});
QJsonObject result;
for (const auto& json : {obj1, obj2, obj34})
{
for (auto it = json.begin(); it != json.end(); it++)
{
result.insert(it.key(), it.value());
}
}
for (auto it = result.begin(); it != result.end(); it++)
{
qDebug() << it.key() << ": " << it.value();
}
不过可能不是最有效的。
解决方案
我更喜欢避免显式循环,所以我的解决方案是使用转换 to 和 from QVariantMap
,又名 QMap<QString, QVariant>
:
使用
QJsonObject::toVariantMap
将所有JSON对象转换为QVariantMap
使用
QMap::insert
将所有地图插入一个使用
QJsonObject::fromVariantMap
将生成的地图转换回JSON对象
注意: 如果所有 JSON 对象都包含唯一键,建议的解决方案将最有效,因为 documentation 状态:
If map contains multiple entries with the same key then the final value of the key is undefined.
例子
这是我为您准备的一个简单示例,用于演示如何实施建议的解决方案:
QJsonObject json1{{"foo_key", "foo_value"}};
QJsonObject json2{{"moo_key", "moo_value"}, {"boo_key", "boo_value"}};
QVariantMap map = json1.toVariantMap();
map.insert(json2.toVariantMap());
qDebug() << QJsonObject::fromVariantMap(map);
结果
此示例产生以下结果:
QJsonObject({"boo_key":"boo_value","foo_key":"foo_value","moo_key":"moo_value"})
扩展版本,它还合并同名对象并添加数组元素(如果两个对象中存在同名):
void mergeJson(QJsonObject& src, const QJsonObject& other)
{
for(auto it = other.constBegin(); it != other.constEnd(); ++it)
{
if(src.contains(it.key()))
{
if(src.value(it.key()).isObject() && other.value(it.key()).isObject())
{
QJsonObject one(src.value(it.key()).toObject());
QJsonObject two(other.value(it.key()).toObject());
mergeJson(one, two);
src[it.key()] = one;
}
else if(src.value(it.key()).isArray() && other.value(it.key()).isArray())
{
QJsonArray arr = other.value(it.key()).toArray();
QJsonArray srcArr = src.value(it.key()).toArray();
for(int i = 0; i < arr.size(); i++)
srcArr.append(arr[i]);
src[it.key()] = srcArr;
}
}
else
src[it.key()] = it.value();
}
}
如果src
和other
有同名字段(数组和对象除外,见顶部),将使用src。
来源:
{
"arr":[
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
}
],
"fieldOne":"dqwd",
"fieldTwo":"dqwd2",
"two":{
"fieldOne":"dwqwfw",
"fieldTwo":"grew",
"fregtegergwedffe":{
"sdqqwd":"wdqfrg"
}
}
}
其他:
{
"arr":[
{
"fieldOne":"dwqwfw",
"fieldTwo":"kjhgf",
"qwdqwd":"grew"
}
],
"fieldOne":"rfgwef",
"grege":"gfewrfew",
"grwefege":"fewfgrew",
"two":{
"fieldOne":"dwqwfw",
"fieldTwo":"kjhgf",
"qwdqwd":"grew"
}
}
merged/src 调用后:
{
"arr":[
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dqwd",
"fieldTwo":"dqwd2"
},
{
"fieldOne":"dwqwfw",
"fieldTwo":"kjhgf",
"qwdqwd":"grew"
}
],
"fieldOne":"dqwd",
"fieldTwo":"dqwd2",
"grege":"gfewrfew",
"grwefege":"fewfgrew",
"two":{
"fieldOne":"dwqwfw",
"fieldTwo":"grew",
"fregtegergwedffe":{
"sdqqwd":"wdqfrg"
},
"qwdqwd":"grew"
}
}