Почему нет достойного инструмента JSONDIFF?

JSON

Предыстория заключается в том, что отдел недавно разрабатывает инструмент воспроизведения трафика.Простое понимание воспроизведения трафика состоит в том, чтобы записать исходную информацию онлайн-запроса и исходную информацию ответа, а затем воспроизвести ее в среде, которую необходимо воспроизвести для сравнения. независимо от того, один и тот же запрос до или после не. Получаются одинаковые результаты ответа. Если результаты ответа не совпадают, то этот инструмент должен быть в состоянии сказать нам, где два результата отличаются. Поскольку большинство служб внутри отдела предоставляют внешние интерфейсы через http+jsonresponse, результат сравнительного ответа можно понимать как сравнение двух строк со структурой json.

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

Эта статья направлена ​​на то, чтобы поделиться изучением и обменом принципами jsondiff, а также тем, как удовлетворить различные потребности различных пользователей в jsondiff.

1. Сопоставление строк

Итак, как доказать, что два json одинаковы?

Если это oj вопрос, то должно быть много способов задать этот вопрос, самый простой способ задать это

Дайте вам две строки формата json строки типа, верните true, если они равны, и верните false, если они не равны. (Можно предположить, что значение типа Number в тестовом примере является целым числом)

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

func Compare(json0,json1 string)bool{   return json0 == json1}

Конечно, ваш личный опыт подскажет вам, что тест-кейсы не так хороши, как вы думаете. Например, он должен провалить следующие тесты.

param0:{"a":1}

param1:{ "a":1}

Отличие между ними в том, что перед полем, где ключ объекта — а, скрытно добавляется неизвестный пробел.

После того, как вы вдумчиво и вежливо поприветствовали создателя тестового набора, вы решили снова и снова чистить тестовый пример: открыли таблицу кодов ascii и удалили все первые тридцать два управляющих символа, которые, по вашему мнению, мог добавить создатель тестов в Факторы помех в тестовом примере, я злобно нажал «Отправить», я думаю, вы увидите это на этот раз.пройти через Но через три секунды экран все равно появляетсяответить на ошибку, ты вздохнула и открыла тест-кейс, и обнаружила, что парни, которые тебе вредны, выглядят вот так

param0:{"a\t":1}

param1:{"a":1}

Получается, что вы удалили управляющие символы, влияющие на семантику json.Если вы хотите поломать голову, вы не знаете, почему есть такие зануды, которые добавляют управляющие символы к значению типа ключа или строки, а вы злобно схватил все на затылке.Мало волос осталось. На этот раз вы научились умнее, вы сопоставили все содержимое в двойных кавычках и мудро избежали ", чтобы гарантировать, что удаление символа управления на этот раз случайно не повредит дружественным войскам, вы хотите молча нажать "Отправить" на этот раз. увидим позжепройти через, вы, кто смотрит на рынок А-акций в течение дня, никогда не подумаете, что однажды вы будете так надеяться, что на экране появится зеленый цвет. Но вы все равно ошибаетесь, тестовый пример выглядит так.

param0:{"a":1,"b":2}

param1:{"b":2,"a":1}

В вашем уме есть слово прямо сейчасОбъект в json — это неупорядоченный набор пар ключ-значение., вы ответили, что объект json не будет отличаться из-за другого порядка ключей, на этот раз вы решили не волноваться, вам нужноРазобратьЭто строка json, вы умница, конечно, вы не будете ее сортировать, а потом сравнивать по порядку, вы же знаете, что в пакете отражения golang естьreflect.DeepEqualТакая полезная вещь. Нажмите «Отправить», на этот раз вы, наконец,зеленый Что ж, вы стоите на плечах гигантов и побеждаете весёлого создателя вопросов.

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

2. анализ json-дерева

Дайте вам две строки формата json строки типа (можно предположить, что значение типа Number в тестовом примере оба являются целыми), на этот раз, если два jsons разные, вам нужно использовать структуру данных, чтобы описать, как они отличаются , Если они одинаковы, вы можете вернуть null.

Гигант безжалостно сбрасывает вас со своих плеч, вы знаете, что DeepEqual не сможет вам помочь, на этот раз вам придется идти одному.

