Tengo el siguiente objeto JavaScript:
esta es básicamente una lista de comentarios, la lista real es mucho más larga y más anidada, por lo que esta es una versión simplificada.
[ { id: 200, comment: "If you have any question, please comment here.", depth: 1, parent_id: null, comments: [], }, { id: 201, comment: "Hi, I'm stuck at the installation of node.js. Can I ask help?", depth: 2, parent_id: 200, comments: [], }, { id: 202, comment: "This is a detailed explanation, great.", depth: 1, parent_id: null, comments: [], }, { id: 203, comment: "Hello! That's weird. Do you have a screenshot?", depth: 3, parent_id: 201, comments: [], }, ]Quiero convertir lo anterior a lo siguiente. Pero creo que uso .map o similar, pero no tengo una idea clara de cómo implementar esto.
[ { id: 200, comment: "If you have any question, please comment here.", depth: 1, parent_id: null, comments: [ { id: 201, comment: "Hi, I'm stuck at the installation of node.js. Can I ask help?", depth: 2, parent_id: 200, comments: [ { id: 203, comment: "Hello! That's weird. Do you have a screenshot?", depth: 3, parent_id: 201, comments: [], }, ], }, ], }, { id: 202, comment: "This is a detailed explanation, great.", depth: 1, parent_id: null, comments: [], }, ]Gracias.
una solución con array.reduce
var data = [ { id: 200, comment: "If you have any question, please comment here.", depth: 1, parent_id: null, comments: [], }, { id: 201, comment: "Hi, I'm stuck at the installation of node.js. Can I ask help?", depth: 2, parent_id: 200, comments: [], }, { id: 202, comment: "This is a detailed explanation, great.", depth: 1, parent_id: null, comments: [], }, { id: 203, comment: "Hello! That's weird. Do you have a screenshot?", depth: 3, parent_id: 201, comments: [], }, ]; const result = data.reduce((acc, curr) => { let parent = (curr.parent_id) ? data.filter(el => el.id === curr.parent_id) : []; if (parent.length) { parent[0].comments.push(curr); } else { acc.push(curr); } return acc; }, []); console.log(result);Un enfoque que parece funcionar es usar un bucle doble con forEach() y una declaración condicional para insertar los elementos dentro de la matriz de comments si se cumplen las condiciones.
let data = [ { id: 200, comment: "If you have any question, please comment here.", depth: 1, parent_id: null, comments: [], }, { id: 201, comment: "Hi, I'm stuck at the installation of node.js. Can I ask help?", depth: 2, parent_id: 200, comments: [], }, { id: 202, comment: "This is a detailed explanation, great.", depth: 1, parent_id: null, comments: [], }, { id: 203, comment: "Hello! That's weird. Do you have a screenshot?", depth: 3, parent_id: 201, comments: [], }, ] data.forEach((el_one) => { data.forEach((el_two) => { if(el_one.parent_id === el_two.id){ el_two.comments.push(el_one) } }) }) console.log(data)Cree un objeto simple con elementos, recorra su matriz y coloque todos los elementos secundarios en el campo de comments accediendo al elemento principal correspondiente a través de ese objeto simple. Luego, filtre todos los elementos que no sean raíz (supongo que sus datos se almacenan en la matriz llamada data ):
// Fill in id-accessed storage var elements_by_id = {}; data.forEach((el) => elements_by_id[el.id] = el ); // Feed comments data.forEach((el) => el.parent_id ? ( elements_by_id[el.parent_id].comments.push(el) ) : '' ); // Remove non-root elements data = data.filter( (el) => !el.parent_id );