skip to Main Content

I have this object:

{
  name: "Gold's Gym Venice",
  "categories[0].alias": "gyms",
  "categories[0].title": "Gyms",
  "categories[1].alias": "healthtrainers",       
  "categories[1].title": "Trainers",
  "location.state": "CA",
  "location.city": "Venice",
  "location.zip_code": "90291",
  "location.display_address[0]": "360 Hampton Dr",
  "location.display_address[1]": "Venice, CA 90291"
}

… and am trying to transform it into this:

{
    name: "Gold's Gym Venice",
    categories: [
        { alias: "gyms", title: "Gyms" },
        { alias: "healthtrainers", title: "Trainers" }
    ],
    location: {
      state: "CA",
      city: "Venice",
      zip_code: "90291",
      display_address: [ "360 Hampton Dr", "Venice, CA 90291" ]
    }
}

I tried both of these answers. Each gives slightly different output—the second one gets closer—but neither handles keys with square bracketed numbers/array positions properly.

What’s the best way to handle this?

2

Answers


  1. Chosen as BEST ANSWER

    I tried ChatGPT after this question was answered and it came up with a very robust, elegant solution after a few tries.

    function deepSet(obj, path, value) {
        let current = obj;
        for (let i = 0; i < path.length - 1; i++) {
            const part = path[i];
            if (!current[part] || typeof current[part] !== 'object') {
                current[part] = {};
            }
            current = current[part];
        }
        current[path[path.length - 1]] = value;
    }
    
    function transformObject(input) {
        const output = {};
        Object.keys(input).forEach(key => {
            const path = key.split(/.|[|]./).map(part => part.replace(/]$/, ''));
            deepSet(output, path, input[key]);
        });
        return output;
    }
    
    const inputObject = {
        name: "Gold's Gym Venice",
        "categories[0].alias": "gyms",
        "categories[0].title": "Gyms",
        "categories[1].alias": "healthtrainers",
        "categories[1].title": "Trainers",
        "location.state": "CA",
        "location.city": "Venice",
        "location.zip_code": "90291",
        "location.display_address[0]": "360 Hampton Dr",
        "location.display_address[1]": "Venice, CA 90291"
    };
    
    const transformedObject = transformObject(inputObject);
    
    console.log(JSON.stringify(transformedObject, null, 2));

    I find this solution to be more concise and equally readable compared to the accepted answer.

    Another, more verbose approach can be viewed in this answer's edit history.


  2. I think we can use the method from this answer, here is an example code for the example you provided:

    const deepSet = (obj, path, val) => {
        path = path.replaceAll("[", ".[");
        const keys = path.split(".");
    
        for (let i = 0; i < keys.length; i++) {
            let currentKey = keys[i];
            let nextKey = keys[i + 1];
            if (currentKey.includes("[")) {
                currentKey = parseInt(currentKey.substring(1, currentKey.length - 1));
            }
            if (nextKey && nextKey.includes("[")) {
                nextKey = parseInt(nextKey.substring(1, nextKey.length - 1));
            }
    
            if (typeof nextKey !== "undefined") {
                obj[currentKey] = obj[currentKey] ? obj[currentKey] : (isNaN(nextKey) ? {} : []);
            } else {
                obj[currentKey] = val;
            }
    
            obj = obj[currentKey];
        }
    };
    
    const result = {};
    
    const originalObj = {
      'categories[0].alias': 'gyms',
      'categories[0].title': 'Gyms',
      'categories[1].alias': 'healthtrainers',       
      'categories[1].title': 'Trainers',
      'location.display_address[0]': '360 Hampton Dr',
      'location.display_address[1]': 'Venice, CA 90291'
    };
    
    for (const [key, value] of Object.entries(originalObj)) {
      deepSet(result, key, value);
    }
    
    console.log(result);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search