Вы глубоко затянулись сигаретой и решили успокоиться и проанализировать знакомую и незнакомую структуру данных json.Вы обнаружили, что json представляет собой особую древовидную структуру данных.Особенность в том, что узлы этого дерева имеют понятие "тип", а типы разные.Есть Object, Array, Number, String, Boolean, и не каждый тип узла имеет дочерние узлы, только узлы типа Array и Object имеют дочерние узлы, и поиск дочерних узлов родительским узлом относится к левому и правому дочерним элементам бинарного дерева.Деревья разные. Индекс родительского узла типа Object к дочернему узлу равенключ строкового типа, индекс родительского узла типа Array к дочернему узлу равениндекс типа int, вы нарисовали рисунок ниже, чтобы выразить свое понимание json.

Вы обнаружили, что этот вопрос имеет некоторое сходство с вопросом, который вы задавали ранее.то же дерево, конечно, если этот вопрос хочет, чтобы ответ дать подробный дифф, они больше похожи на это. Вы описали свой подход в одном предложении.

Сначала сравните значения двух узлов, а затем рекурсивно сравните левый и правый дочерние узлы двух узлов таким же образом. Конечно, если вам нужно дать подробный diff, вам нужно дополнительно передать древовидную структуру данных, описывающую diff.

Таким образом, вы обнаружите, что им также необходимо рекурсивно сравнивать отдельные узлы. Отличие в том, что перед сравнением двух узлов в этот раз нужно сравнить типы значений узлов, если типы значений разные, конечно, смысла сравнивать значения нет. Вы также обнаружите, что если типы значений двух текущих сравниваемых узлов являются объектами или массивами, вам необходимо рекурсивно сравнить их дочерние узлы. В отличие от «того же дерева», индекс больше не является левым и правым, а должен обсуждаться в соответствии с типом значения текущего узла. Если тип значения — Object, вы хотите сопоставить дочерние узлы одного и того же ключа и рекурсивно выполнить следующее сравнение. Если тип значения является типом массива, вам необходимо сопоставить дочерние узлы того же индекса и выполнить следующее рекурсивное сравнение еще раз.

Конечно, для того, чтобы предоставить подробные различия, вы также определяете типы данных различных различий, которые

  • Добавлено: запись узлов типа объекта/массива нового json, которые не могут быть сопоставлены из-за избыточности.

  • Удалено: узел, который записывает узлы типа объекта/массива нового json, не может быть сопоставлен из-за их отсутствия.

  • Изменено: когда один из двух типов узлов является базовым типом, запишите два узла, потому что типы значений разные или типы значений одинаковы, но конкретные значения не совсем одинаковы.

  • Объект: запишите текущий узел объекта diff, потому что есть подузел, потому что он хочет более подробно описать разницу между подузлами, поэтому ему нужно поле типа под-diff для более подробного описания diff , этот тип различий включает все типы в этом списке.

  • Массив: запишите текущий узел массива diff, потому что в дочернем узле есть diff, потому что он хочет более подробно описать разницу между дочерними узлами, поэтому ему нужно поле типа sub-diff для более подробного описания diff детали, этот тип различий включает все типы в этом списке.

Вы нарисовали диаграмму, выражающую ваше понимание этой структуры данных diff.

Вы, наконец, решили эту проблему, глядя на волосы, падающие с клавиатуры, вы чувствуете, что стали сильнее, вы чувствуете, что ваше понимание jsondiff очень хорошее, и вы с легкостью можете решить все бизнес-сценарии jsondiff, вы решили официально начать чтобы столкнуться с реальными потребностями пользователей в воспроизведении трафика. На следующий день вы уверенно нашли лидера и сказали: «Мне нужно всего два дня для этого спроса».

Через два дня функция запущена, вы полны уверенности, вы верите, что код, который вы пишете, не будет иметь проблем, если есть, то это тоже проблема этого мира.

3. Добавьте шум

Два часа спустя Сяо Чжао, первый пользователь вашей новой функции, нашел вас и описал свое замешательство.

«Хотя поле trace_id отличается в моем ответе на запись и ответ на воспроизведение, вы не должны мне говорить, мне не нужно это знать».

Ну а для сравнения ответа на запрос trace_id (что можно понимать как случайное значение) действительно поле, которое не нужно сравнивать.Глядя на 100 000 запросов, воспроизведенных Сяо Чжао, вам сложно убедить его положиться на это.Каждая запись с количеством различий 1 игнорируется невооруженным глазом. Кроме того, из-за этого проклятого поля trace_id Сяо Чжао не может использовать ваши тщательно разработанныепросто выглядеть иначеФункции. Вы разработали эту функцию, чтобы пользователи действительно видели, что есть разные записи, о которых они должны заботиться, но когда различия между разными записями становятся бессмысленными, эта функция также, кажется, смеется над своим разработчиком.

