Home > other >  Convert object to array of prorperties
Convert object to array of prorperties

Time:02-07

I need to convert object:

{
        middleName: null,
        name: "Test Name",
        university: {
            country: {
                code: "PL"
            },
            isGraduated: true,
            speciality: "Computer Science"
        }
    }

to array:

[{
        key: "name",
        propertyValue: "Test Name",
    },
    {
        key: "middleName",
        propertyValue: null,
    },
    {   
        key: "university.isGraduated",
        propertyValue: true,
    },
    {   
        key: "university.speciality",
        propertyValue: "Computer Science", 
    },
    {   
        key: "university.country.code",
        propertyValue: "PL"
    }];

I wrote algorithm, but it's pretty dummy, how can I improve it? Important, if object has nested object than I need to write nested object via dot (e.g university.contry: "value")

let arr = [];
    Object.keys(parsedObj).map((key) => {
        if (parsedObj[key] instanceof Object) {
            Object.keys(parsedObj[key]).map((keyNested) => {
                if (parsedObj[key][keyNested] instanceof Object) {
                    Object.keys(parsedObj[key][keyNested]).map((keyNestedNested) => {
                        arr.push({ 'key': key   '.'   keyNested   '.'   keyNestedNested, 'propertyValue': parsedObj[key][keyNested][keyNestedNested] })
                    })
                } else {
                    arr.push({ 'key': key   '.'   keyNested, 'propertyValue': parsedObj[key][keyNested] })
                }
            })
        } else {
            arr.push({ 'key': key, 'propertyValue': parsedObj[key] })
        }
    });

Thanks

CodePudding user response:

A recursive function implementation.

I have considered that your object consist of only string and object as the values. If you have more kind of data types as your values, you may have to develop on top of this function.

const myObj = {
  middleName: null,
  name: "Test Name",
  university: {
    country: {
      code: "PL"
    },
    isGraduated: true,
    speciality: "Computer Science"
  }
}
const myArr = [];

function convertObjectToArray(obj, keyPrepender) {
  Object.entries(obj).forEach(([key, propertyValue]) => {
    if (typeof propertyValue === "object" && propertyValue) {
      const updatedKey = keyPrepender ? `${keyPrepender}.${key}` : key;
      convertObjectToArray(propertyValue, updatedKey)
    } else {
      myArr.push({
        key: keyPrepender ? `${keyPrepender}.${key}` : key,
        propertyValue
      })
    }
  })
}

convertObjectToArray(myObj);
console.log(myArr);

CodePudding user response:

I'd probably take a recursive approach, and I'd probably avoid unnecessary intermediary arrays (though unless the original object is massive, it doesn't matter). For instance (see comments):

function convert(obj, target = [], prefix = "") {
    // Loop through the object keys
    for (const key in obj) {
        // Only handle "own" properties
        if (Object.hasOwn(obj, key)) {
            const value = obj[key];
            // Get the full key for this property, including prefix
            const fullKey = prefix ? prefix   "."   key : key;
            if (value && typeof value === "object") {
                // It's an object...
                if (Array.isArray(value)) {
                    throw new Error(`Arrays are not valid`);
                } else {
                    // ...recurse, providing the key as the prefix
                    convert(value, target, fullKey);
                }
            } else {
                // Not an object, push it to the array
                target.push({key: fullKey, propertyValue: value});
            }
        }
    }
    // Return the result
    return target;
}

Live Example:

const original = {
    middleName: null,
    name: "Test Name",
    university: {
        country: {
            code: "PL"
        },
        isGraduated: true,
        speciality: "Computer Science"
    }
};

function convert(obj, target = [], prefix = "") {
    // Loop through the object keys
    for (const key in obj) {
        // Only handle "own" properties
        if (Object.hasOwn(obj, key)) {
            const value = obj[key];
            // Get the full key for this property, including prefix
            const fullKey = prefix ? prefix   "."   key : key;
            if (value && typeof value === "object") {
                // It's an object...
                if (Array.isArray(value)) {
                    throw new Error(`Arrays are not valid`);
                } else {
                    // ...recurse, providing the key as the prefix
                    convert(value, target, fullKey);
                }
            } else {
                // Not an object, push it to the array
                target.push({key: fullKey, propertyValue: value});
            }
        }
    }
    // Return the result
    return target;
}
const result = convert(original, []);
console.log(result);
.as-console-wrapper {
    max-height: 100% !important;
}

Note that I've assumed the order of the array entries isn't significant. The output you said you wanted is at odds with the standard order of JavaScript object properties (yes, they have an order now; no, it's not something I suggest relying on

  •  Tags:  
  • Related