AJV — еще один валидатор схемы JSON. Один из наиболее часто используемых валидаторов схемы JSON в JS-программировании. Если вы использовали этот валидатор, вы могли столкнуться с проблемой проверки «multipleOf». Здесь я объясняю использование ключевого слова «multipleOf», возможную блокировку и решение путем создания пользовательского ключевого слова AJV для проверки «multipleOf».
Использование валидатора AJV:
Давайте перейдем к примеру и посмотрим, как использовать AJV для проверки схемы JSON с числовыми значениями.
Давайте инициализируем проект и добавим AJV в качестве зависимости,
#npm init
#npm добавить ajv
Создайте файл ajvValidator1.js и добавьте следующее содержимое:
Запустите код,
#узел ajvValidator1.js
Это дает следующий результат,
integer validation 25 true integer validation 25.45 false integer validation a false number validation 25 true number validation 25.45 true number validation a false
Использование ключевого слова multipleOf для проверки
Ключевое слово типа «multipleOf» помогает проверить, является ли данное число кратным значению схемы или нет. Давайте рассмотрим простой пример использования валидатора «multipleOf» для проверки числа, кратного 10.
это выходы,
multiple of 10 validation 100 true multiple of 10 validation 101 false
Теперь давайте попробуем проверить точность с плавающей запятой. Например, чтобы проверить 2 десятичную точку, мы можем использовать 0,01 в качестве значения MultipleOf.
вывод:
multiple of 0.01 validation 7.11 true multiple of 0.01 validation 7.999 false
Пока все выглядит нормально. Давайте продолжим изучение еще нескольких примеров,
это выходы,
multiple of 0.01 validation 7.01 true multiple of 0.01 validation 7.02 false multiple of 0.01 validation 7.03 true
странный! 7.02 подтвержден как ложный.
Основная причина
Какова основная причина такого неожиданного поведения? Чтобы узнать подробности, давайте попробуем выполнить следующие математические операции:
это выходы,
7.0200000000000005 0.30000000000000004
Проверьте длинные десятичные дроби. Это связано с бесконечным дробным значением, хранящимся в двоичном формате. Чтобы узнать больше об этой проблеме, перейдите по ссылке ниже,
Несколько проверок
Теперь мы знаем, что по умолчанию валидатор MultipleOf AJV ведет себя жутко, и мы не можем на это полагаться. Кроме того, мы увидели основную причину проблемы. Попробуем разобраться с этим альтернативными методами.
Мы можем проверить, является ли данное число кратным другому числу, разделив и проверив значение остатка. Если остаток равен 0, данное число кратно проверочному числу.
Проверьте следующие фрагменты кода,
Как и ожидалось, code-snippet-1 возвращает 0. Таким образом, 400 кратно 10.
Во фрагменте кода-2 мы ожидаем 0, но из-за проблемы с дробью он предоставляет дополнительные дроби.
Чтобы избежать проблемы с дробями, дроби удаляются путем умножения на 100 во фрагменте кода-3. Затем, как и ожидалось, он возвращает 0.
Теперь это выглядит великолепно! Но та же логика не работает для фрагмента кода-4. Опять же, мы в конечном итоге с проблемой дроби!
Наконец, после попытки округления значений он возвращает 0 во фрагменте кода-5.
Итак, метод, который мы использовали во фрагменте кода-5, дает правильный результат для проверки кратности значения. Давайте сделаем полную функцию для проверки кратности проверки,
Итак, мы увидели проблему проверки AJV с ключевым словом multipleOf, исследовали основную причину и нашли обходную функцию для проверки кратности проверки.
Теперь давайте начнем работать над нашей актуальной темой, создав пользовательское ключевое слово multipleOf для валидатора AJV.
Как указано в приведенном выше коде, мы можем использовать «removeKeyword», чтобы удалить валидатор MultipleOf по умолчанию, а с помощью метода «addKeyword» мы можем добавить пользовательское ключевое слово.
Давайте, запустим код,
#узел ajvMultipleOf.js
Это дает следующий результат,
multiple of 0.01 validation 7.001 false multiple of 0.01 validation 7.02 true multiple of 0.01 validation 7.03 true
Наконец-то мы получили ожидаемый результат :-)
Как показано выше, мы можем написать новое пользовательское ключевое слово или заменить существующее пользовательской функцией проверки.
Ссылка:
https://javascript.info/number#imprecise-calculations
https://github.com/tdegrunt/jsonschema/blob/master/lib/attribute.js#L601
https ://ajv.js.org/custom.html