Skip to content

Instantly share code, notes, and snippets.

@blessanm86
Last active August 16, 2020 18:27
Show Gist options
  • Save blessanm86/b6179d6baf5a814113804fccb435afc6 to your computer and use it in GitHub Desktop.
Save blessanm86/b6179d6baf5a814113804fccb435afc6 to your computer and use it in GitHub Desktop.
A javascript function that converts a flat array into a tree. Support sorting
function convertCommentsToTree(comments) {
  const commentsMap = comments.reduce((acc, comment) => {
    comment.children = [];
    acc[comment.id] = comment;
    return acc;
  }, {});

  const sortedParentIds = new Set();

  for (let comment of comments) {
    if (comment.parent_id) {
      //only consider children that that have a parent in the map.
      //If parent doesnt exist, it means it was deleted so the children can be ignored.
      if (commentsMap[comment.parent_id]) {
        commentsMap[comment.parent_id].children.push(comment);
      }

      let node = comment; 
      while(node.parent_id) {
        node = commentsMap[node.parent_id];
      }
      sortedParentIds.add(node.id);
    } else {
      sortedParentIds.add(comment.id);
    }
  }

  return [...sortedParentIds].map(id => commentsMap[id]);
}

Handle when some nodes are deleted

function convertCommentsToTree(comments) {
  const commentsMap = comments.reduce((acc, comment) => {
    comment.children = [];
    acc[comment.id] = comment;
    return acc;
  }, {});

  const sortedParentIds = new Set();

  for (let comment of comments) {
    if (comment.parent_id) {
      //only consider children that that have a parent in the map.
      //If parent doesnt exist, it means it was deleted so the children can be ignored.
      if (commentsMap[comment.parent_id]) {
        commentsMap[comment.parent_id].children.push(comment);
      }

      let node = comment;
      while (node.parent_id) {
        node = commentsMap[node.parent_id];
        if (!node) {
          break;
        }
      }
      node && sortedParentIds.add(node.id);
    } else {
      sortedParentIds.add(comment.id);
    }
  }

  return [...sortedParentIds].map((id) => commentsMap[id]);
}

Eg. dataset

