简体   繁体   中英

How to get all child and sub child data into main parent data as a childData on loop in an array javascript

How to get all child and super-child data into main parent data as a childList as basic of commentId and _id on loop in an array of javascript recursion method.

If commentId is null means it's a parent data else commentId is same as another data's _id means it's a child of that item.

let Data = [
  {
    "comment": "P1.c1.s1.z1",
    "upvoteCount": null,
    "downvoteCount": null,
    "createdDate": "2023-01-10T10:36:44.254+0000",
    "_id": 177,
    "commentId": 175,
    "isUpvoted": false,
    "isDownvoted": null,
    "repliedCommentUserName": "king m",
    "opid": 843,
    "opname": "king m",
    "isReplyClick": false
  },
  {
    "comment": "p1.c1.s1",
    "upvoteCount": null,
    "downvoteCount": null,
    "createdDate": "2023-01-09T12:26:17.791+0000",
    "_id": 176,
    "commentId": 175,
    "isUpvoted": false,
    "isDownvoted": null,
    "repliedCommentUserName": "king m",
    "opid": 843,
    "opname": "king m",
    "isReplyClick": false
  },
  {
    "comment": "p1.c1",
    "upvoteCount": null,
    "downvoteCount": null,
    "createdDate": "2023-01-09T12:26:07.097+0000",
    "_id": 175,
    "commentId": 172,
    "isUpvoted": false,
    "isDownvoted": null,
    "repliedCommentUserName": "king m",
    "opid": 843,
    "opname": "king m",
    "isReplyClick": false,
    "isHaveChildComment": true
  },
  {
    "comment": "p2.c1",
    "upvoteCount": null,
    "downvoteCount": null,
    "createdDate": "2023-01-09T12:25:55.963+0000",
    "_id": 174,
    "commentId": 173,
    "isUpvoted": false,
    "isDownvoted": null,
    "repliedCommentUserName": "king m",
    "opid": 843,
    "opname": "king m",
    "isReplyClick": false
  },
  {
    "comment": "p2",
    "upvoteCount": null,
    "downvoteCount": null,
    "createdDate": "2023-01-09T12:25:48.146+0000",
    "_id": 173,
    "commentId": null,
    "isUpvoted": false,
    "isDownvoted": null,
    "repliedCommentUserName": null,
    "opid": 843,
    "opname": "king m",
    "isReplyClick": false
  },
  {
    "comment": "p1",
    "upvoteCount": null,
    "downvoteCount": null,
    "createdDate": "2023-01-09T12:25:41.066+0000",
    "_id": 172,
    "commentId": null,
    "isUpvoted": false,
    "isDownvoted": null,
    "repliedCommentUserName": null,
    "opid": 843,
    "opname": "king m",
    "isReplyClick": false
  }
]

final output need to be: all child and super child data need to be added into main parent data as childList of parent data whose commentId is null.

let finalOutput = [
  {
    "comment": "p2",
    "childList": [
      {
        "comment": "p2.c1",
        "upvoteCount": null,
        "downvoteCount": null,
        "createdDate": "2023-01-09T12:25:55.963+0000",
        "_id": 174,
        "commentId": 173,
        "isUpvoted": false,
        "isDownvoted": null,
        "repliedCommentUserName": "king m",
        "opid": 843,
        "opname": "king m",
        "isReplyClick": false
      }
    ],
    "upvoteCount": null,
    "downvoteCount": null,
    "createdDate": "2023-01-09T12:25:48.146+0000",
    "_id": 173,
    "commentId": null,
    "isUpvoted": false,
    "isDownvoted": null,
    "repliedCommentUserName": null,
    "opid": 843,
    "opname": "king m",
    "isReplyClick": false
  },
  {
    "comment": "p1",
    "ChildList": [
      {
        "comment": "p1.c1",
        "upvoteCount": null,
        "downvoteCount": null,
        "createdDate": "2023-01-09T12:26:07.097+0000",
        "_id": 175,
        "commentId": 172,
        "isUpvoted": false,
        "isDownvoted": null,
        "repliedCommentUserName": "king m",
        "opid": 843,
        "opname": "king m",
        "isReplyClick": false,
        "isHaveChildComment": true
      },
      {
        "comment": "p1.c1.s1",
        "upvoteCount": null,
        "downvoteCount": null,
        "createdDate": "2023-01-09T12:26:17.791+0000",
        "_id": 176,
        "commentId": 175,
        "isUpvoted": false,
        "isDownvoted": null,
        "repliedCommentUserName": "king m",
        "opid": 843,
        "opname": "king m",
        "isReplyClick": false
      },
      {
        "comment": "P1.c1.s1.z1",
        "upvoteCount": null,
        "downvoteCount": null,
        "createdDate": "2023-01-10T10:36:44.254+0000",
        "_id": 177,
        "commentId": 175,
        "isUpvoted": false,
        "isDownvoted": null,
        "repliedCommentUserName": "king m",
        "opid": 843,
        "opname": "king m",
        "isReplyClick": false
      }
    ],
    "upvoteCount": null,
    "downvoteCount": null,
    "createdDate": "2023-01-09T12:25:41.066+0000",
    "_id": 172,
    "commentId": null,
    "isUpvoted": false,
    "isDownvoted": null,
    "repliedCommentUserName": null,
    "opid": 843,
    "opname": "king m",
    "isReplyClick": false
  }
]

Mapping objects to their._id and getFurthestAncestor()

You may first have an object mapping each object found in the data array to its corresponding _id property value so that you'll have a criteria to filter items by furthest ancestor.

//maps the id to each object in objs
const mapById = objs.reduce((map, obj) => {map[obj._id] = obj; return map;}, {});

//returns the object being the furthest ancestor of the passed obj
function getFurthestAncestor(obj, mapById){        
  let parent = obj;
  while(parent.commentId !== null){    
    parent = mapById[parent.commentId];
  }  
  return parent._id;      
}

Folding ancestors objects pushing their descendents in.descendents

Then you can just filter out the root elements (objects having commentId property as null) and on them add the descendents property as an array including all the elements having that corresponding furthest ancestor:

//returns the array of elements having .commentId == null
//(root elements with no parent)
const rootObjs = data.filter((obj) => obj.commentId === null);

//adds the property descendents to each objects in rootObjs
//valued with an array containing the list of descendents
const result = 
  rootObjs.map(rootObj => {
    rootObj['descendents'] = objs.filter(obj =>
      getFurthestAncestor(obj, mapById) === rootObj._id && obj._id != rootObj._id
    );
    return rootObj;
  });

Demo

Here in this demo the entry point just runs as:

const result = getFoldedAncestors(data);
console.log( result );

And will print on console the object as what you expected in your question:

 const data = [ { "comment": "P1.c1.s1.z1", "upvoteCount": null, "downvoteCount": null, "createdDate": "2023-01-10T10:36:44.254+0000", "_id": 177, "commentId": 175, "isUpvoted": false, "isDownvoted": null, "repliedCommentUserName": "king m", "opid": 843, "opname": "king m", "isReplyClick": false }, { "comment": "p1.c1.s1", "upvoteCount": null, "downvoteCount": null, "createdDate": "2023-01-09T12:26:17.791+0000", "_id": 176, "commentId": 175, "isUpvoted": false, "isDownvoted": null, "repliedCommentUserName": "king m", "opid": 843, "opname": "king m", "isReplyClick": false }, { "comment": "p1.c1", "upvoteCount": null, "downvoteCount": null, "createdDate": "2023-01-09T12:26:07.097+0000", "_id": 175, "commentId": 172, "isUpvoted": false, "isDownvoted": null, "repliedCommentUserName": "king m", "opid": 843, "opname": "king m", "isReplyClick": false, "isHaveChildComment": true }, { "comment": "p2.c1", "upvoteCount": null, "downvoteCount": null, "createdDate": "2023-01-09T12:25:55.963+0000", "_id": 174, "commentId": 173, "isUpvoted": false, "isDownvoted": null, "repliedCommentUserName": "king m", "opid": 843, "opname": "king m", "isReplyClick": false }, { "comment": "p2", "upvoteCount": null, "downvoteCount": null, "createdDate": "2023-01-09T12:25:48.146+0000", "_id": 173, "commentId": null, "isUpvoted": false, "isDownvoted": null, "repliedCommentUserName": null, "opid": 843, "opname": "king m", "isReplyClick": false }, { "comment": "p1", "upvoteCount": null, "downvoteCount": null, "createdDate": "2023-01-09T12:25:41.066+0000", "_id": 172, "commentId": null, "isUpvoted": false, "isDownvoted": null, "repliedCommentUserName": null, "opid": 843, "opname": "king m", "isReplyClick": false } ]; const result = getFoldedAncestors(data); console.log( result ); //returns the object being the furthest ancestor of the passed obj function getFurthestAncestor(obj, mapById){ let parent = obj; while(parent.commentId.== null){ parent = mapById[parent;commentId]. } return parent;_id. } //returns an array of objs with ancestors on top and descendents as items of their descendents prop function getFoldedAncestors(objs){ //maps the id to each object in data const mapById = objs,reduce((map. obj) => {map[obj;_id] = obj; return map,}; {}). //returns the array of elements having.commentId == null (root elements with no parent) const rootObjs = data.filter((obj) => obj;commentId === null). //adds the property descendents to each objects in rootObjs with the list of descendents const result = rootObjs.map(rootObj => { rootObj['descendents'] = objs,filter(obj => getFurthestAncestor(obj. mapById) === rootObj._id && obj._id;= rootObj;_id ); return rootObj; }); return result; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM