РЕДАКТИРОВАТЬ: Помимо других решений этой проблемы, я также хотел бы понять, если у такого рода рекурсивных или рекурсивных проблем есть образец, есть ли название технике, которую я использовал (то есть, чтобы передать объект ссылка на разрыв будущей рекурсии на основе изменений объекта)? Полезна ли эта техника в некоторых других сценариях?
Я ищу значение в древовидном дереве, и как только оно найдено, я хочу нарушить рекурсию (есть другие базовые случаи, чтобы сломать пример). Вот как выглядит код:
function getCommentById(root, commentId, foundComment) {
if (root.id === commentId) {
return root;
}
if (foundComment.comment) {
return foundComment.comment;
}
if (!root.comments) {
return foundComment.comment;
} else {
for (let i = 0; i < root.comments.length; i++) {
foundComment.comment = getCommentById(
root.comments[i],
commentId,
foundComment
);
}
}
return foundComment.comment;
}
В основном я просматриваю вложенные комментарии, чтобы найти комментарий по его идентификатору.
Мне нужно перебрать все дочерние элементы текущего комментария и вызвать эту функцию рекурсивно. Допустим, я нашел комментарий в child1 текущего комментария, я хотел бы больше не повторять его и просто выйти из рекурсии, но цикл продолжится до следующего родного брата и повторения.
Такого рода вещи были просты в двоичном дереве, так как я мог просто сделать что-то вроде
return getCommentById(left) || getCommentById(right)
но у меня возникли проблемы с реализацией той же логики здесь, потому что нам нужно было бы каким-то образом хранить результат каждого дочернего вызова, и на основании этого решить, нашли ли мы значение или нет. Таким образом, мое решение использует вспомогательную переменную, которая обозначает, когда значение было найдено. Я понял, что это должен быть объект, а не переменная, чтобы изменение значения было видно при последующем вызове рекурсии от child1 к child2. Это было бы невозможно, если бы я только использовал флаг и установил его в true в рекурсии child1, потому что тогда рекурсия child2 все равно увидит флаг как false и продолжит рекурсию.
Есть ли лучший подход?
Есть ли название для этого метода использования ссылки на объект для прерывания рекурсии? Как еще это можно реализовать?
РЕДАКТИРОВАТЬ: набор данных для тестирования
const post = {
id: "post1",
title: "Sample Post 1",
description: "This is a sample post",
createdBy: "user1",
createdAt: new Date(),
comments: [
{
id: "post1comment1",
text: "This is comment 1",
userId: "user1",
timestamp: new Date().setFullYear(2018),
comments: [
{
id: "post1comment1.1",
text: "This is sub comment 1 of comment 1",
userId: "user2",
timestamp: new Date()
}
]
},
{
id: "post1comment2",
text: "This is comment 2",
userId: "user4",
timestamp: new Date()
},
{
id: "post1comment3",
text: "This is comment 3",
userId: "user4",
timestamp: new Date()
}
]
},
использование:
const foundComment = { comment: null };
getCommentById(post, "post1comment1.1", foundComment);