提问人:lala 提问时间:11/15/2022 最后编辑:lala 更新时间:11/15/2022 访问量:191
从无限嵌套的对象数组中获取数据
get data from unlimited nested array of objects
问:
我得到了这个数据结构:-
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: [] },
]
目前,我正在尝试删除选定的行及其子行。但同时也需要删除孩子的孩子的孩子的......的选定行。
答:我只能使用下面的代码成功删除选定的行及其直接子行。
// 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.但是在尝试递归方式时不成功。有超出限制的东西
// 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
如何调整代码以使其正常工作?
答:
0赞
Bhavya Dhiman
11/15/2022
#1
这是我的解决方案。首先,我创建了一个函数,可以调用我要删除的级别。 对于子项,我调用了一种递归方法,在这种方法中,我还检查嵌套子项不会一次又一次地重复以获得无限循环。
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);
评论
type===obj || type===arrayObj
children