Reduce

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

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

const reduce = (f, tree, acc) => {
  const [, children] = tree;
  const newAcc = f(acc);

  if (!children) {
    return newAcc;
  }
  return children.reduce((iAcc, n) => reduce(f, n, iAcc), newAcc);
};

const tree = ['A', [
  ['B', [['E'], ['F']]],
  ['C'],
  ['D', [['G'], ['J']]],
]];

reduce((acc) => acc + 1, tree, 0); // 8

https://repl.it/@hexlet/js-trees-reduce-reduce

Выше пример теста, в котором используется reduce для подсчёта количества узлов в дереве. С помощью reduce, задача выполняется в одну строку.

Так же как и в остальных функциях высшего порядка, в функцию-обработчик передаётся нода целиком, а не только имя. Самое интересное происходит при обработке детей. Вызов reduce на каждом ребёнке должен происходить с аккумулятором, протаскиваемым сквозь обработку каждого ребёнка. Из-за этого получается что снаружи есть reduce перебирающий children, в то время как каждый ребёнок принимает на вход текущий acc внешнего reduce и запускает внутренний с этим аккумулятором.

Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Javascript, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →