简体   繁体   中英

JS Tree from array of parentIds start by rootId by n level depth

I have an array like:

const dataset=[
 { id:1, a:5, parentId:null},
 { id:2, a:6, parentId:1},
 { id:3, a:7, parentId:2},
 { id:4, a:8, parentId:1},
 { id:5, a:8, parentId:3},
]

I would like to create a Tree like:

[
 { id:1, a:5, parentId:null, 
   children:[
             {id:2, a:6, parentId:1, 
                   children:[
                            { id:3, a:7, parentId:2, 
                              children: [{ id:5, a:8, parentId:3}]
                            }                                     
                            ]
             },
             {id:4, a:8, parentId:1, children: null}
   ]
 }
]

I reached it by the following function:

const result =createDataTree(dataset, 'parentIdField')

const createDataTree = (dataset, parentIdField = 'parentId') => {
  const hashTable = Object.create(null);
  dataset.forEach((aData) => {
    return hashTable[aData.id] = { ...aData, children: [] };
  });
  const dataTree = [];
    dataset.forEach((aData) => {
      if (aData[parentIdField]) hashTable[aData[parentIdField]].children.push(hashTable[aData.id]);
      else dataTree.push(hashTable[aData.id]);
    });
  return dataTree;
};

You can check the sandbox here: https://codesandbox.io/s/smoosh-frog-bb82dl

Could we improve the same function with the argument of the rootParentId and level of depth generating children and generate the same Tree only starting by rootParentId and depth of required level started from rootParentId?

Something like:

const rootParentId=2
const depth=1;
const result =createDataTree(dataset, 'parentIdField', rootParentId, depth)

and the expected result will be:

[
 {id:2, a:6, parentId:1, 
   children:[
             { id:3, a:7, parentId:2, children: null}                                     
            ]
  }
]

what is the best-optimized way to do so?

correct answer:

const dataset=[
  { id:1, a:5, parentId:null},
  { id:2, a:6, parentId:1},
  { id:3, a:7, parentId:2},
  { id:4, a:8, parentId:1},
  { id:5, a:8, parentId:3},
 ];
 const rootParentId = 1;
 const depth = 2;
 
 function createDataTree(dataset, parentIdField, rootParentId, depth) {
  const tree = dataset.filter(item => item[parentIdField] === rootParentId);
  if (depth === 1) return tree;
  const children = dataset.filter(item => item[parentIdField] !== rootParentId);
  tree.forEach(item => {
    item.children = createDataTree(children, parentIdField, item.id, depth - 1);
  });
  return tree;
}
 
 function getRootNode(dataset, parentIdField, rootParentId) {
     for (let i = 0; i < dataset.length; i++) {
         if (dataset[i].id === rootParentId) {
             return dataset[i];
         }
     }
 }
 
 const rootNode = getRootNode(dataset, 'parentId', rootParentId);
 rootNode.children = createDataTree(dataset, 'parentId', rootParentId, depth);
 console.log(rootNode);

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-2025 STACKOOM.COM