Когда вы тем вечером идете домой и едите свой ужин из жареной курицы, вы думаете об этом и чувствуете, что сегодняшняя жареная курица не такая ароматная, как раньше. У вас внезапная вспышка вдохновения, вы можете добавитьшумКонцепция игнорировать некоторые различия, которые существуют объективно, но пользователям не нужно заботиться о них, и благодаря вашему дизайну древовидной структуры различий вы, естественно, думаете, что этот «шум» может быть описан jsonpath. Таким образом, после создания дерева jsondiff вы находите узел diff, о котором пользователю не нужно заботиться с помощью jsonpath, удаляете его и рекурсивно удаляете родительский узел, который не должен существовать, поскольку дочерний узел отсутствует. процесс следующим образом.

Вы всю ночь получали эту функцию, а на следующий день у вас были темные круги под глазами, и вы объяснили Сяо Чжао, как она называется.шум, Хотя Сяо Чжао этого не понимал, он знал, что ему нужен jsonpath только для того, чтобы игнорировать проклятый trace_id, так что вы потратили утро, обучая его jsonpath с trace_id, и, наконец, решили проблему. В это время вы чувствуете себя экспертом в области jsondiff, и нет никаких других странных проблем, которые могут вас беспокоить, и вы решаете вздремнуть в полдень, чтобы наверстать потерянный накануне сон. ваш во сне Вождь пришел к вам любезно, и вы почувствовали, что он должен дать вам прибавку. В это время Сяо Чжао внезапно будит вас и сообщает, что написанный вами код снова имеет проблему.

4. Стратегия сопоставления массивов на основе lcs

На этот раз оригинальная запись Сяо Чжао и запись воспроизведения показаны ниже.

old:[0,1,2,3]

new:[1,2,3]

Дифференциал, который он видит, такой.

(Оранжевый фон означает другой, розовый фон означает удаление, зеленый фон означает новый)

Дифференциал, который он хотел увидеть, выглядел так.

В соответствии с вашим дизайном дерево различий двух сравнений json должно выглядеть так.

Вы не думаете, что в этом результате есть какие-то проблемы, и он полностью соответствует вашему дизайну.В вашем исходном проекте сравнение значений типа массива выполняется по тому же индексу на этапе сопоставления.Как вы думаете, это не в чем проблема. Но Сяо Чжао сказал, что этот отображаемый результат не имеет для него смысла, Он надеется, что результат может сказать ему, что 0 в левом массиве — это лишнее значение, а другие значения могут быть точно сопоставлены.

Считаете ли вы потребности пользователей Сяо Чжао разумными?Хотя Сяо Чжао заботится о порядке, он не заботится о порядке.абсолютный порядок, ноотносительный порядок, В этом мире нет проблем. Это действительно проблема вашего дизайна, поэтому вы решаете решить эту проблему. Многолетний опыт чистки говорит вам, что эта проблема очень похожа на знаменитую lcs, и вы чистили эту когда-нибудь вопроссамая длинная общая подпоследовательность.

Преобразование в массив diff должно максимально соответствовать наибольшему общему подпорядку, потому что у вас есть таблица dp lcs, поэтому вы можете найти новые и старые массивы в соответствии с тенденцией роста таблицы dp.подходящая пара, оставшиеся несопоставленные элементы/узлы, если они есть в новой таблице, вы запишете их как добавленный тип различий, если они есть в старой таблице, вы запишете их как удаленный тип различий, как показано ниже:

В этом примере вы нашли совпадающие пары старого и нового массивов (0,1), (1,2), (2,3) в таблице ниже, поэтому вы не будете отображаться в других старых массивах в совпадающей паре. Элемент записывается как Deleted, а элемент в совпадающей паре, который не появляется в новом массиве, записывается как Added.

Вы прокрались на линию, но не сказали Сяо Чжао, что решили проблему, потому что сегодня хотели хорошо выспаться. Но вы не ожидали, что Сяо Чжао тайком обратил внимание на ваш гитлаб, как только вы запустили эту функцию, Сяо Чжао впервые воспользовался ею, и сказал вам, что с вашей функцией снова возникла проблема! Проблема json на этот раз такова:

