简体   繁体   中英

Convert an array of objects into an array of nested objects js

So I have a task to properly order the files directory. For simplicity, all the documents and files are saved as a flat array. As an identifier to display nested files I have a property uniqueId , that tells me what are the parent directories. Flat array is sorted by uniqueId , so that each child goes after its parent.

Here is an example of the flat array:

[{
 id: 1,
 uniqueId: '1',
 name: 'folder1',
 dir: true
},
{
 id: 2,
 uniqueId: '1.2',
 name: 'test1',
 dir: false
},
{
 id: 3,
 uniqueId: '1.2.3',
 name: 'test2'
 dir: false
},
{
 id: 4,
 uniqueId: '1.2.4',
 name: 'test3'
 dir: true
},
{
 id: 3,
 uniqueId: '1.3',
 name: 'test23'
 dir: true
},
{
 id: 1,
 uniqueId: '1.3.1',
 name: 'test6',
 dir: true
},
]

Which basically represents files directory tree:

1
  1.2
    1.2.3
    1.2.4
  1.3
    1.3.1

I need to display directories first, ie those that have dir: true . Thus, the above tree would become:

1
 1.3
    1.3.1
 1.2
    1.2.4
    1.2.3

So as a solution I decided that it's better to convert a flat array into nested object, sort children of each object in the desired way and then transform into flat array back again. So that my flat array would become like this:

{
 id: 1,
 uniqueId: '1',
 name: 'folder1',
 dir: true
 childs: [
  {
   id: 2,
   uniqueId: '1.2',
   name: 'test1',
   dir: false,
   childs: [
   {
     id: 3,
     uniqueId: '1.2.3',
     name: 'test2'
     dir: false
   },
   {
     id: 4,
     uniqueId: '1.2.4',
     name: 'test3'
     dir: true
   }
 ]},
 {
   id: 3,
   uniqueId: '1.3',
   name: 'test23'
   dir: true,
   childs: [
    {
     id: 1,
     uniqueId: '1.3.1',
     name: 'test23'
     dir: true
    }
  ]
}
}]

I can't find a way to convert flat into the desired nested object. I already have a function that returns children of the current object isChild(parent, objectToCheck) . I suppose it's better to use some kind of recursion for this but I am totally stuck.

Please help me to convert it into desired nested object.

Any suggestions on other ways to sort flat array are welcome too? Maybe there's a better way to sort it without actually converting back and force?

Thanks a lot in advance!

You could sort the data directly and build a tree with uniqueId and a parent value.

 const input = [{ id: 1, uniqueId: '1', name: 'folder1', dir: true }, { id: 2, uniqueId: '1.2', name: 'test1', dir: false }, { id: 3, uniqueId: '1.2.3', name: 'test2', dir: false }, { id: 4, uniqueId: '1.2.4', name: 'test3', dir: true }, { id: 3, uniqueId: '1.3', name: 'test23', dir: true }, { id: 1, uniqueId: '1.3.1', name: 'test6', dir: true }], tree = function (data) { var t = {}; data.forEach(o => { const parent = o.uniqueId.split('.').slice(0, -1).join('.'); Object.assign(t[o.uniqueId] = t[o.uniqueId] || {}, o); t[parent] = t[parent] || {}; t[parent].children = t[parent].children || []; t[parent].children.push(t[o.uniqueId]); }); return t[''].children; }(input.sort((a, b) => b.dir - a.dir)); console.log(tree);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

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