JS: Массивы

Генерация строки в цикле

Генерация строк в циклах — задача, часто возникающая на практике. Типичный пример — функция, помогающая генерировать HTML-списки. Она принимает на вход коллекцию элементов и возвращает HTML-список из них:

const coll = ['milk', 'butter'];

buildHTMLList(coll);
// <ul><li>milk</li><li>butter</li></ul>

Как можно решить эту задачу "в лоб":

  1. Создать переменную result и записать в нее <ul>.
  2. Пройтись циклом по элементам коллекции и дописать в результирующую строку очередной элемент <li>.
  3. Добавить в конце </ul> и вернуть result из функции.
const buildHTMLList = (coll) => {
  let result = '<ul>';
  for (const item of coll) {
    result = `${result}<li>${item}</li>`;
    // либо так: result += `<li>${item}</li>`;
  }
  result = `${result}</ul>`;

  return result;
}

Такой способ вполне рабочий, но для большинства языков программирования максимально неэффективный. Дело в том, что конкатенация и интерполяция порождают новую строчку вместо старой, — и подобная ситуация повторяется на каждой итерации. Причём строка становится всё больше и больше. Копирование строк приводит к серьёзному расходу памяти и может влиять на производительность. Конечно, для большинства приложений данная проблема неактуальна из-за малого объёма прогоняемых данных, но более эффективный подход не сложнее в реализации и обладает рядом плюсов. Поэтому стоит сразу приучить себя работать правильно.

Правильно, в случае с динамическими языками, – формировать массив, который затем с помощью метода join() превратить в строку:

const buildHTMLList = (coll) => {
  const parts = [];
  for (const item of coll) {
    parts.push(`<li>${item}</li>`);
  }

  // Метод join объединяет элементы массива в строку
  // В качестве разделителя между значениями
  // используется то, что передано первым параметром
  const innerValue = parts.join('');
  const result = `<ul>${innerValue}</ul>`;
  return result;
}

Размер кода практически не изменился, но способ формирования результата стал другим. Вместо строки, сначала собирается массив, который затем превращается в строку с помощью метода join(). Помимо эффективности, у такого подхода есть дополнительные плюсы:

  • Такой код проще отлаживать. Данные, представленные массивом, легче вычленять визуально и программно.
  • Массив это структура, с ним можно производить дополнительные манипуляции. С готовой строкой уже ничего особо не сделать.

Регулируя разделитель, строки можно объединять разными способами. Например, через запятую с пробелом:

const parts = ['JavaScript', 'PHP', 'Python'];
const output = parts.join(', ');

console.log(output); // => JavaScript, PHP, Python

Если каждое слово надо вывести на новой строчке, то в качестве разделителя используем символ перевода строки '\n':

const parts = ['JavaScript', 'PHP', 'Python'];

 // теперь каждое слово будет начинаться с новой строки
const output = parts.join('\n');

console.log(output); // =>
// JavaScript
// PHP
// Python

Последний пример особенно важен. Новички часто допускают ошибку и добавляют перевод строки в момент формирования массива, а не в join(). Посмотрите на пример с нашей функцией buildHTMLList():

// Неправильно

const parts = [];
for (const item of coll) {
  parts.push(`\n<li>${item}</li>`);
}
const innerValue = parts.join(''); // разделителя нет

// Правильно

const parts = [];
for (const item of coll) {
  parts.push(`<li>${item}</li>`);
}
const innerValue = parts.join('\n'); // перевод строки

Дополнительные материалы

  1. Джоэль Спольски. Назад к основам (английская версия)

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

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

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».