Рубріки: 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]
*/

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

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

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023