Nano Hash - криптовалюты, майнинг, программирование

Как объединить два объекта QJsonObject в Qt?

У меня есть:

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

и мне нужно:

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

Или в JSON:

{
    "bla" : "lab"
}

{
    "bla2" : "lab2"
}

И мне нужно:

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

Как этого добиться?

03.11.2020

  • Вам нужно объединиться рекурсивно? Пробовали ли вы зацикливаться на отдельных объектах и ​​вставлять пары ключ-значение в obj3? 03.11.2020

Ответы:


1

Решение

Я предпочитаю избегать явных циклов, поэтому моим решением будет использование преобразования to и from QVariantMap, он же QMap<QString, QVariant>:

  1. Используйте QJsonObject::toVariantMap, чтобы преобразовать все объекты JSON в QVariantMap

  2. Используйте QMap::insert, чтобы вставить все карты в одну

  3. Используйте QJsonObject::fromVariantMap, чтобы преобразовать полученную карту обратно в объект JSON.

Примечание. Предлагаемое решение лучше всего работает, если все объекты JSON содержат уникальные ключи, поскольку документация гласит:

Если карта содержит несколько записей с одним и тем же ключом, то окончательное значение ключа не определено.

Пример

Вот простой пример, который я подготовил для вас, чтобы продемонстрировать, как можно реализовать предложенное решение:

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"})
03.11.2020
  • Я использовал предложенное вами решение, оно подходит для моей ситуации. Единственное, по какой-то причине я не мог использовать insert, поэтому я использовал map.unite(json2.toVariantMap()). 05.11.2020
  • @dosvarog, вы не указали версию Qt. insert был представлен в Qt 5.15. С другой стороны, unite устарело. В любом случае, я рад помочь. 05.11.2020
  • Ты прав. Я всегда упускаю из виду, что Qt меняется довольно часто. Моя версия 5.12. 05.11.2020
  • @dosvarog, пока это работает для вас, я думаю, все в порядке. Вероятно, было бы неплохо оставить комментарий в этом месте, чтобы напомнить вам изменить его, если вы когда-нибудь обновитесь до 5.15 или новее. 05.11.2020

  • 2

    Вы можете перебрать все 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();
      }
    

    Хотя, наверное, не самый эффективный.

    03.11.2020

    3

    Расширенная версия, которая также объединяет объекты с одинаковыми именами и добавляет элементы массива (если они присутствуют с одинаковыми именами в обоих объектах):

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

    объединено/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"
       }
    }
    
    15.03.2021
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..