Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Javascript – Convert array to recursive object

I have a recursive object of the structure:

const obj = {
  name: 'entity-0',
  children: [{
    name: 'entity-0-0',
    children: []
  }, {
    name: 'entity-0-1',
    children: [{
      name: 'entity-1-0',
      children: []
    }]
  }]
}

And I’m currently converting it to a flat array like this:

const arr = [];

function convertObjToArr(obj, level, parent) {
  arr.push({ name: obj.name, parent: parent?.name, level });
  obj.children.forEach(v => this.convertObjToArr(v, level + 1, obj));
}

convertObjToArr(obj, 0);

This results in array that looks like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

[
  { name: 'entity-0', level: 0 },
  { name: 'entity-0-0', parent: 'entity-0', level: 1 },
  { name: 'entity-0-1', parent: 'entity-0', level: 1 },
  { name: 'entity-1-0', parent: 'entity-0-1', level:  2}
]

What I now need to do is reverse the process. Where I give the generated arr as the input and get obj as the output. Is this possible? How would I do this?

This is as far as I’ve gotten:

function convertArrToObj(iArr) {
  for(let i = 0; i < iArr.length; i++) {
    if(!iArr[i].parent) newObj = { ...iArr[i], children: [] };
    else {
      // this should somehow find iArr[i].parent and insert itself into its children array
    }
  }
}

But as you can see, it’s incomplete and I’m pretty sure it’s not gonna be recursive, so if it’s more than 1 layer deep it won’t work, I don’t think.

>Solution :

This might work.

If there is a single root, take the first element in the result array.

const arr = [
  { name: 'entity-0', level: 0 },
  { name: 'entity-0-0', parent: 'entity-0', level: 1 },
  { name: 'entity-0-1', parent: 'entity-0', level: 1 },
  { name: 'entity-1-0', parent: 'entity-0-1', level:  2}
];

const convertArrToObj = (arr, parent) => {
    return arr.filter(item => item.parent === parent)
        .reduce((acc, item) => {
            acc.push({name: item.name, children: convertArrToObj(arr, item.name)});
            return acc;
        }, []);
};

const result = convertArrToObj(arr);

console.log(result);

// using map is simpler, advised by Nick Parsons
const convertArrToObj2 = (arr, parent) => {
    return arr.filter(item => item.parent === parent)
        .map(item => ({name: item.name, children: convertArrToObj2(arr, item.name)}));
};

console.log(convertArrToObj2(arr));
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading