1

I have the following JavaScript object:

this is basically a list of comments, the actual list is much longer and more deeply nested, so this is a simplified version.

[
    {
        id: 200,
        comment: "If you have any question, please comment here.",
        depth: 1,
        parent_id: null, 
        comments: [],
    },
    {
        id: 201,
        comment: "Hi, I'm stuck at the installation of node.js. Can I ask help?",
        depth: 2,
        parent_id: 200, 
        comments: [],
    },
    {
        id: 202,
        comment: "This is a detailed explanation, great.",
        depth: 1,
        parent_id: null, 
        comments: [],
    },
    {
        id: 203,
        comment: "Hello! That's weird. Do you have a screenshot?",
        depth: 3,
        parent_id: 201, 
        comments: [],
    },
]

I want to convert the above to the following. But I think I use .map or similar, but I don't have a clear idea of how to implement this.

[
    {
        id: 200,
        comment: "If you have any question, please comment here.",
        depth: 1,
        parent_id: null, 
        comments: [
            {
                id: 201,
                comment: "Hi, I'm stuck at the installation of node.js. Can I ask help?",
                depth: 2,
                parent_id: 200, 
                comments: [                    
                    {
                        id: 203,
                        comment: "Hello! That's weird. Do you have a screenshot?",
                        depth: 3,
                        parent_id: 201, 
                        comments: [],
                    },
                ],
            },
        ],
    },
    {
        id: 202,
        comment: "This is a detailed explanation, great.",
        depth: 1,
        parent_id: null, 
        comments: [],
    },
]

Thanks.

3 Answers 3

2

a solution with array.reduce

var data = [
    {
        id: 200,
        comment: "If you have any question, please comment here.",
        depth: 1,
        parent_id: null, 
        comments: [],
    },
    {
        id: 201,
        comment: "Hi, I'm stuck at the installation of node.js. Can I ask help?",
        depth: 2,
        parent_id: 200, 
        comments: [],
    },
    {
        id: 202,
        comment: "This is a detailed explanation, great.",
        depth: 1,
        parent_id: null, 
        comments: [],
    },
    {
        id: 203,
        comment: "Hello! That's weird. Do you have a screenshot?",
        depth: 3,
        parent_id: 201, 
        comments: [],
    },
];


const result = data.reduce((acc, curr) => {
  let parent = (curr.parent_id) ? data.filter(el => el.id === curr.parent_id) : [];
  if (parent.length) {
    parent[0].comments.push(curr);
  } else {
    acc.push(curr);
  }
  return acc;
}, []);
console.log(result);

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

Comments

1

One approach to seem to work is by using a double loop with forEach() and a conditional statement to push the elements inside the comments array if conditions are met.

let data = [
    {
        id: 200,
        comment: "If you have any question, please comment here.",
        depth: 1,
        parent_id: null, 
        comments: [],
    },
    {
        id: 201,
        comment: "Hi, I'm stuck at the installation of node.js. Can I ask help?",
        depth: 2,
        parent_id: 200, 
        comments: [],
    },
    {
        id: 202,
        comment: "This is a detailed explanation, great.",
        depth: 1,
        parent_id: null, 
        comments: [],
    },
    {
        id: 203,
        comment: "Hello! That's weird. Do you have a screenshot?",
        depth: 3,
        parent_id: 201, 
        comments: [],
    },
]

data.forEach((el_one) => {
  data.forEach((el_two) => {
    if(el_one.parent_id === el_two.id){
     el_two.comments.push(el_one)  
    }
  })
})

console.log(data)

1 Comment

i think you should sort() data by depth first :
0

Create a plain object with elements, walk through your array and place all children elements into the comments field accessing corresponding parent element via that plain object. Then filter out all non-root elements (i assume your data is stored in the array named data):

// Fill in id-accessed storage
var elements_by_id = {};
data.forEach((el) => elements_by_id[el.id] = el );

// Feed comments
data.forEach((el) => el.parent_id ? ( elements_by_id[el.parent_id].comments.push(el) ) : '' );

// Remove non-root elements
data = data.filter( (el) => !el.parent_id );

Comments

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.