Шаблонизация
Напишите функцию template
, которая первым аргументом принимает строку-шаблон, а вторым — описание литералов, которые в этот шаблон нужно вставить.
Дополнительно: функция может работать с массивами:
Решение
Самым очевидным способом является использование регулярных выражений. Если у вас нету опыта работы с ними, настоятельно рекомендую ознакомиться. MDN, раз туториал, два туториал. У класса String есть замечательный метод replace, принимающий регулярное выражение и строку, на которую надо заменить все подстроки, которые соответствуют этому выражению. Итерируем по каждому литералу и постепенно преобразуем нашу строку.
Заметим, что на каждый литерал мы создаем новое регулярное выражение. Это, его компиляци и пробег по всей строке происходит для каждого литерала. Можем ли мы это исправить? Посмотрим в документацию метода replace. Вместо того, чтобы передевать строку, на которую мы хотим заменить, мы можем передавать функцию, в которую будет переданы все подстроки, которые соответсвуют регулярному выражению. Будем искать любое слово, которое обернуто в {}
. Для этого хватит /\{\w+\}/g
. Однако, тогда в нашу функцию будет передаваться вся подстрока, включая и сами {}
. Если же обернуть само слово в группу, вторым аргументом будет передана она сама. Таким образом, код получается проще и эффективнее.
Дополнительное
Можно заметить, что если один из литералов является массивом, то при неявном преобразовании в строку, каждый элемент в нем будет соединен запятой. Например, ["a", "b"]
превратится в "a,b"
. Выглядит не эстетично. К счастью, нас спасает метод join, который соединяет все элементы в строку, используя в качестве разделителя любую строку, что мы ему передадим.
Именно такой код прислал нам Дмитрий Семиградский.
Самописное решение
Для меня регулярные выражения для данной задачи кажутся стрельбой из пушки по воробьям. Свою работу они делают, но регулярки известны своей нерасторопностью. Пробежимся по строке один раз, и каждой строке внутри фигурных скобок будем сопоставлять нужный литерал.
Уфф, код получился объемнее. Может, это стоит того? Запустим бенчмарки и посмотрим.
Выигрыш сомнительный. Да и поддерживать такой код будет несколько сложнее. Затея оказалась не очень удачная, хотя в критических местах пара сотен миллисекунд и может сыграть роль.
Надеюсь, вы справились с заданием. Спасибо за внимание!
Комментарии