Сравнить два JSON

Сравнить два JSON: добавленные, удалённые и изменённые поля с путём до каждого отличия, старым и новым значением. Сравнение без учёта порядка ключей, массивы по порядку или как множества. Всё считается в браузере.

Настройки сравнения

Элемент сравнивается с элементом на той же позиции: перестановка считается различием

Значения
Учитывать регистр в значениях строкВыключите, чтобы «Анна» и «анна» считались одним значением
Считать null и отсутствие ключа разнымиВыключите, если поле со значением null для вас то же самое, что удалённое поле

JSON для сравнения

Отличия

Показывать
Добавленные
Удалённые
Изменённые

Вставьте два JSON — отличия появятся здесь.

Зачем сравнивать две версии JSON

Две версии одного JSON редко расходятся целиком: в конфиге меняется пара параметров, в ответе API добавляется поле, в выгрузке правят несколько записей. На глаз такое сравнение заканчивается на первом различии — внимание цепляется за него, и остальные отличия остаются незамеченными. Особенно когда в документе десятки ключей на каждом уровне, а различаются из них три.

Инструмент разбирает оба документа и обходит их вместе, собирая путь до каждого отличия — от корня «$» через имена ключей и индексы массивов, вплоть до конкретного поля внутри конкретного элемента. В таблице видно, что именно изменилось: добавлено, удалено или изменено, — а рядом старое и новое значение. Порядок ключей при этом не важен, потому что объекты сравниваются по именам; порядок элементов массива, наоборот, учитывается, но его можно выключить и сравнить массивы как множества — тогда перестановка различием не считается.

Настройки закрывают самые частые расхождения, которые различиями не являются: регистр в значениях строк и поле, погашенное через null, вместо удалённого поля. Список отличий копируется текстом, с теми же пометками, что и в таблице, — его можно вставить в задачу или в переписку. Считается всё в браузере: оба JSON остаются на странице и никуда не отправляются, поэтому сюда можно вставлять выгрузки и конфиги с данными, которые не стоит отдавать стороннему сервису.

Частые вопросы

Чем это отличается от сравнения двух текстов?

Сравнение текстов работает построчно: два документа выравниваются алгоритмом наибольшей общей подпоследовательности, и результат — список строк с номерами. JSON так сравнивать нельзя: в нём важна структура, а не порядок строк. Здесь документ сначала разбирается, а затем два значения обходятся вместе — путь до отличия собирается из имён ключей и индексов, поэтому переставленные ключи различием не считаются, а сдвиг элемента внутри массива виден как изменение конкретного элемента, а не как «поехали все строки с этого места».

Как читать путь до отличия?

Путь начинается со знака «$» — это сам документ — и собирается точками и индексами: «$.user.roles[0]» читается как «элемент с индексом 0 в массиве roles объекта user». Ключ, в котором есть точка, пробел или дефис, записывается в скобках: «$["first name"]» — иначе такой ключ был бы неотличим от вложенного. Индекс в квадратных скобках всегда означает позицию в массиве, имя в скобках и кавычках — ключ объекта. При сравнении массивов как множеств путь добавленного отличия указывает на позицию во втором документе, а остальных — на позицию в первом: у элемента, найденного по значению, своей позиции нет.

Что значит сравнение массивов как множеств?

В обычном режиме элементы сравниваются по порядку: первый с первым, второй со вторым, и вставка элемента в начало массива сдвигает все следующие. В режиме множеств порядок не важен — каждый элемент подбирается к равному ему элементу с другой стороны, независимо от позиции. В таблицу попадают только те элементы, которым пары не нашлось: лишние в первом документе показаны как удалённые, лишние во втором — как добавленные. Совпавшие элементы не показываются вовсе. Если одинаковых элементов не нашлось, но с обеих сторон остались объекты, они сопоставляются попарно, чтобы правка поля внутри элемента читалась как изменение, а не как «объект удалён, объект добавлен». Повторы учитываются: «[1, 1]» и «[1]» разными остаются.

Как учитывается регистр строк?

Флажок «Учитывать регистр в значениях строк» включён по умолчанию, и это значит, что «Анна» и «анна» — разные значения. Снимите его, если сравниваете выгрузки, где регистр мог разойтись: строки будут сравниваться без учёта регистра. Флажок действует только на значения строк — имена ключей, числа, логические значения и null сравниваются как есть, — и распространяется на все проверки, включая поиск равных элементов при сравнении массивов как множеств.

Почему JSON с разным порядком ключей считается равным?

Потому что порядок ключей в объекте JSON ничего не значит: по стандарту это неупорядоченный набор пар, и «{"a":1,"b":2}» с «{"b":2,"a":1}» — одна и та же структура. Инструмент обходит объекты по объединению имён ключей, а не по позициям, поэтому такая перестановка различием не считается и вложенные объекты можно свободно переупорядочить. Порядок элементов массива, наоборот, значащая часть данных: если он не важен, переключите сравнение массивов на «Как множества».

Что значит «считать null и отсутствие ключа разными»?

Если флажок включён (по умолчанию), «{"email": null}» и «{}» — разные документы: в первом поле есть и равно null, во втором поля нет. Это разные состояния, и различие о них сообщается. Во многих выгрузках разницы нет: поле «гасят», записывая null, вместо того чтобы удалять его из объекта, и тогда каждое такое поле превращается в отличие. Снимите флажок — и ключ со значением null будет считаться тем же, что отсутствующий ключ, в обе стороны и внутри вложенных объектов.

Можно ли сравнить большой JSON?

Да, но с двумя ограничениями, и оба показаны прямо на странице. Первое — размер: документы больше миллиона символов не сравниваются, потому что обход идёт на каждое нажатие клавиши в поле и вкладка переставала бы отвечать. Второе — число отличий: собираются первые 5000, дальше обход останавливается, и об этом сообщается под таблицей; числа в сводке тогда относятся к собранным отличиям. Отдельный предел есть у сравнения массивов как множеств: там сопоставление каждого элемента с каждым, и массивы длиннее 2000 элементов так не сравниваются — выберите сравнение по порядку или разбейте документ на части. Само сравнение идёт в браузере, поэтому упор идёт в скорость вкладки, а не в ограничения сервиса.