0

I have a huge array of objects. These objects are like this:

data = [
    {
        content: {
            ...,
            depth: 1
        },
        subContent: []
    },
    {
        content: {
            ...,
            depth: 2
        },
        subContent: []
    },
    {
        content: {
            ...,
            depth: 3
        },
        subContent: []
    },{
        content: {
            ...,
            depth: 2
        },
        subContent: []
    },
    {
        content: {
            ...,
            depth: 1
        },
        subContent: []
    },
]

I need it like this:

result = [
    {
        content: {
            ...,
            depth: 1
        },
        subContent: [
            {
                content: {
                    ...,
                    depth: 2
                },
                subContent: [
                    {
                        content: {
                            ...,
                            depth: 3
                        },
                        subContent: []
                    }
                ]
            },
            {
                content: {
                    ...,
                    depth: 2
                },
                subContent: []
            },
        ], 
        {
            content: {
                ...,
                depth: 1
            },
            subContent: []
        },
    },
]

I need the result array with the larger depth number inside the previous smaller subContent. I used a for loop starting at the end of the array and going i--, where I push the higher depth inside the next subContent if its depth+1 is equal to the depth and remove the index from array after.

for (let i = arr.length-1; i > 0; i--) {
  if (arr[i].content.depth === arr[i-1].content.depth + 1) {
    arr[i-1].subContent.push(arr[i]);
    arr.splice(i, 1);
  } else {
    let index = this.findNextLowerIndex(arr[i].content.depth, arr);
    
    // console.log(index);
    if (arr[index]) {
      arr[index].subContent.push(arr[i]);
      arr.splice(i, 1);
    }
  }
}




findNextLowerIndex(depth: number, arr: any[]): number {
    let findIndex = depth - 1;

    for (let i = arr.length-1; i > 0; i--) {
        if (arr[i].content.depth === findIndex) {
            return i;
        }
    }
}

This kind of works execpt for when there are several subContent when the layers of the array are like 4, 3, 4, 3, 2, 1. What I get is 4->3 nested, 4->3->2->1 nested but not 4->3 nested inside the 2 of the 4->3->2->1 nested. Something is missing when there are several layers with subContents.

Any ideas?

2 Answers 2

2

Are you looking something like this ?

let data = [{ content: { depth: 1 }, subContent: [] }, { content: { depth: 2 }, subContent: [] }, { content: { depth: 3 }, subContent: [] }, { content: { depth: 2 }, subContent: [] }, { content: { depth: 1 }, subContent: [] },]
let result = [];
for (let item of data) {
    let node = data.find(v => v.content.depth == item.content.depth - 1)?.subContent || result
    node.push(item)
}
console.log(result)

Sign up to request clarification or add additional context in comments.

Comments

1

I think this will be the solution that you are looking for.

const data = [
  { content: { depth: 1 }, subContent: [] },
  { content: { depth: 2 }, subContent: [] },
  { content: { depth: 3 }, subContent: [] }, 
  { content: { depth: 2 }, subContent: [] },
  { content: { depth: 1 }, subContent: [] },
];

const res = data.reduce((acc, curr) => {
  if (curr.content.depth === 1) {
    acc.push(curr);
  } else {
    let node = acc[acc.length - 1]; // Selecting last node
    while (node.content.depth !== curr.content.depth - 1) {
      if (node.subContent) {
        node = node.subContent[node.subContent.length - 1];
      } 
    }
    node.subContent.push(curr);
  }
  return acc;
}, []);

console.log(res);

1 Comment

Thanks so much! I had to adjust a little because my real data starts with depth 0. I cant believe you solved that so quick

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.