Russian Qt Forum

Qt => Общие вопросы => Тема начата: DenKor29 от Июль 27, 2015, 08:35



Название: Объдинение двух Json обьектов
Отправлено: DenKor29 от Июль 27, 2015, 08:35
Читаю документацию и не могу понять каким образом можно:

1. Объединить два объекта с перезаписью общих ключей.
2. Имея два объекта получить третий обьект, дополняющий второй до первого.


Пример, что нужно сделать для объдинение 1 и 2 объектов.

Код:

{
  "Comment":"My comment",
  "Count":10,
  "DiskParam":
  {
    "DB":10.000000,
    "DBAngle":1.234000
  }
}



{
  "Comment":"My comment",
  "Count":20
}


{
  "Comment":"My comment",
  "Count":20,
  "DiskParam":
  {
    "DB":10.000000,
    "DBAngle":1.234000
  }
}





Название: Re: Объдинение двух Json обьектов
Отправлено: gil9red от Июль 27, 2015, 09:56
Сделайте вручную :)
Если уровней вложенности 1-2, то будет несложно


Название: Re: Объдинение двух Json обьектов
Отправлено: DenKor29 от Июль 27, 2015, 10:37
Мне нужно это сделать в общем случае. Велосипед изобретать не хочется ....


Название: Re: Объдинение двух Json обьектов
Отправлено: gil9red от Июль 27, 2015, 13:56
Навелосипедил немного :) Алгоритм нужно тестить, а так, вроде бы работает :)
Сделал на питоне, но алгоритм будет такой же и для с++

Код
Javascript
{
  "Comment":"My comment",
  "Count":10,
  "Errors": null,
  "DiskParam":
  {
    "DB":10.000000,
    "DBAngle":1.234000
  }
}
 
{
 "Comment":"My super comment!",
 "Count":20,
 "Errors": "@##@##%!",
 "DiskParam":
 {
   "DB":42,
   "Foo": [1, 2, 3, 4]
 }
}

Питоничий json-сериализатор парсит строку в стандартные питоничьи типы: dict, list, None, False, True, int, float, str, поэтому в функцию попадают 2 dict.
Слияние идет от второго в первый словарь.
В цикле перебираются все элементы и возвращаются их ключ (k) и значение (v)
В условии мы проверяем что ключ k есть у первого словаря и то, что значениями словарей j1 и j2 являются словари (json object), тогда вызываем сами себя
Если условие не совпало, просто добавляем / переписываем значение под ключом k. Добавляем, если такого ключа нет в словаре, и переписываем если есть

https://github.com/gil9red/SimplePyScripts/blob/master/jsonmerge.py
Код
Python
def jsonmerge(j1, j2):
   for k, v in j2.items():
       if k in j1 and isinstance(j1[k], dict) and isinstance(v, dict):
           jsonmerge(j1[k], v)
       else:
           j1[k] = v


Результат:
Код
Javascript
{
   "Errors": "@##@##%!",
   "Comment": "My super comment!",
   "DiskParam": {
       "DB": 42,
       "DBAngle": 1.234,
       "Foo": [1, 2, 3, 4]
   },
   "Count": 20
}
 


Название: Re: Объдинение двух Json обьектов
Отправлено: DenKor29 от Июль 27, 2015, 14:15
Спасибо. Но я питон не знаю.

Можно пример на c++ и классов Json.   :)


Название: Re: Объдинение двух Json обьектов
Отправлено: DenKor29 от Июль 28, 2015, 09:44
Все оказалось проще чем я думал. Может кому пригодится.

Код:
QJsonObject merge(QJsonObject obj1, QJsonObject obj2)
{
QJsonObject obj;

obj = obj1;

QStringList keys = obj2.keys();

foreach (QString key,keys)

{
if (obj2[key].isObject())
obj[key] = merge(obj[key].toObject(),obj2[key].toObject());
else obj[key] = obj2[key];
}

return obj;
}


Название: Re: Объдинение двух Json обьектов
Отправлено: gil9red от Июль 28, 2015, 10:23
Молодец :)

Проверьте алгоритм для этих json'ов ;)
Код
Javascript
{
  "Comment":"My comment"
}
 
{
 "Comment":"My super comment!",
 "Count":20
}
 


Название: Re: Объдинение двух Json обьектов
Отправлено: DenKor29 от Июль 29, 2015, 17:12
А в чем подвох ? Будет

{
        {"Comment","My super comment"},
        {"Count", 20}
}





Название: Re: Объдинение двух Json обьектов
Отправлено: gil9red от Июль 29, 2015, 20:45
А в чем подвох ? Будет

{
        {"Comment","My super comment"},
        {"Count", 20}
}

По-идеи, в строке obj[key] = merge(obj[key].toObject(),obj2[key].toObject()); случится фигня, потому что в словаре obj не будет такого ключа


Название: Re: Объдинение двух Json обьектов
Отправлено: DenKor29 от Июль 30, 2015, 08:10
Фигни не будет так как в этом случае obj[key].toObject() вернет ссылку на пустой объект.
Что довольно логично ...


Название: Re: Объдинение двух Json обьектов
Отправлено: gil9red от Июль 30, 2015, 08:33
Ну раз он не null возвращает, то да :)