Хорошая возможность узнать о взаимной рекурсии - В математике и информатике взаимная рекурсия - это форма рекурсии, в которой два математических или вычислительных объекта, такие как функции или типы данных, определяются в терминах друг с другом. Взаимная рекурсия очень распространена в функциональном программировании и в некоторых проблемных областях, таких как парсеры рекурсивного спуска, где типы данных естественным образом взаимно рекурсивны -
type node =
{ slugs : string array
, children : node array
}
Каждый узел имеет свойство children , которое представляет собой массив узлов, каждый из которых имеет свойство children , содержащее еще больше узлов. Итак, у вас есть рекурсивная структура данных и хорошее время для применения техники взаимной рекурсии.
Ниже match
вызывает match1
, что, в свою очередь, вызывает match
. Обе функции написаны с использованием чистого выражения. Цикл for
не требуется, поскольку for
является оператором, основан на побочном эффекте и используется в императивном стиле. Функциональный стиль позволяет избежать побочных эффектов и поэтому предпочитает рекурсию вместо for
петель -
const None =
Symbol ()
const EmptyNode =
{ slugs: []
, children: []
}
const match1 = (s = "", node = EmptyNode) =>
node.slugs .join ('/') === s
? node
: match (s, node.children)
const match = (s = "", [ node = None, ...rest ] = []) =>
node === None
? undefined
: match1 (s, node) || match (s, rest)
console .log
( match ("men/tops", data) // { slugs: [ men, tops ], ... }
, match ("women/bottoms", data) // { slugs: [ women, bottoms ], ... }
, match ("cat/dog", data) // undefined
)
Небольшая адаптация позволяет нам собирать все результаты вместо остановки после первого матча -
const EmptyNode =
{ slugs: []
, children: []
}
const match1 = (s = "", node = EmptyNode) =>
node.slugs .join ('/') === s
? [ node, ...match (s, node.children) ]
: match (s, node.children)
const match = (s = "", nodes = []) =>
nodes .flatMap (x => match1 (s, x))
console .log
( match ("men/tops", data) // [ ... all matches ... ]
, match ("cat/dog", data) // []
)
Эй, смотри, мы вернули значение , даже не используя return
. Спасибо, функциональный стиль.