[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Сравнить структуру JSON объектов
MatrixGod
Всем привет!

Я немного зол и измучен а олени из stackoverflow ничего умного и элегантного предложить не могут. Я надеюсь на супер-мозг наших русских экспертов. :)

У меня есть 2 JSON объекта которые генерируются на лету в зависимости от динамического контента. мне нужно найти способ сравнить их структуру.

сами объекты всегда разные потому что зависят от внешних факторов но структура их почти всегда одинаковая. я хочу иметь возможно обнаружить изменения в их структуре.

каким образом лучше всего это сделать?

к примеру, эти 2 объекта должны считаться одинаковыми потому что у них обоих есть переменная index и массив tags (и только):

{
"index": 0,
"tags": [
"abc"
]
}
{

"index": 1,
"tags": [
"xyz"
]
}


я пытался сделать это:
$array = json_decode($json, true);

$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));

foreach($iterator as $key => $value){
echo $key.'<br>';
echo $value.'<br><br>';
}


этот итератор бежит только по листьям дерева, то есть как раз те элементы которые мне нужно проигнорировать во время сравнения. проблема в том что "$key => $value" в этом цикле не содержать информации о вложенности и я не знаю о какой паре идет речь.

так же думал использовать array_diff_key() но он не рекурсивный. :(

в общем, посоветуйте пжл как это сделать!

спасибо!
AllesKlar
нужны критерии, когда считать объекты одинаковыми, когда разными, а когда измененными.

_____________
[продано копирайтерам]
MatrixGod
AllesKlar, я же привел пример.
kaww
MatrixGod, в мануале есть комментарий в котором преложено решение http://php.net/manual/ru/function.array-diff-key.php#112558
MatrixGod
kaww, код глючит. не возвращает желаемого результата.
sergeiss
MatrixGod, можно вот так попробовать (код не проверял)

$arr1 = ... //первый объект
$arr2 = ... // второй объект
$compare = array(); // массив, куда будут записаны данные сравнения

foreach( $arr1 as $key => $val ) {
$compare[ $key ] = 0;
}

foreach( $arr2 as $key => $val ) {
if( isset( $compare[$key] ) ) {
$compare[$key] = 1;
}
else {
$compare[$key] = -1;
}
}



На выходе имеем массив $compare, который содержит ключи обоих твоих объектов. При этом величина каждого элемента массива показывает наличие ключей в массивах:
0 - ключ есть только в первом массиве
1 - ключ есть в обоих массивах
-1 - ключ есть только во втором массиве

Что ты будешь делать с этим $compare, это уже твои проблемы :)

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
MatrixGod
sergeiss, тоже не вариант. скажем, если в объекте есть массив "qwe", а в нем тоже есть массив "qwe" и в этом тоже, то переменная $key из цикла запутается и будет давить не то что надо.

я же ищу общее решение которое схавает объекты любого вида и любой вложенности.
S.Chushkin
MatrixGod, ну Вы даёте - сутки ищите решения, а работы там на полчаса, вместе с отладкой и примерами. wink.gif
Например, так: http://php.ru/forum/viewtopic.php?p=433962#p433962


_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
MatrixGod
S.Chushkin, он односторонний. такой и я могу написать.
EqualRecursive($j1, $j2) и EqualRecursive($j2, $j1) возвращают разные результаты.

когда сравниваются 2 объекта, порядок не должен иметь значения. ибо если они действительно равны то $obj1 = $obj2 и $obj2 = $obj1.
S.Chushkin
Цитата (MatrixGod @ 18.08.2015 - 16:06)
... такой и я могу написать. ...

Написать можете, а поправить не можете? smile.gif

(функцию поправил)


_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
SerginhoLD
$obj1 = '{
"index": 0,
"tags": [
"abc",
"12",
45,
66
]
}'
;

$obj2 = '{
"index": 1,
"tags": [
"xyz",
34,
12,
[
"99"
],
45
],
"sd": 2
}'
;

$obj1 = json_decode($obj1, true);
$obj2 = json_decode($obj2, true);

function structRecursive($ar1, $ar2)
{
$res = array();
$checkAr = $ar2;

foreach ($ar1 as $k1 => $v1)
{
if (!isset($checkAr[$k1]))
{
$res[$k1] = $v1;
}
else
{
if (is_array($v1))
{
if (!is_array($checkAr[$k1])) // ???
{
$res[$k1] = $v1;
}
else
{
$newres = structRecursive($v1, $checkAr[$k1]);
if (!empty($newres)) $res[$k1] = $newres;
}
}

else
{
if (is_array($checkAr[$k1])) // ???
{
$res[$k1] = $checkAr[$k1];
}
}


unset($checkAr[$k1]);
}
}


if (!empty($checkAr))
{
foreach ($checkAr as $v)
{
$k = array_search($v, $ar2, true);
$res[$k] = $v;
}
}


return $res;
}

$arr1 = structRecursive($obj1, $obj2);
pre($arr1);


$arr2 = structRecursive($obj2, $obj1);
pre($arr2);


Array
(
[tags] => Array
(
[3] => Array
(
[0] => 99
)

[4] => 45
)

[sd] => 2
)
Array
(
[tags] => Array
(
[3] => Array
(
[0] => 99
)

[4] => 45
)

[sd] => 2
)


ключи нумерованного массива только не сохраняются, там уже сам насилуй, в строки их там преобразуй, хз
поправил

_____________
"internet explorer всех правильней отображает страницы" ©
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.