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