Actualmente estoy tratando de eliminar de una matriz de objetos si se elimina el padre.
Mi matriz se ve así:
const items = [ { id: '1' generatedFrom: undefined }, { id: '2', generatedFrom: '1', }, { id: '3', generatedFrom: '2' }, { id: '4', generatedFrom: '1' } ]Tengo un método que filtra los objetos según la identificación que estoy pasando al método:
const removeFromArray = (id: string) => { const filtered = items.filter(item => item.id !== id); }Esto me da los resultados correctos que esperaba en términos de eliminar el objeto principal. Sin embargo, el problema que tengo es que esto debería tener un efecto en cadena para el resto de los objetos dentro de la matriz.
Si tomas el ejemplo anterior:
2 , entonces debería eliminar items[1]items[2] se generan a partir de la identificación 2 , este también debe eliminarse.items[3] deben seguir existiendo ya que el padre todavía está allí.Esta podría ser una matriz que tiene muchos elementos dentro y no estoy seguro de cómo abordarla.
Ejemplo de problema actual:
const items = [ { id: 1, generatedFrom: undefined }, { id: 2, generatedFrom: 1 }, { id: 3, generatedFrom: 2 }, { id: 4, generatedFrom: 3 }, { id: 5, generatedFrom: 4 }, { id: 6, generatedFrom: 1 } ] const removeFromArray = (id) => { return items.filter(item => item.id !== id && item.generatedFrom !== id); } console.log(removeFromArray(2)); // Expected Output: const expected = [ { id: 1, generatedFrom: undefined }, { id: 6, generatedFrom: 1 } ]Dado que teóricamente podría tener un nivel ilimitado de profundidad, no creo que una llamada a Array.prototype.* sea suficiente aquí. El enfoque de un principiante sería la recursividad, pero puede modificarlo en un proceso de cola:
const items = [ { id: 1, generatedFrom: undefined }, { id: 2, generatedFrom: 1 }, { id: 3, generatedFrom: 2 }, { id: 4, generatedFrom: 3 }, { id: 5, generatedFrom: 4 }, { id: 6, generatedFrom: 1 } ]; const removeFromArray=(id:number)=>{ let queue:number[]=[id]; let rst=[...items]; while(queue.length>0){ let hd=queue.shift(); rst=rst.filter((item)=>{ if(item.id==hd){ return false; } if(item.generatedFrom==hd){ queue.push(item.id); return false; } return true; }); } return rst; }; console.log(removeFromArray(2)); Eliminar 2 te dará
[{ "id": 1, "generatedFrom": undefined }, { "id": 6, "generatedFrom": 1 }]Podrías probar con una recursividad:
const items = [ { id: 1, generatedFrom: undefined }, { id: 2, generatedFrom: 1 }, { id: 3, generatedFrom: 2 }, { id: 4, generatedFrom: 3 }, { id: 5, generatedFrom: 4 }, { id: 6, generatedFrom: 1 } ] const removeFromArray = (id, items) => { items = items.filter(x => x.id !== id); // remove element with id == id // recursively find orphan objects let index = items.findIndex(obj => obj.generatedFrom === id); if (index !== -1) { let newId = items[index].id; items = items.filter(x => x.generatedFrom !== id); return removeFromArray(newId, items) } else return items; } console.log(removeFromArray(2, items));Dos pasos:
id === id ;id original y recupere la función filtrando la matriz de resultados.Puede usar una función recursiva, le aconsejo que use un Set para evitar bucles infinitos o eliminaciones repetidas:
const items = [ { id: 1, generatedFrom: undefined }, { id: 2, generatedFrom: 1 }, { id: 3, generatedFrom: 2 }, { id: 4, generatedFrom: 3 }, { id: 5, generatedFrom: 4 }, { id: 6, generatedFrom: 1 } ] const ids = new Set(); const deleteById = (id, items) => { ids.delete(id); let filtered = items.filter(item => { if (item.id === id || item.generatedFrom === id) { if(item.id) ids.add(item.id); return false; } return true; }); const it = ids.values(); let next = it.next(); while (!next.done) { const value = next.value; filtered = deleteById(value, filtered); next = it.next(); } return filtered; } console.log(deleteById(2, items));