Me gustaría encontrar el padre de un elemento determinado en una matriz recursiva
{ "uuid": "707a5ffd-68e2-4dbd-b539-128512ba3a0a", "type": "page", "items": [ { "uuid": "9d823429-cc24-444d-a21c-a81357305851", "title": "1", "type": "question", }, { "type": "section", "title": "2", "uuid": "346dec94-124c-4932-bd40-af9dc68f1d27", "items": [ { "uuid": "bf0a9ab9-99cc-4833-b3d3-84a97072e85f", "title": "2.1", "type": "question", } ], }, { "type": "section", "title": "3", "uuid": "4964096d-0de9-4ab1-ace5-e42516d6b866", "items": [ { "uuid": "b2170580-1e2e-4fb4-a7b9-a56b79db21b3", "title": "3.1", "type": "question", } ], } ], "params": { "collapsed": false } }He intentado hasta ahora:
export const findItemParent = (items, id, parent = null) => { if (parent && parent.id === id) { return parent; } for (const item of items) { if (Object.prototype.hasOwnProperty.call(item, 'items')) { return findItemParent(item.items, id, item); } } return parent; }; Entonces estoy llamando a findItemParent como:
const data = [{...}]; // the data of the first snipet // b2170580-1e2e-4fb4-a7b9-a56b79db21b3 -> item with title 3.1 const parent = findItemParent(data, "b2170580-1e2e-4fb4-a7b9-a56b79db21b3"); Cada vez que ejecuto este código, obtengo que el padre es 2 .
En el caso anterior, estoy pasando la identificación del elemento con el título 3.1 , por lo que lógicamente el padre es 3 . ¿Cómo puedo obtener el padre de cualquier artículo dado el id?
Usando recursividad, esto es lo que se me ocurrió.
Los items de parámetro, diría que son un poco engañosos, habría usado algo como root.
const findItemParent = (root, id, parent = null) => { if (root.uuid === id) return parent; if ('items' in root) { for (const i of root.items) { const r = findItemParent(i, id, root); if (r) return r; } } return null; }; const data = { "uuid": "707a5ffd-68e2-4dbd-b539-128512ba3a0a", "type": "page", "items": [ { "uuid": "9d823429-cc24-444d-a21c-a81357305851", "title": "1", "type": "question", }, { "type": "section", "title": "2", "uuid": "346dec94-124c-4932-bd40-af9dc68f1d27", "items": [ { "uuid": "bf0a9ab9-99cc-4833-b3d3-84a97072e85f", "title": "2.1", "type": "question", } ], }, { "type": "section", "title": "3", "uuid": "4964096d-0de9-4ab1-ace5-e42516d6b866", "items": [ { "uuid": "b2170580-1e2e-4fb4-a7b9-a56b79db21b3", "title": "3.1", "type": "question", } ], } ], "params": { "collapsed": false } }; const findItemParent = (root, id, parent = null) => { if (root.uuid === id) return parent; if ('items' in root) { for (const i of root.items) { const r = findItemParent(i, id, root); if (r) return r; } } return null; }; const parent = findItemParent(data, "b2170580-1e2e-4fb4-a7b9-a56b79db21b3"); if (parent) console.log(parent.title, parent.type, parent.uuid);Puede usar una función recursiva para iterar sobre los elementos de cada elemento.
const data = { "uuid": "707a5ffd-68e2-4dbd-b539-128512ba3a0a", "type": "page", "items": [ { "uuid": "9d823429-cc24-444d-a21c-a81357305851", "title": "1", "type": "question", }, { "type": "section", "title": "2", "uuid": "346dec94-124c-4932-bd40-af9dc68f1d27", "items": [ { "uuid": "bf0a9ab9-99cc-4833-b3d3-84a97072e85f", "title": "2.1", "type": "question", } ], }, { "type": "section", "title": "3", "uuid": "4964096d-0de9-4ab1-ace5-e42516d6b866", "items": [ { "uuid": "b2170580-1e2e-4fb4-a7b9-a56b79db21b3", "title": "3.1", "type": "question", } ], } ], "params": { "collapsed": false } }; function findItemParent(items, id, parent = null) { if (items.find(item => item.uuid === id)) return { uuid: parent?.uuid, type: parent?.type, title: parent?.title }; for (const item of items) { let p; if (item.type === 'section') { p = findItemParent(item.items, id, item); } if (p) return p; } } console.log(findItemParent(data.items, "b2170580-1e2e-4fb4-a7b9-a56b79db21b3"));Haría un mapa donde tienes una referencia al padre en el árbol. Esto es útil si tiene muchas búsquedas.
const book = { "uuid": "707a5ffd-68e2-4dbd-b539-128512ba3a0a", "type": "page", "items": [ { "uuid": "9d823429-cc24-444d-a21c-a81357305851", "title": "1", "type": "question", }, { "type": "section", "title": "2", "uuid": "346dec94-124c-4932-bd40-af9dc68f1d27", "items": [ { "uuid": "bf0a9ab9-99cc-4833-b3d3-84a97072e85f", "title": "2.1", "type": "question", } ], }, { "type": "section", "title": "3", "uuid": "4964096d-0de9-4ab1-ace5-e42516d6b866", "items": [ { "uuid": "b2170580-1e2e-4fb4-a7b9-a56b79db21b3", "title": "3.1", "type": "question", } ], } ], "params": { "collapsed": false } }; function walkTree(group, parentRef, titleMapping) { titleMapping = titleMapping || {}; group.items.forEach(function (item) { titleMapping[item.title] = { ...item, parentRef }; if (item.items) walkTree(item, titleMapping[item.title], titleMapping); }); return titleMapping; } const titleMapping = walkTree(book); console.log(titleMapping["3.1"].parentRef.title);Otra opción es usar una búsqueda recursiva donde mira para ver si los elementos contienen el título.