Something I've found myself having to do reasonably often is map properties from an Object (usually a heavily nested MongoDB document) to a different 'shape' to then pass it to a function call or API endpoint etc. Combine this with a development environment in which these 'shapes' are prone to change and it felt messy to do the mapping manually each time (though learning object destructuring often made it much neater!).
I've written this code to accept two arrays containing key names, an object and a delimiter option. The function then returns an object containing the properties pointed to by the keys in the input array, but with the key names as specified in the output array.
const transposeObjectByArraysOfPairs = (input, output, object, delimiter = '.') => {
const toReturn = {};
input.map((keyString, idx) => {
const keysIn = keyString.split(delimiter);
// copy object to avoid mutating original
let _currentProp = Object.assign({}, object);
for (let i = 0; i < keysIn.length; i++) {
_currentProp = _currentProp[keysIn[i]];
}
const keysOut = output[idx].split(delimiter);
let len = keysOut.length;
let _obj = {[keysOut[len - 1]]: _currentProp};
for (let j = len - 2 ; j >= 0; --j) {
_obj = {[keysOut[j]]: _obj};
}
Object.assign(toReturn, _obj);
});
return toReturn;
};
const object = {a : {b: { c: 10, d: 30 }}};
const input = ['a.b.c', 'a.b.d'];
const output = ['A.B', 'B.C'];
console.log(misc.transposeObjectByArraysOfPairs(input, output, object));
// { A: { B: 10 }, B: { C: 30 } }
Whilst this function has neatened up chunks of my code significantly, I can't help but feel there's a neater way to do this. Iterating through an array of keys to get to the desired property feels quite hacky in particular.
In a perfect world I think I'd essentially have a function that mapped from one object schema to another and then I could simply maintain schema and know that if I made changes, I wouldn't need to modify the code that did the mapping.