Home > OS >  get data from unlimited nested array of objects
get data from unlimited nested array of objects

Time:11-15

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