0

I am trying to transform the array object into new object with some new key name and rest of the key convert into cameCase

Example:

1. Old Key to New Key name

old key: orgId converting into clientDivisionOrganizationId

2. Remaining all key converting from snakeCase to cameCase but I am having one corner case as you can see in below example where having addresses as array object inside that you can see address_usages key as array object where I am unable to understand to handle or convert those all keys into cameCase.

I have tried as below solution. Help would be much appreciated.

Thanks

const originalArray =[{
    "uuid": "65a49008-3291ba-4dc6-8fd8-476c4ea7b84d",
    "name": "Post-man Hospital-local",
    "site_number": "PKKk-2219232",
    "phone": "",
    "fax": "",
    "org_id": "PKKKK-2219232",
    "principal_investigator_user_uuid": null,
    "study_uuid": "863080a12c-5335-472334-9103-50ea782da3c9",
    "principal_investigator": {
        "uuid": null,
        "email": null,
        "first_name": null,
        "last_name": null
    },
    "licenses": [],
    "has_assigned_users": false,
    "addresses": [
        {
            "uuid": "60c132a43b-5ab5-434a91-a4ec-d6e4704d4937",
            "address_1": "Chinchwad",
            "address_2": "",
            "address_3": "",
            "city": "Pune",
            "state": "MH",
            "subregion": "MH",
            "country": "IND",
            "postal_code": "412105",
            "translated_country_name": null,
            "translated_subregion_name": null,
            "latitude": "18.64742",
            "longitude": "73.80003",
            "timezone_name": "Asia/Kolkata",
            "types": [
                "main"
            ],
            "cascaded_at": null,
            "is_current": true,
            "usage_types": [
                {
                    "name": "main"
                }
            ]
        }
    ],
    "email_addresses": [],
    "telecom_addresses": [],
    "status": "planned",
    "team_memberships_count": 0,
    "cascaded_at": null,
    "address_usages": [
        {
            "uuid": "e58efc53223a-2028-4f7a-bc56-e8d72f4f2c18",
            "active": true,
            "usage_types": [
                {
                    "name": "main"
                }
            ],
            "address": {
                "uuid": "60c123a43b-5ab5-4a91-a4ec-d6e4704d4937",
                "address_1": "Chinchwad",
                "address_2": "",
                "address_3": "",
                "city": "Pune",
                "subregion": "MH",
                "country": "IND",
                "postal_code": "412105",
                "translated_country_name": null,
                "translated_subregion_name": null,
                "latitude": "18.64742",
                "longitude": "73.80003",
                "timezone_name": "Asia/Kolkata"
            },
            "is_current": true,
            "cascaded_at": null
        }
    ],
    "active_pi_tm": null,
    "main_address": {
        "address_1": "Chinchwad",
        "address_2": "",
        "address_3": "",
        "city": "Pune",
        "state": "MH",
        "subregion": "MH",
        "country": "IND",
        "postal_code": "412105",
        "translated_country_name": null,
        "translated_subregion_name": null,
        "latitude": "18.64742",
        "longitude": "73.80003",
        "timezone_name": "Asia/Kolkata"
    }
}];
//transform respective response into new Key
const newKeyMap={
    uuid:"uuid",
    site_number:"siteNumber",
    name:"siteName",
    main_address:"mainAddress",
   "main_address.address_1":"address_1",
   "main_address.address_2":"address_2",
   "main_address.address_3":"address_3",
   "main_address.city":"city",
   "main_address.state":"state",
   "main_address.subregion":"subregion",
   "main_address.country":"country",
   "main_address.postal_code":"postal_code",
    "study_environment_uuid":"studyEnvironmentuuid",
    "team_memberships_count":"teamMembershipCount",
    "has_assigned_users":"hasAssignedUsers",
    "orgId":"clientDivisionOrganizationId"
};
function camelize(text) {
    const a = text.toLowerCase()
        .replace(/[-_\s.]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
    return a.substring(0, 1).toLowerCase() + a.substring(1);
}

const transformArrayObject=(originalArray,newKeyMap)=>{
return originalArray.map(obj => {
  const transformedObj = Object.entries(obj).reduce((acc, [key, value]) => {
if (typeof value === "object" && !Array.isArray(value) && value!==null) {
  const nestedObj = Object.entries(value).reduce((nestedAcc, [nestedKey, nestedValue]) => {
    const newNestedKey = newKeyMap[`${camelize(key)}.${camelize(nestedKey)}`] || camelize(nestedKey);
    nestedAcc[camelize(newNestedKey)] = nestedValue;
    //console.log("First If",key);
    return nestedAcc;
  }, {});
  acc[camelize(key)] = nestedObj;
} else if (Array.isArray(value) && value.length>0) {

  acc[camelize(key)] = value.map(nestedObj => {
    return Object.entries(nestedObj).reduce((nestedAcc, [nestedKey, nestedValue]) => {
      const newNestedKey = newKeyMap[`${key}.${camelize(nestedKey)}`] || nestedKey;
      nestedAcc[camelize(newNestedKey)] = nestedValue;
      return nestedAcc;
    }, {});
  });
} else {
    
  const newKey = newKeyMap[camelize(key)] || camelize(key);
  acc[newKey] = value;
}
return acc;
  }, {});
  return transformedObj;
});
}
console.log("Result:",transformArrayObject(originalArray,newKeyMap));

2 Answers 2

1

Sorry to admit that I have a bit of trouble following your original code, but you could use recursion to take care of the nested objects. Your existing transformation is just about there but you need to also transform the values of the object entries. This is a bit easier if you define a separate function to organise the code.

function transform(value, keyMap, prefix="") {
  // Transform the keys in the given value, recursively.

  if (Array.isArray(value)) {
    // Array entries use the prefix unchanged
    return value.map(value => transform(value, keyMap, prefix));
  }
  else if (value && typeof value === "object") {
    // Do most of the work here ...
    return Object.entries(value).reduce((nestedAcc, [nestedKey, nestedValue]) => {
      const newNestedKey = keyMap[`${prefix}${nestedKey}`] || camelize(nestedKey);
      // Add the new key to the prefix while we recurse
      const newPrefix = `${nestedKey}.`;
      nestedAcc[newNestedKey] = transform(nestedValue, keyMap, newPrefix);
      return nestedAcc;
    }, {});
  }
  else {
    // Easy case -- it's a non-object/non-array, just return it as-is
    return value;
  }
}

// Allow override of key names -- can specify nested keys by joining with `.`
// (Note: many of the entries in your initial map were redundant)
const newKeyMap={
    "name":"siteName",
    "study_environment_uuid":"studyEnvironmentuuid",
    "team_memberships_count":"teamMembershipCount",
    "org_id":"clientDivisionOrganizationId",

    // Unnecessary example to show nesting
    "main_address.timezone_name": "timezone_name"
};

function camelize(text) {
    const a = text.toLowerCase()
        .replace(/[-_\s.]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
    return a.substring(0, 1).toLowerCase() + a.substring(1);
}

const originalArray =[{
    "uuid": "65a49008-91ba-4dc6-8fd8-476c4ea7b84d",
    "name": "Post-man Hospital-local",
    "site_number": "PKKk-2219232",
    "phone": "",
    "fax": "",
    "org_id": "PKKKK-2219232",
    "principal_investigator_user_uuid": null,
    "client_division_site_uuid": "a82733418f-f532-429d-8671-ba4cec5a3b93",
    "client_division_scheme_uuid": "8cbeb43c3a-b74d-4998-be2b-ab75f378e247",
    "study_uuid": "863080ac-5335-472334-9103-50ea782da3c9",
    "principal_investigator": {
        "uuid": null,
        "email": null,
        "first_name": null,
        "last_name": null
    },
    "study_environment_country_uuid": "08f943d64d-bf31-43b9-b320-59d80797e05e",
    "licenses": [],
    "has_assigned_users": false,
    "addresses": [
        {
            "uuid": "60c1a43b-5ab5-434a91-a4ec-d6e4704d4937",
            "address_1": "Chinchwad",
            "address_2": "",
            "address_3": "",
            "city": "Pune",
            "state": "MH",
            "subregion": "MH",
            "country": "IND",
            "postal_code": "412105",
            "translated_country_name": null,
            "translated_subregion_name": null,
            "latitude": "18.64742",
            "longitude": "73.80003",
            "timezone_name": "Asia/Kolkata",
            "types": [
                "main"
            ],
            "cascaded_at": null,
            "is_current": true,
            "usage_types": [
                {
                    "name": "main"
                }
            ]
        }
    ],
    "email_addresses": [],
    "telecom_addresses": [],
    "status": "planned",
    "team_memberships_count": 0,
    "cascaded_at": null,
    "address_usages": [
        {
            "uuid": "e58efc532a-2028-4f7a-bc56-e8d72f4f2c18",
            "active": true,
            "usage_types": [
                {
                    "name": "main"
                }
            ],
            "address": {
                "uuid": "60c1a43b-5ab5-4a91-a4ec-d6e4704d4937",
                "address_1": "Chinchwad",
                "address_2": "",
                "address_3": "",
                "city": "Pune",
                "subregion": "MH",
                "country": "IND",
                "postal_code": "412105",
                "translated_country_name": null,
                "translated_subregion_name": null,
                "latitude": "18.64742",
                "longitude": "73.80003",
                "timezone_name": "Asia/Kolkata"
            },
            "is_current": true,
            "cascaded_at": null
        }
    ],
    "active_pi_tm": null,
    "main_address": {
        "address_1": "Chinchwad",
        "address_2": "",
        "address_3": "",
        "city": "Pune",
        "state": "MH",
        "subregion": "MH",
        "country": "IND",
        "postal_code": "412105",
        "translated_country_name": null,
        "translated_subregion_name": null,
        "latitude": "18.64742",
        "longitude": "73.80003",
        "timezone_name": "Asia/Kolkata"
    }
}];


const transformedArray = transform(originalArray, newKeyMap);
console.log("Result:", transformedArray);

2
  • Thanks @motto , you are answer has save my time. I just have one doubt . if I want to make this function configurable as originalArray and newKeyMap then what would be ideal way. I mean originalArray and newKeyMap as arguments to this function Commented May 8, 2023 at 9:34
  • @PramodKharade keyMap is now accepted as a parameter to transform. Also fixed a bug where transform would try to camelize the pre-formatted keys from keyMap.
    – motto
    Commented May 8, 2023 at 10:01
0

You could use a recursive approach and hand over the path to the property for checking with given new keys.

const
    originalArray = [{ uuid: "65a49008-3291ba-4dc6-8fd8-476c4ea7b84d", name: "Post-man Hospital-local", site_number: "PKKk-2219232", phone: "", fax: "", org_id: "PKKKK-2219232", principal_investigator_user_uuid: null, study_uuid: "863080a12c-5335-472334-9103-50ea782da3c9", principal_investigator: { uuid: null, email: null, first_name: null, last_name: null }, licenses: [], has_assigned_users: false, addresses: [{ uuid: "60c132a43b-5ab5-434a91-a4ec-d6e4704d4937", address_1: "Chinchwad", address_2: "", address_3: "", city: "Pune", state: "MH", subregion: "MH", country: "IND", postal_code: "412105", translated_country_name: null, translated_subregion_name: null, latitude: "18.64742", longitude: "73.80003", timezone_name: "Asia/Kolkata", types: ["main"], cascaded_at: null, is_current: true, usage_types: [{ name: "main" }] }], email_addresses: [], telecom_addresses: [], status: "planned", team_memberships_count: 0, cascaded_at: null, address_usages: [{ uuid: "e58efc53223a-2028-4f7a-bc56-e8d72f4f2c18", active: true, usage_types: [{ name: "main" }], address: { uuid: "60c123a43b-5ab5-4a91-a4ec-d6e4704d4937", address_1: "Chinchwad", address_2: "", address_3: "", city: "Pune", subregion: "MH", country: "IND", postal_code: "412105", translated_country_name: null, translated_subregion_name: null, latitude: "18.64742", longitude: "73.80003", timezone_name: "Asia/Kolkata" }, is_current: true, cascaded_at: null }], active_pi_tm: null, main_address: { address_1: "Chinchwad", address_2: "", address_3: "", city: "Pune", state: "MH", subregion: "MH", country: "IND", postal_code: "412105", translated_country_name: null, translated_subregion_name: null, latitude: "18.64742", longitude: "73.80003", timezone_name: "Asia/Kolkata" } }],
    newKeyMap = { uuid: "uuid#", site_number: "siteNumber#", name: "siteName#", main_address: "mainAddress#", "main_address.address_1": "address_1#", "main_address.address_2": "address_2#", "main_address.address_3": "address_3#", "main_address.city": "city#", "main_address.state": "state#", "main_address.subregion": "subregion#", "main_address.country": "country#", "main_address.postal_code": "postal_code#", study_environment_uuid: "studyEnvironmentuuid#", team_memberships_count: "teamMembershipCount#", has_assigned_users: "hasAssignedUsers#", orgId: "clientDivisionOrganizationId#" },
    camelize = text => {
        const a = text.toLowerCase().replace(/[-_\s.]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
        return a.substring(0, 1).toLowerCase() + a.substring(1);
    },
    getKey = (key, path = '') => path + (path && ".") + key,
    transform = (keys, path = "") => obj => {
        const transformedObj = Object.entries(obj).reduce((acc, [key, value]) => {
            const newKey = keys[getKey(key, path)] || camelize(key);
            if (Array.isArray(value)) acc[newKey] = transformArrayObject(value, keys);
            else if (value && typeof value === "object") acc[newKey] = transform(keys, getKey(key, path))(value);
            else acc[newKey] = value;
            return acc;
        }, {});
        return transformedObj;
    },
    transformArrayObject = (originalArray, newKeyMap) => originalArray.map(transform(newKeyMap)),
    result = transformArrayObject(originalArray, newKeyMap);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Not the answer you're looking for? Browse other questions tagged or ask your own question.