I got this data structure:-
interface DataType {
level: number;
type: string | number | arrayString | arrayNumber | arrayObj | obj;
key: string;
value: any;
children: number[] // will store index of children
}
const data = [
{ level: 1, type: 'obj', key: 'obj1', value: {}, children: [1, 2] },
{ level: 2, type: 'string', key: 'obj1 child', value: 'child string', children: [] },
{ level: 2, type: 'obj', key: 'obj1 child obj', value: {}, children: [3] },
{ level: 3, type: 'obj', key: 'obj1-1', value: {}, children: [4] },
{ level: 4, type: 'obj', key: 'obj1-1-1', value: {}, children: [5] },
{ level: 5, type: 'string', key: 'obj1-1-1-1', value: 'last nest', children: [] },
]
Currently I'm trying to delete selected row & it's children. But in the same time also need to delete children's children's child... of selected row.
A. I only successfully able to delete selected row & it's direct children with the code below.
// let say current we inside .map of above data array of objects
// thus, we gonna have 'item' & 'index`
<button
onClick={(): void => {
let index2Delete: number[] = []
data.forEach((item2, index2) => {
if(index2 === index) {
// include curr data index to be deleted later
index2Delete.push(index2)
// include children indexes to be deleted if have any
if(item2.children.length > 0) {
index2Delete = [...index2Delete, ...item2.children]
}
}
})
// filter those that need to be deleted
const filtered = data.filter((item2, index2) => !index2Delete.includes(index2))
// update new data list
handleUpdateNewDataList(filtered)
}}
>
Delete
</button
B. But unsuccessful when trying to do recursive way. Got exceed limit something
// let say current we inside .map of above data array of objects
// thus, we gonna have 'item' & 'index`
<button
onClick={(): void => {
let index2Delete: number[] = []
const repeatThis = (mainIndex: number) => {
data.forEach((item2, index2) => {
if(index2 === mainIndex) {
// include curr data index to be deleted later
// check first if already include index, since we're repeating this func
if(!index2Delete.includes(index2))
index2Delete.push(index2)
// include children indexes to be deleted if have any
if(item2.children.length > 0) {
index2Delete = [...index2Delete, ...item2.children]
// check if children got their own children
item2.children.forEach((item3, index3) => {
const childInfo = data.find((item4, index4) => index4 === item3)
if(childInfo?.children.length > 0)
repeatThis(index3)
})
}
}
})
}
// run for main index
repeatThis(index)
// filter those that need to be deleted
const filtered = data.filter((item2, index2) => !index2Delete.includes(index2))
// update new data list
handleUpdateNewDataList(filtered)
}}
>
Delete
</button
How can I adjust my code to make this work?
CodePudding user response:
Here is my solution. First I created a function which calls out the levels I want to delete. For children, I called a recursive approach in which I also check that nested children won't repeat again and again to get infinite loop.
let data = [
{ level: 1, type: 'obj', key: 'obj1', value: {}, children: [1, 2] },
{ level: 2, type: 'string', key: 'obj1 child', value: 'child string', children: [] },
{ level: 2, type: 'obj', key: 'obj1 child obj', value: {}, children: [3] },
{ level: 3, type: 'obj', key: 'obj1-1', value: {}, children: [4] },
{ level: 4, type: 'obj', key: 'obj1-1-1', value: {}, children: [5] },
{ level: 5, type: 'string', key: 'obj1-1-1-1', value: 'last nest', children: [] },
];
const levelToDelete = [];
const deleteChildrenData = (data, children, curr) => {
// console.log('CHILDREN', children);
children.forEach(c => {
levelToDelete.push(c);
const childIndexes = [];
data.forEach((d, indx) => {
if (d.level === c && curr.level !== c) {
childIndexes.push(indx);
}
});
if (childIndexes.length) {
childIndexes.forEach(innerC => {
console.log('DATA INNER C,', data[innerC]);
const nestedChildren = data[innerC].children.filter(c => c !== curr.level);
if (nestedChildren.length > 0) {
deleteChildrenData(data, nestedChildren, data[innerC]);
}
});
}
});
}
const deleteData = (data, index) => {
data.forEach((curr, innerIndex) => {
if (innerIndex === index) {
levelToDelete.push(curr.level);
if (curr.children.length && curr.type === 'arrObj' || curr.type === 'obj') {
const filteredChildren = curr.children.filter(c => c !== curr.level);
deleteChildrenData(data, filteredChildren, curr);
}
}
} )
}
deleteData(data, 0, []);
// filter those that need to be deleted
console.log(levelToDelete);
const filtered = data.filter((item2, index2) => !levelToDelete.includes(item2.level))
console.log(filtered);