Javascript - Change name of all object keys in nested arrays

Viewed 597

This is the array i get:

const packages = [
  {
    id: '641a1690-6c8b-4ada-ae97-8d82cc4fe7a3',
    name: 'com.sample',
    children: {
      id: 'd7384f60-e4ab-4a86-8e2e-0f66cc32f',
      name: 'child.computer.com',
      children: { id: 'e4ab-4a86-0f66cc32f560', name: 'child.com' }
    }
  },
  { id: 'd7384f60-e4ab-4a86-8e2e-0f66cc32f560', name: 'computer.com' },
  { id: 'ca7f972e-64ee-4cb0-80b9-1036fac69d32', name: 'java.util' }
];

So, it is an array of objects, and each object can have children, which again have id, name and possibly children (children is optional), and so on, it can be nested X times. I want to change key names, id to key, name to title and children will remain children. So, my problem is that i don't know how to change keys inside children, i just change the first level and that is all.. It should be like:

{
    key: '641a1690-6c8b-4ada-ae97-8d82cc4fe7a3',
    title: 'com.sample',
    children: {
      key: 'd7384f60-e4ab-4a86-8e2e-0f66cc32f',
      title: 'child.computer.com',
      children: { key: 'e4ab-4a86-0f66cc32f560', title: 'child.com' }
    }   
}
2 Answers

You can do this by using Recursion.

Check if the value of the [key-value] pair from the Object#entries() call is an object.

If so, call the transformObj function again recursively for that value. Else return the value as is.

And finally convert the array of [key-value] pairs back to an object by using Object#fromEntries:

const packages = [{ id: '641a1690-6c8b-4ada-ae97-8d82cc4fe7a3', name: 'com.sample', children: { id: 'd7384f60-e4ab-4a86-8e2e-0f66cc32f', name: 'child.computer.com', children: { id: 'e4ab-4a86-0f66cc32f560', name: 'child.com' }}}, { id: 'd7384f60-e4ab-4a86-8e2e-0f66cc32f560', name: 'computer.com' }, { id: 'ca7f972e-64ee-4cb0-80b9-1036fac69d32', name: 'java.util' }];
const replacer = { "id": "key", "name" :"title"};
const transformObj = (obj) => {
  if(obj && Object.getPrototypeOf(obj) === Object.prototype){
    return Object.fromEntries(
    Object.entries(obj)
          .map(([k, v]) => [replacer[k] || k, transformObj(v)])
    );
  }
  //Base case, if not an Object literal return value as is
  return obj;
}
console.log(packages.map(o => transformObj(o)));

You can try to go through every object inside your array and recursively iterate through its keys. Then you can change the keys you want to change and iterate further through the childrens key.

const packages = [{id: '641a1690-6c8b-4ada-ae97-8d82cc4fe7a3',name:'com.sample',children: {id: 'd7384f60-e4ab-4a86-8e2e-0f66cc32f',name: 'child.computer.com',children: { id: 'e4ab-4a86-0f66cc32f560', name: 'child.com' }}},{ id: 'd7384f60-e4ab-4a86-8e2e-0f66cc32f560', name: 'computer.com' },{ id: 'ca7f972e-64ee-4cb0-80b9-1036fac69d32', name: 'java.util' }];

const renameNestedObjects = (obj) => {
    Object.keys(obj).forEach((key, index) => {
    if (key == "id") {
      obj["key"] = obj["id"];
      delete obj["id"];
    }
    if (key == "name") {
      obj["title"] = obj["name"];
      delete obj["name"];
    }
    if (key == "children") {
        renameNestedObjects(obj["children"]);
    }
  });
}

console.log(packages);
packages.forEach(obj => { renameNestedObjects(obj); });
console.log(packages);

Related