1

I want to the update the object of id 21, make reply to false.

const arr = [ {id: 1, comment:'parent 01', parentId:null, reply:true, children:[{id: 11, comment:'child', reply:true, parentId:1, children:[{id: 21, comment:'super child ', reply:true,parentId:11 }] }] }, {id: 2, comment:'parent 02', reply:true, parentId:null } ]

result should be:

const arr = [ {id: 1, comment:'parent 01', parentId:null, reply:true, children:[{id: 11, comment:'child', reply:true, parentId:1, children:[{id: 21, comment:'super child ', reply:false,parentId:11 }] }] }, {id: 2, comment:'parent 02', reply:true, parentId:null } ]
[ 
{id: 1, comment:'parent 01', reply:true,parentId:null},
{id: 11, comment:'child', reply:true, parentId:1},
{id: 21, comment:'super child', reply:true, parentId:11},
{id: 2, comment:'parent 02', reply:true, parentId:null},
]

function to make this nested array:

function nestComments(commentList) {
  const commentMap = {};

  // move all the comments into a map of id => comment
  commentList.forEach(comment => commentMap[comment.id] = comment);

  // iterate over the comments again and correctly nest the children
  commentList.forEach(comment => {
    if(comment.parentId !== null) {
      const parent = commentMap[comment.parentId];
      (parent.children = parent.children || []).push(comment);
    }
  });

  // filter the list to return a list of correctly nested comments
  return commentList.filter(comment => {
    return comment.parentId === null;
  });
}
2
  • What is your required condition to update that object? Commented Nov 5, 2022 at 6:49
  • make id:21 reply value to false : { id: 21 reply:false} Commented Nov 5, 2022 at 6:51

3 Answers 3

3

You should use recursion concept here

  function changeData(arr,id){
        arr.forEach((ar)=>{
            if(ar.id==id){
                ar.reply=false;
            }
            if(ar && ar.children && ar.children.length>0){
                changeData(ar.children,id);
            }
        })
        return arr;
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Don't forget to mark the accepted answer
1

Solution with stack:

const update = (arr, id, key, value) => {
  let i = 0;
  let stack = [arr[i]];

  while (stack.length && stack[0]) {
    let current = stack.pop();

    if (current.id === id) {
      current[key] = value;
      break;
    } else {
      if (current.children && current.children.length) {
        stack = [...stack, ...current.children];
      } else {
        stack.push(arr[i++]);
      }
    }
  }
};

update(arr, 21, "reply", "NEW VALUE");

Comments

1

You can use one of the solutions above if you know that the level of nesting is 2, but if the children may have other children i.e. unknown level of nesting, you may use the next recursive solution.

/**
   * @description Recursively finds and updates reply state of the passed comment id.
   * @typedef {{
   *    id: number,
   *    parentId: number | null,
   *    reply: boolen,
   *    comment: string,
   *    children?: Comment[]
   * }} Comment
   * @param {Comment[] | undefined} comments
   * @param {number} id
   * @param {boolean} state
   * @return {Comment | undefined}
   */
   function updateCommentReplyState(comments, id, state) {
      if (!comments) {
        return;
      }

     for (let comment of comments) {
        if (comment.id === id) {
          // We've found the id, then update its reply state then
          // return the comment, and do not search the children.
          comment.reply = state;
          return comment;
        }

        // Recursively search each child
        return updateCommentReplyState(comment.children, id, state);
     }
  }

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.