[{"created_utc":1570693670,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":0,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f35vz2f/","body_html":"<div class=\"md\"><p>Bruh</p>\n</div>","downs":0,"body":"Bruh","author":"RandomName01","id":"t1_f35vz2f","ups":1},{"created_utc":1570683149,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":0,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f35nn9e/","body_html":"<div class=\"md\"><p>97% Disagree it's the most unpopular opinion I've seen here after that guy who wanted to be pregnant</p>\n</div>","downs":0,"body":"97% Disagree it's the most unpopular opinion I've seen here after that guy who wanted to be pregnant","author":"shantanu011","id":"t1_f35nn9e","ups":2233},{"created_utc":1570680701,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":0,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f35kuhk/","body_html":"<div class=\"md\"><p>I'm gonna try this tonight op, and if it's shit I will come for you.</p>\n\n<p>Edit: just got home. Getting in shower now.</p>\n\n<p>Edit 2 electric boogaloo: risky click of the day. \n<a href=\"https://imgur.com/a/u1C215L\">No bamboozle</a></p>\n\n<p>Edit 3: you!!!  I declare shenanigans.</p>\n</div>","downs":0,"body":"I'm gonna try this tonight op, and if it's shit I will come for you.\n\nEdit: just got home. Getting in shower now.\n\nEdit 2 electric boogaloo: risky click of the day. \n[No bamboozle](https://imgur.com/a/u1C215L)\n\nEdit 3: you!!!  I declare shenanigans.","author":"OceLawless","id":"t1_f35kuhk","ups":263},{"created_utc":1570697457,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":1,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f35y9gp/","body_html":"<div class=\"md\"><p>Or the guy who likes sleeping in jeans</p>\n\n<p>Edit: to everyone commenting, I meant the dude liked to get into bed at night with the duvet on with jeans, not just taking a nap</p>\n</div>","downs":0,"body":"Or the guy who likes sleeping in jeans\n\nEdit: to everyone commenting, I meant the dude liked to get into bed at night with the duvet on with jeans, not just taking a nap","author":"ShitOnMyArsehole","id":"t1_f35y9gp","ups":638,"parent_id":"t1_f35nn9e"},{"created_utc":1570703350,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":1,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f361yrc/","body_html":"<div class=\"md\"><p>Am I pregegnant or am I ok?</p>\n</div>","downs":0,"body":"Am I pregegnant or am I ok?","author":"HansenTakeASeat","id":"t1_f361yrc","ups":56,"parent_id":"t1_f35nn9e"},{"created_utc":1570709099,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":2,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f369ye5/","body_html":"<div class=\"md\"><p>Or the guy who eats his cereal with water</p>\n</div>","downs":0,"body":"Or the guy who eats his cereal with water","author":"nikithb","id":"t1_f369ye5","ups":551,"parent_id":"t1_f35y9gp"},{"created_utc":1570710788,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":2,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f36drup/","body_html":"<div class=\"md\"><p>Sleeping in jeans is fine on a couch or something, but not good in a bed under sheets.</p>\n</div>","downs":0,"body":"Sleeping in jeans is fine on a couch or something, but not good in a bed under sheets.","author":"bellowingbullfinches","id":"t1_f36drup","ups":32,"parent_id":"t1_f35y9gp"},{"created_utc":1570711829,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":3,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f36ge9a/","body_html":"<div class=\"md\"><p>Good lord, I wanted to down vote this but realised you're the messenger, we don't shoot the messenger</p>\n</div>","downs":0,"body":"Good lord, I wanted to down vote this but realised you're the messenger, we don't shoot the messenger","author":"Sazzybee","id":"t1_f36ge9a","ups":286,"parent_id":"t1_f369ye5"},{"created_utc":1570711069,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":3,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f36efud/","body_html":"<div class=\"md\"><p>Yeah but you don't purposely go to bed in jeans like the poster did</p>\n</div>","downs":0,"body":"Yeah but you don't purposely go to bed in jeans like the poster did","author":"ShitOnMyArsehole","id":"t1_f36efud","ups":16,"parent_id":"t1_f36drup"},{"created_utc":1570710595,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":2,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f36daww/","body_html":"<div class=\"md\"><p>Can you get.....PREGANTE</p>\n</div>","downs":0,"body":"Can you get.....PREGANTE","author":"_Noot_Noot","id":"t1_f36daww","ups":32,"parent_id":"t1_f361yrc"},{"created_utc":1570711616,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":3,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f36fubr/","body_html":"<div class=\"md\"><h1>AM I GREGNANT?!</h1>\n</div>","downs":0,"body":"#AM I GREGNANT?!","author":"Macho_Mans_Ghost","id":"t1_f36fubr","ups":29,"parent_id":"t1_f36daww"},{"created_utc":1570681556,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":1,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f35ltpb/","body_html":"<div class=\"md\"><p>[deleted]</p>\n</div>","downs":0,"body":"[deleted]","author":"[deleted]","id":"t1_f35ltpb","ups":136,"parent_id":"t1_f35kuhk"},{"created_utc":1570690006,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":1,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f35tfxh/","body_html":"<div class=\"md\"><p>So?</p>\n</div>","downs":0,"body":"So?","author":"DaSwagCow","id":"t1_f35tfxh","ups":33,"parent_id":"t1_f35kuhk"},{"created_utc":1570725030,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":2,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f37esup/","body_html":"<div class=\"md\"><p>You, sonofabitch.</p>\n</div>","downs":0,"body":"You, sonofabitch.","author":"OceLawless","id":"t1_f37esup","ups":10,"parent_id":"t1_f35ltpb"},{"created_utc":1570691417,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":2,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f35uh0q/","body_html":"<div class=\"md\"><p>It's shit.</p>\n</div>","downs":0,"body":"It's shit.","author":"Killahcamcam","id":"t1_f35uh0q","ups":75,"parent_id":"t1_f35tfxh"},{"created_utc":1570694504,"subreddit_name_prefixed":"r/unpopularopinion","subreddit":"unpopularopinion","depth":2,"permalink":"/r/unpopularopinion/comments/dfqxf8/taking_showers_with_your_socks_on_is_so_much/f35wht6/","body_html":"<div class=\"md\"><p>It's 3pm where I am. So still at work</p>\n\n<p>Edit:sorry lads I'm still at a bar. I will update ASAP no bamboozle.</p>\n</div>","downs":0,"body":"It's 3pm where I am. So still at work\n\n\nEdit:sorry lads I'm still at a bar. I will update ASAP no bamboozle.","author":"OceLawless","id":"t1_f35wht6","ups":23,"parent_id":"t1_f35tfxh"}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment