Home > Back-end >  Rebuilding the array of dictionaries into array of hierarchical trees
Rebuilding the array of dictionaries into array of hierarchical trees

Time:12-21

I have followed the suggestion from Scott Sauer, and have used the solution from this post but tried to adapt to take into account the topics object that is already present.

The original post is here Invert data structure while deduplicating

I have modified the function, but now I am getting duplicates in the deepest dictionary, I would appreciate if anyone could point out what am I doing wrong?

const initObject = [
  { 
    id: 5,
    topics: [{
      id: 7,
      topics: [
        {id:9, topics:[]}
      ]
    }],
    parent: {
     id: 10,
     parent: {
       id: 15,
       parent: null
      }
    }
  },
  {
    id: 7,
    topics: [
        {id:9, topics:[]}
    ],
    parent: {
     id: 5,
     parent: {
       id: 10,
       parent: {
         id: 15,
         parent: null
       }
      }
    }
  }
]

function reverseGraphAll(data) {
    const rootTopics = [];
    const map = new Map([[undefined, rootTopics]]);
    
    function upward({id, parent, topics}) {
        if (map.has(id)) return map.get(id);
        let topicsNew = topics ? topics : [];
        map.set(id, topicsNew);
        (parent ? upward(parent) : rootTopics).push({id, topicsNew});
        return topicsNew;
    }
    
    data.forEach(upward);
    return rootTopics;
}

const result = reverseGraphAll(initObject);
console.log("Total", result);

CodePudding user response:

You'll have to iterate (recursively) the topics properties, so to mark them in the map too, thus registering where each of those child nodes is positioned in the final hierarchy:

function reverseGraphAll(data) {
    const rootTopics = [];
    const nodeMap = new Map([[undefined, { topics: rootTopics }]]);
    const expanded = new Set;
    
    function upward({id, parent}) {
        if (nodeMap.has(id)) return nodeMap.get(id);
        const node = {id, topics: []};
        nodeMap.set(id, node);
        upward(Object(parent)).topics.push(node);
        return node;
    }
    
    function expand({id, topics}) {
        if (expanded.has(id)) return;
        expanded.add(id);
        nodeMap.get(id).topics = topics;
        for (const topic of topics) {
            nodeMap.set(topic.id, topic);
            expand(topic);
        }
    }
    
    data.forEach(node => (upward(node), expand(node)));
    return rootTopics;
}

const initObject = [{id: 5,topics: [{id: 7,topics: [{id:9, topics:[]}]}],parent: {id: 10,parent: {id: 15,parent: null}}},{id: 7,topics: [{id:9, topics:[]}],parent: {id: 5,parent: {id: 10,parent: {id: 15,parent: null}}}}];
const result = reverseGraphAll(initObject);
console.log(result);

  • Related