Рубріки: Front-end

Практическое применение рекурсии в JavaScript

Роман Гармидер

Игорь Быков, Frontend Developer в Opticks Security, написал практический гайд по применению рекурсии в JavaScript, без большого O, без чисел Фибоначчи и других скучных академических примеров. Приводим отрывок из его статьи, который демонстрирует как использовать рекурсию при работе с многоуровневыми массивами.

В программировании есть два способа запускать повторяющиеся вычисления — это циклы и рекурсия. Такие циклы как for, while, Array.prototype.map и Array.prototype.forEach по умолчанию внедрены в JavaScript. Но рекурсия — это более гибкая возможность для циклических вычислений. Использовать ее мешают только ментальные барьеры.

Например, применим рекурсию для выравнивания вложенных массивов:

const flatToBase = array => array.reduce(
  (accumulator, value) => accumulator.concat(
    Array.isArray(value) ? flatToBase(value) : value
  ),
  [],
);

flatToBase([[[[[[[ 42 ]]]], 36]]]); // -> [ 42, 36 ]

Для решения этой проблемы в JavaScript есть встроенная функция Array.prototype.flat. Но для выравнивания вложенных массивов неопределенной глубины ее применение считается плохой практикой:

nestedArrays.flat(Infinity);

Цикл + рекурсия

Эти двое не обязательно должны конкурировать друг с другом. Они прекрасно работают вместе!

Допустим мы получаем с сервера следующую структуру:

// Fetched from server

const nestedNumbers = [
  [[0], [[[[[[[1, 2]]]]]]], [3]],
  [[[4], [[5]]], [[[6, 7, 8]]]],
  [9]
];

Нам нужно увеличить каждое число на единицу, при этом сохранив существующий порядок вложений таким, какой он есть. Хорошие новости — в том, что каждый массив содержит либо число, либо другой массив.

Рекурсия отлично подходит для обработки повторяющихся структур данных, а итерация отлично подходит для циклического перебора массивов. Можно извлечь максимум пользы из двух инструментов сразу: 

const incrementNestedNumbers = (arrayWithNums) => {
  for (let i = 0; i < arrayWithNums.length; i++) {
    if (Array.isArray(arrayWithNums[i])) { // if array
      incrementNestedNumbers(arrayWithNums[i]);
    } else { // if number
      arrayWithNums[i] = arrayWithNums[i] + 1;
    }
  }
};

incrementNestedNumbers(nestedNumbers);

/* nestedNumbers now look like this:
  [[1], [[[[[[[2, 3]]]]]]], [4]],
  [[[5], [[6]]], [[[7, 8, 9]]]],
  [10]
*/

Некоторые наверняка возразят, что этот тип кода может легко вызвать утечки памяти и проблемы с производительностью. Но на практике, если вы понимаете, что делаете, и хорошо тестируете код перед использованием в продакшене, он вряд ли приведет к возникновению каких-либо проблем.

Останні статті

Что такое прокси-сервер: пояснение простыми словами, зачем нужны прокси

Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…

21.11.2024

Что такое PWA приложение? Зачем необходимо прогрессивное веб-приложение

Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…

19.11.2024

Как создать игру на телефоне: программирование с помощью конструктора

Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…

17.11.2024

Google Bard: эффективный аналог ChatGPT

В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…

14.11.2024

Скрипт и программирование: что это такое простыми словами

Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…

12.11.2024

Дедлайн в разработке: что это такое простыми словами

Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…

11.11.2024