JSFiddle - React, Tailwind, and code Playground
HTML
<pre id="text"></pre>
CSS
#text {
font-family: "SF Mono","Monaco","Andale Mono","Lucida Console","Bitstream Vera Sans Mono","Courier New",Courier,monospace;
font-size: 13px;
}
JavaScript
const items = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4, children: [{ id: 6 }, { id: 7, children: [{ id: 8 }, { id: 9 }] }] }, { id: 5 }];
function findNode(list, id) {
return list.find(node => node.id === id) ||
list.reduce((result, node) => {
return result ||
node.children && findNode(node.children, id)
}, false)
}
// функция принимает некий узел
function findParent(list, node) {
function f(acc, el) {
// если на предыдущих шагах уже был найден ответ, то вернём его
if(acc) return acc
// если у объекта есть массив потомков && любой из его потомков равен node
// значит родитель найден, возвращаем его как результат
if(el.children && el.children.some(child => child === node)) return el
// в ином случае проведём такой же поиск среди потомков объекта
if(el.children) return el.children.reduce(f, acc)
// в случае, если у этого объекта и его потомков не найдено подходящего
// тогда передадим null в дальнейший поиск
return acc
}
// запускаем рекурсивный поиск здесь
return list.reduce(f, null);
}
let obj6 = findNode(items, 6)
let currentObj = obj6
// заменяем currentObj на его родителя пока поиск не вернёт null
while (currentObj = findParent(items, currentObj)) {
// для всех родителей устанавливаем параметр
currentObj.open = true
}
document.getElementById('text').innerHTML =
JSON.stringify(items, null, 2)