Las respuestas en este hilo y en otros lugares en los que he buscado solo funcionan si se conoce "parent_id" para cada objeto en la matriz.
¿Y si la única propiedad de los objetos es la depth ?
La profundidad esencialmente me dice si el elemento es un "nodo raíz" ( depth de 1) o un "nodo secundario" ( depth de 2 o más).
El padre de un niño es el objeto directamente antes de él si el objeto anterior tiene una depth menor. (La profundidad del padre siempre debe ser 1 más que su hijo).
Si un objeto y el objeto anterior tienen la misma depth , entonces en realidad son hermanos en el mismo nivel.
Si el objeto anterior tiene una depth mayor, entonces el elemento actual es en realidad el hermano del elemento anterior anterior que tiene la misma depth (o también puede verlo como el elemento secundario del elemento anterior anterior que tiene una depth menor)
P.ej
// Please note "name" in the example below // is just for illustrative purposes. // My actual array will have random names const items = [ { name: "1", depth: 1, }, { name: "2", depth: 1, }, { name: "2_1", depth: 2, }, { name: "2_1_1", depth: 3, }, { name: "2_1_2", depth: 3, }, { name: "2_2", depth: 2, }, ]Entonces me gustaría convertir esa matriz plana en un árbol como:
const newItems = [ { name: "1", depth: 1, children: [], }, { name: "2", depth: 1, children: [ { name: "2_1", depth: 2, children: [ { name: "2_1_1", depth: 3, children: [], }, { name: "2_1_2", depth: 3, children: [], }, ], }, { name: "2_2", depth: 2, children: [], }, ], }, ]Puede tomar una matriz auxiliar para los niveles y asignar el objeto a la última matriz de depth .
const items = [{ name: "1", depth: 1 }, { name: "2", depth: 1 }, { name: "2_1", depth: 2 }, { name: "2_1_1", depth: 3 }, { name: "2_1_2", depth: 3 }, { name: "2_2", depth: 2 }], tree = [], levels = [tree]; items.forEach(o => levels[o.depth - 1].push({ ...o, children: levels[o.depth] = [] }) ); console.log(tree); .as-console-wrapper { max-height: 100% !important; top: 0; }