old:[1,2,3,4]

new:[4,3,2,1]

Когда вы сравниваете стратегию lcs для узлов типа массива, в этом примере может быть сопоставлен только один элемент/узел, а остальные элементы являются различиями добавленного/удаленного типа, но в этом примере Сяо Чжао не заботятся о старых и новых узлах.приказ, он надеется, что, пока старый и новый узлы могут совпадать, они должны совпадать По его мнению, эти два массива json должны быть в состоянии сделатьточное совпадение, вы знаете, что сегодня суждено быть еще одной бессонной ночью, потому что вы человек, который отказывается признать поражение.

5. Стратегия сопоставления массивов с двойным обходом

Итак, вы думаете, пришло время построить новую стратегию выравнивания массива.

Вы хотите построить карту, использовать все элементы в массиве в качестве ключа и пройти каждый элемент в другом массиве, чтобы узнать, существует ли текущий элемент в карте.На основе характеристик хэш-таблицы временная сложность одиночный поиск может быть выполнен до O (1)​, общая временная сложность может бытьO(n+m), объемная сложность O(MIN(n,m)).

Но когда вы запускаете тестовый пример, тестовый пример говорит вам, что элементы в массиве не обязательнопростой тип, если есть элементы типа Object или Array, они анализируются в golang какmap[string]interface{}и[]interface{}тип, поскольку типы массивов и типы карт являются особыми типами нехэшируемых, они не поддерживают операторы==и!=, поэтому его нельзя использовать в качестве ключа карты. Так что жаль, что вы можете использовать только

Схема временной сложности состоит в том, чтобы дважды пройти два массива, выбрать элементы, которые могут быть полностью сопоставлены, и записать позицию. Элементы, позиции которых не записаны в старом и новом json, записываются как добавленные и удаленные соответственно.

И вы предоставляете механизм, который позволяет пользователям свободно выбирать передачу массива в соответствии с jsonpath массива.сопоставление относительного порядка,все ещезаказать независимое сопоставление. Хотя было три часа ночи после решения этой задачи, но на этот раз вы чувствуете, что действительно выиграли, вы компенсируете беспомощное выражение лица Сяо Чжао, что он не может найти ошибку, и вы чувствуете, что потерянный сон стоит того.

6. Стратегия сопоставления массивов на основе подобия + lcs

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

old:[{"a":1,"b":2},{"c":1,"d":0}]

new:[{"c":2,"d":0},{"e":3}]

В двух разработанных вами стратегиях сравнения массивов результаты сравнения в этом случае заключаются в том, что старый и новый jsons вообще не совпадают В частности, кажется, что новый json добавляет два элемента к старому json и уменьшает два элемента, соответствующие Структура Diff состоит из 2-х элементов diff типа Added и 2-х элементов diff типа Deleted (см. рис. ниже). И вы думаете, что это очень разумно, но требование Сяо Чжао состоит в том, чтобы индекс 1 в старом массиве совпадал с индексом 0 в новом массиве.Почему вы спрашиваете его? Он сказал, что из-за того, что это очень похоже, нормальные люди будут сравнивать так.В этот момент ты очень хочешь его забить, но разум подсказывает тебе, что в его потребностях тоже есть доля правды, поэтому ты решаешь принять его требования.

(статус кво)

(ожидал)

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

Итак, вы внимательно ознакомились со словарем Синьхуа.рисунокзначит, вы решили поставитьрисунокЭто определение абстрагируется каксходство, для количественной оценкирисунок. ты положилсходствоОпределяется как число с плавающей запятой 0-1, если сходство равно 1, это означает, что они точно такие же, если сходство равно 0, это означает, что они совершенно разные. Вы определяете метод вычисления сходства следующим образом.

  • Добавлено: 0

  • Удалено: 0

  • Изменено: По крайней мере, позиция такая же, поэтому вы даете базовую точку 0,3 балла.Если они имеют одинаковый тип значения, вы даете еще 0,3 балла комфорта.В соответствии со степенью различия в конкретных значениях вы даете остальные 0,4 балла по мере необходимости.

  • Цель: разделить сумму оценок поля на общее количество полей​​sum(fields'similarity)/count(fields)sum(fields'similarity)/count(fields)

  • Массив: разделите сумму оценок поля на общее количество полей​ ​sum(fields'similarity)/count(fields)sum(fields'similarity)/count(fields)

