从无限嵌套的对象数组中获取数据

get data from unlimited nested array of objects

提问人:lala 提问时间:11/15/2022 最后编辑:lala 更新时间:11/15/2022 访问量:191

问:

我得到了这个数据结构:-

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

如何调整代码以使其正常工作?

JavaScript 打字稿 多维数组 嵌套列表

评论

0赞 Bhavya Dhiman 11/15/2022
obj型会有孩子吗?右?
0赞 lala 11/15/2022
是的。只有将被填充。type===obj || type===arrayObjchildren
0赞 Bhavya Dhiman 11/15/2022
明白了!由于您还将 1 作为 1 的子项放置,因此调用堆栈最大化的原因!
0赞 lala 11/15/2022
你是什么意思?对不起,我不明白
1赞 Bhavya Dhiman 11/15/2022
级别 1 有一个子级,即 1 级,该子级进入循环。1-> 1-> 1->1.但是我解决了!

答:

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);