Tengo una matriz de json como esa:
y este es mi código para eliminar un elemento específico con todos sus hijos secundarios...:
const items = [ {id: 1, name: 'Block', text: '', has_childs: true, parent_id : null}, {id: 2, name: 'Block', text: '', has_childs: true, parent_id : 1}, {id: 3, name: 'Block', text: '', has_childs: false, parent_id : 1}, {id: 4, name: 'Block', text: '', has_childs: true, parent_id : 2}, {id: 5, name: 'Block', text: '', has_childs: false, parent_id : 2}, {id: 6, name: 'Block', text: '', has_childs: false, parent_id : 2}, {id: 7, name: 'Block', text: '', has_childs: false, parent_id : 4} ]; function removeItem(item){ var index = items.findIndex(function (o) { return o.id == item.id; }) if (index !== -1) { var hasOtherChilds = false; items.forEach((i) => { if(i.parent_id == item.parent_id) hasOtherChilds = true; }); items.forEach((i)=> { if(i.id == item.parent_id && !hasOtherChilds) i.has_childs = false; } ) if (items[index].has_childs == true) { var items_to_remove = []; items.forEach((i) => { if (i.parent_id == item.id) { items.splice(index, 1); items_to_remove.push(i); } }); }else { items.splice(index, 1); } } if(items_to_remove) items_to_remove.forEach((item) => { removeItem(item); }); } console.log(items); removeItem(items[1]); console.log(items)Pero por alguna razón, siempre solo borra el primer hijo/subhijo y el último hijo/subhijo. No tengo idea de por qué.
Puede almacenar los ID para eliminarlos en una matriz. Entonces en cada iteración en el filtro verificamos
si la id existe en la matriz, si existe, devolvemos falso. si no existe, verificamos si parentId existe en la matriz, si existe, insertamos la id en la matriz y devolvemos falso. por fin, si las dos condiciones anteriores fallan, devolvemos verdadero.
Verifique el siguiente fragmento.
const items = [{ id: 1, name: 'Block', text: '', has_childs: true, parent_id: null }, { id: 2, name: 'Block', text: '', has_childs: true, parent_id: 1 }, { id: 3, name: 'Block', text: '', has_childs: true, parent_id: null }, { id: 4, name: 'Block', text: '', has_childs: true, parent_id: 2 }, { id: 5, name: 'Block', text: '', has_childs: false, parent_id: 2 }, { id: 6, name: 'Block', text: '', has_childs: false, parent_id: 2 }, { id: 7, name: 'Block', text: '', has_childs: false, parent_id: 4 } ]; function remove(arr, id) { const idToRemove = [id]; return items .filter((item) => { if (idToRemove.includes(item.id)) return false; if (idToRemove.includes(item.parent_id)) { idToRemove.push(item.id); return false; } else return true; }); } const filteredItems = remove(items, 1); filteredItems.forEach(item => console.log(item)); //verify the right ones are goneAquí hay más sobre el filtro
Una solución que elimina recursivamente todos los elementos secundarios y luego el elemento original en sí. Tenga en cuenta que la propiedad has_childs es completamente inútil en este proceso.
let items = [ {id: 1, name: 'Block', text: '', parent_id : null}, {id: 2, name: 'Block', text: '', parent_id : 1}, {id: 3, name: 'Block', text: '', parent_id : 1}, {id: 4, name: 'Block', text: '', parent_id : 2}, {id: 5, name: 'Block', text: '', parent_id : 2}, {id: 6, name: 'Block', text: '', parent_id : 2}, {id: 7, name: 'Block', text: '', parent_id : 4} ]; const removeItem = item => { // Selecting all children const children = items.filter(i => i.parent_id===item.id); for(let child of children){ console.log(`Removing child ${child.id}`) removeItem(child) // Will recursively remove all of their children } // Removing the original item itself, after removing all its children recursively items = items.filter(i => i.id !== item.id) } removeItem({id: 2, name: 'Block', text: '', parent_id : 1}) console.log("Items are now =", items)¿No puede tener una función simple para filtrar los valores? Según la estructura de la matriz que desea filtrar (no está anidada), no veo ninguna necesidad de recursividad.
const items = [ {id: 1, name: 'Block', text: '', has_childs: true, parent_id : null}, {id: 2, name: 'Block', text: '', has_childs: true, parent_id : 1}, {id: 3, name: 'Block', text: '', has_childs: true, parent_id : 1}, {id: 4, name: 'Block', text: '', has_childs: true, parent_id : 2}, {id: 5, name: 'Block', text: '', has_childs: false, parent_id : 2}, {id: 6, name: 'Block', text: '', has_childs: false, parent_id : 2}, {id: 7, name: 'Block', text: '', has_childs: false, parent_id : 4} ]; function remove(arr, id) { const removed = new Set([id]); return arr.filter(item => { if (removed.has(item.parent_id)) { removed.add(item.id); return false; } return !removed.has(item.id); }); } //suppose we want to remove id = 2 and all its progeny const filteredItems = remove(items, 2); filteredItems.forEach(item => console.log(item));