вы помещаете элементы массива json diffсовпадениеЭта вещь абстрагированаСтремитесь к максимальному сходствупроцесс, каждый шаг в двух массивахискать паруРешения принимаются для борьбы за массивобщее сходствоЧем больше значение , поэтому для записи сходства, которое каждый элемент в старом массиве может получить по сравнению с каждым элементом в новом массиве, естественно установить шкалу n*mтаблица подобияscoreTable,scoreTable[i][j]Представляет индекс i в старом массивес индексом j в новом массивеСходство элементов . Вы обнаружите, что эту проблему также можно решить с помощью динамического программирования.dp[i][j]Определяется как старый массив до iэлементы и первый j нового массиваСумма максимального подобия элементов, уравнение перехода состояний имеет видdp[i][j] = MAX( scoreTable[i][j] + dp[i-1][j-1] ,dp[i][j-1],dp[i-1][j])​, и в соответствии с восходящей тенденцией массива dp (конкретный метод аналогичен методу dp, который появился ранее, и рисунок здесь не нарисован), вы нашли подходящую пару лучшей стратегии и выполняете глубокий рекурсивный сопоставление элементов в совпадающей паре, которая не появляется в совпадающей паре.Старые элементы массива в паре помечаются как удаленные, а новые элементы массива, которые не появляются в совпадающей паре, помечаются как добавленные, поэтому Сяо Чжао видит результат сопоставления, который соответствует ожиданиям, и неохотно возвращается на свое рабочее место.

Только через три дня Сяо Чжао снова нашел вас и сказал, что ваша старая стратегия, основанная на сходстве + lcs, больше не может адаптироваться к нему! Он столкнулся с новой проблемой.

7. Стратегия сопоставления массивов на основе сходства + восемь ферзей

Проблема, с которой на этот раз столкнулся Сяо Чжао, заключается в следующем.

(статус кво)

(ожидал)

Вы тщательно запускаете тестовый пример Сяо Чжао и шаг за шагом проверяете, есть ли проблемы с вашим кодом.В результате вы обнаруживаете, что с вашим кодом нет проблем, и окончательный результат соответствует ожиданиям. тестовый случай. действительно согласноСходство + LCSСтратегия сопоставления массивов реализована правильно, поэтому вы смиренно просите совета у Сяо Чжао.

Сяо Чжао сказал, что он не заботится о порядке в массиве, и в этом тестовом случае очевидно, что элемент с индексом 1 в старом массиве выглядит очень похоже на элемент с индексом 0 в новом массиве, так Когда вы не заботитесь о заказе, они, очевидно, должны быть сопоставлены и сделаны дальнейшие сравнения.

Он объяснил, что старый индекс массива 0 соответствует новому индексу массива 1, старый индекс массива 1 соответствует новому индексу массива 0, и поскольку совпадения массива не по порядку, в этом случае вы должны различать, используя различные цвета для выражения, люди могут найти с первого взгляда.

На этот раз вы думаете, что Сяо Чжао немного неразумен, но вы человек, который не знает, как отказать, поэтому вы снова решаете поддержать потребности Сяо Чжао.

Вы два дня анализировали эту проблему, что думаете?сходствоКонцепциясопоставление решенийЗапустите еще один алгоритм, и вы знаете, что на этот раз вы можете захотеть исчерпать все возможности, как вы это делали при переборе совпадений массива (раздел 5). Просто предыдущее требование должно сопоставлять только элементы, которые могут быть полностью равными, и отбрасывать все элементы, которые не могут быть полностью равными. Но на этот раз, потому что введениесходствоКонцепция , вам нужно перечислить сумму каждой совпадающей парной оценки и записать максимальное значение и массив совпадающих пар, соответствующий ему, поэтому вы рисуете следующую таблицу.

Вы нашли проблему и Восемь королев очень похожи, поэтому вы называете этот метод сопоставленияСходство + восемь королев. Разница в том, что после возврата, чтобы найти вероятность каждой позиции ферзя, вам нужно записать их общий балл и, наконец, вернуть вероятность позиции ферзя с наибольшим общим счетом. Конечно, в массиве комбинаций общего балла и наибольшей выборки необходимо записывать балл как 0, то есть комбинация, которая вообще не может быть сопоставлена, записывается как Добавлено/Удалено, ноСлишком высокая временная сложностьНедостатки очевидны, но лучшего способа вы пока не придумали, но, наконец, снова решили проблему Сяо Чжао и думаете, что Сяо Чжао больше никогда к вам не придет.

