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

По чём бежать будем?
Давайте бежать по телефонной книге:
const phoneBook = { andrew: ["+345356245254", "+313232312312"], vasilina: ["+132313123123"], serhiy: ["+587234878234", "+321323124123"], };
Что хотим получить?
Давайте получим список всех номеров.
Как мы это сделаем?
Мы сделаем это в 4 шага:
- Подключим библиотеку для валидации данных
- Создадим обычную функцию валидации
- Добавим побочный эффект собирания номеров в массив
- Обернём в функцию
Будем использовать библиотеку валидации quartet:
import { v } from "quartet";
Напишем функцию валидации:
const checkPhoneBook = v({ [v.rest]: v.arrayOf(v.string), });
Теперь мы можем проверить, является ли некое значение телефонной книгой:
checkPhoneBook({}); // true checkPhoneBook({ andrew: ["123321"] }); // true checkPhoneBook({ andrew: null }); // false
Теперь добавим немного сумасшествия: проверяя элемент списка номеров будем его добавлять в массив.
const phoneNumbers = []; const checkAndCollect = v({ [v.rest]: v.arrayOf( v.and( v.string, v.custom((phoneNumber) => { phoneNumbers.push(phoneNumber); return true; }) ) ), });
Вызовем эту функцию валидации на конкретной телефонной книге:
checkAndCollect({ andrew: ["+345356245254", "+313232312312"], vasilina: ["+132313123123"], serhiy: ["+587234878234", "+321323124123"], });
Вернулось true. Но нас это не интересует! Главное: в массиве phoneNumbers теперь хранятся все номера.
console.log(phoneNumbers); // [ // '+345356245254', // '+313232312312', // '+132313123123', // '+587234878234', // '+321323124123' // ]
Обернём это в функцию для «переиспользования»:
import { v } from "quartet"; /** * @param {Record<string, string[]>} phoneBook * @returns {string[]} phone numbers */ function collectPhoneNumbers(phoneBook) { const phoneNumbers = []; const checkAndCollect = v({ [v.rest]: v.arrayOf( v.and( v.string, v.custom((phoneNumber) => { phoneNumbers.push(phoneNumber); return true; }) ) ), }); checkAndCollect(phoneBook); return phoneNumbers; }
Оценка
Использование таких трюков может быть забавным. Но я бы не писал так в production коде. И по четырем причинам:
- Это не оптимальное решение по скорости работы. Создание функции валидации для итерации по книге номеров — лишнее действие.
- Это не идиоматический код. Библиотека валидации не предназначена для итераций.
- Это опасный код. Библиотека может поменять внутренние правила проверки и это может привести к повторным вызовам карточного валидатора.
- Есть код более подходящий для этой задачи:
/** * @param {Record<string, string[]>} phoneBook * @returns {string[]} phone numbers */ function collectPhoneNumbers(phoneBook) { const phoneNumbers = []; const personNames = Object.keys(phoneBook); for (const personName of personNames) { const personPhoneNumbers = phoneBook[personName]; phoneNumbers.push(...personPhoneNumbers); } return phoneNumbers; }
Послесловие
Вот такую забаву я придумал в Воскресение вечером. А что странного приходит в вашу голову? Напишите в комментах.
ссылка на оригинал статьи https://habr.com/ru/post/535258/
Добавить комментарий