2

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' }
    }   
}
1
  • Have you tried anything? Try reading map in array Commented Oct 30, 2020 at 11:37

3 Answers 3

4

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)));

Sign up to request clarification or add additional context in comments.

2 Comments

Why if(obj && Object.getPrototypeOf(obj) === Object.prototype) check was necessary?
@RichardRublev check if the value is a nested object, if so we need to recursively transform the nested object as well. If it is a string or a number then we do not bother transforming.
2

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);

1 Comment

this also works, although i have chosen the first answer because it is more dynamic, but thank you a lot!
0

In my case, the solution of Fullstack Guy was good only for one-level transformation. Same for Olli's solution. So for deep transformation the solution of Olli should be like this:

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') {
            obj['children'].forEach((children) => renameNestedObjects(children));
          }
        });
      };

And if your initial array of objects is not extensible you may consider using this:

arrayOfObjects = JSON.parse(JSON.stringify(initialIncomingNotExtensibleArrayOfObjects);

and after that to apply suggested transformation to this new arrayOfObjects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.