8. Алгоритм открытого подобия

...

Верно, он снова здесь, он снова здесь со своим тестовым набором, на этот раз вывод его контрольного примера такой.

(статус кво)

(ожидал)

Вы смотрите на тестовый случай Сяо Чжао с озадаченным лицом Решение о сопоставлении массивов, которое вы дали, удовлетворяет спариванию массивов Сяо Чжао.беспорядокСоответствие требованиям также удовлетворяет общему мнению Сяо Чжао.сходствоСамая большая потребность, вы абсолютно не представляете, что пошло не так.

Сяо Чжао посмотрел на вас, полных сомнений, с довольным выражением лица и медленно сказал, хотя решение, которое вы дали, было в какой-то степени правильным, но в данном случае он надеялся:Элементы с одинаковым значением, соответствующим полю idчтобы соответствовать, потому что в этом примере первичный ключ элемента объекта в массивеID,Толькотот же идентификаторОбъект нужно только сопоставить и сравнить.

Вы проанализировали эту задачу, которая кажется вам очень сложной, и вы думаете, что причина такого результата в алгоритме вычисления подобияслишком общий, он может соответствовать большинству бизнес-сценариев, но небольшое количество бизнес-сценариев не может быть универсальным. Итак, вы решили отдать клавиатуру Сяо Чжао и позволить Сяо Чжао реализовать свой собственный алгоритм вычисления подобия. Конечно, вам неудобно позволять Сяо Чжао модифицировать ваш git-репозиторий, и вы также боитесь, что модификация Сяо Чжао кода для своих нужд повлияет на потребности других, поэтому вы решаете позволить Сяо Чжао написать подобие алгоритм расчета в другом месте, и пусть он Этот специальный алгоритм расчета сходства необходимо использовать для определения массива массива пути json.Когда ваша логика сопоставления выполняется для массива diff этого пути, расчет сходства заменяется пользовательским методом Сяо Чжао . Начинаешь жалеть, что в университете не научились принципам компиляции, но, к счастью, есть много готовых пакетов абстрактного синтаксического дерева, которые можно вызвать. Таким образом, Сяо Чжао может определить свой собственный алгоритм подобия. Код примерно такой.

(a,b)=>a.id==b.id?0.999:0

9. Предопределенный алгоритм подобия

Хотя описанный выше подход может решить проблему Сяо Чжао, это решение кажется слишкомlow level, пользователь должен знать принцип реализации вашего кода, прежде чем научиться писать код, который он хочет, что, очевидно, имеет высокий порог обучения для пользователя. Поэтому на его основе можно абстрагировать и некоторые относительныеhigh levelМетод предоставляется пользователю для выбора в конфигурации.

резюме

В данной статье художественно обработано обдумывание решения различных пользовательских проблем, с которыми столкнулся отдел при разработке функции jsondiff при разработке проигрывания трафика, и проанализированы проблемы.Сюжетная линия чисто выдуманная.

Чтобы ответить на вопрос заголовка, почему нет удовлетворительного инструмента jsondiff? Потому что почти все правила jsondiff, определенные библиотекой jsondiff в сообществе с открытым исходным кодом, смещены в сторонуУниверсальный, конечно, если количество jsons, которые вам нужно сравнить, не велико, даже если инструмент общего назначения не может удовлетворить все ваши потребности diff, вы также можете решить это путем сравнения невооруженным глазом, что, конечно, допустимо. Но почти все бизнес-сценарии, с которыми мы сталкивались, — это десятки тысяч сравнений json, и в этом сценарии сравнения масштабов сравнение невооруженным глазом явно неприемлемо. Итак, что мы ожидаем от функции jsondiff:насколько это возможноУдовлетворить потребности различных настроек пользователей.

Идеи решений, описанные в этой статье, еще не полностью реализованы, и некоторые идеи взяты изGitHub.com/yudai/go — это О…Автор также обнаружил некоторые ошибки во вторичной разработке библиотеки gojsondiff, проблема:GitHub.com/yudai/go — это О…

Наконец, если есть студенты, у которых есть лучшие решения или проблемы, вы можете пообщаться в частном чате ~