Home > Mobile >  How to change property value under nested array of objects in javascript
How to change property value under nested array of objects in javascript

Time:11-05

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

CodePudding user response:

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

CodePudding user response:

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

CodePudding user response:

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