【问题标题】:How to merge two QJsonObjects in Qt?如何在 Qt 中合并两个 QJsonObjects?
【发布时间】:2020-11-03 15:16:01
【问题描述】:

我有:

QJsonObject obj1({"bla" : "lab"})
QJsonObject obj2({"bla2" : "lab2"})

我需要:

QJsonObject obj3({"bla" : "lab", "bla2" : "lab2"})

或者在 JSON 中:

{
    "bla" : "lab"
}

{
    "bla2" : "lab2"
}

我需要:

{
    "bla" : "lab",
    "bla2" : "lab2"
}

如何实现?

【问题讨论】:

  • 需要递归合并吗?您是否尝试过遍历各个对象并将键值对插入obj3

标签: c++ qt qt5 qjsonobject


【解决方案1】:
QJsonObject obj3(obj1);
for (auto it = obj2.constBegin(); it != obj2.constEnd(); it++) {
    obj3.insert(it.key(), it.value());
}

【讨论】:

    【解决方案2】:

    解决方案

    我更喜欢避免显式循环,所以我的解决方案是使用转换 tofrom QVariantMap,又名QMap<QString, QVariant>

    1. 使用QJsonObject::toVariantMap将所有JSON对象转换为QVariantMap

    2. 使用QMap::insert 将所有地图插入一个

    3. 使用QJsonObject::fromVariantMap 将生成的映射转换回 JSON 对象

    注意:如果所有 JSON 对象都包含唯一键,则建议的解决方案效果最佳,因为documentation 声明:

    如果 map 包含具有相同键的多个条目,则键的最终值未定义。

    示例

    这是我为您准备的一个简单示例,用于演示如何实施建议的解决方案:

    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"})
    

    【讨论】:

    • 我使用了您提出的解决方案,它适合我的情况。唯一的问题是由于某种原因我无法使用insert,所以我使用了map.unite(json2.toVariantMap())
    • @dosvarog,您没有指定 Qt 版本。 insert 是在 Qt 5.15 中引入的。另一方面,unite 已过时。无论如何,我很乐意提供帮助。
    • 你是对的。我总是忘记 Qt 经常变化。我的版本是 5.12。
    • @dosvarog,我认为,只要它对您有用,就可以。如果您升级到 5.15 或更高版本,可能最好在该位置添加评论以提醒您更改它。
    【解决方案3】:

    您可以遍历所有需要合并的 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();
      }
    

    但可能不是最有效的。

    【讨论】:

      【解决方案4】:

      扩展版本,它还合并同名对象并添加数组元素(如果两个对象中存在相同名称):

      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();
          }
      }
      

      如果srcother 有同名的字段(数组和对象除外,见顶部),将使用 src。

      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"
         }
      }
      

      调用后合并/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"
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-18
        • 2011-11-03
        相关资源
        最近更新 更多