Skip to content

Instantly share code, notes, and snippets.

@mfcodeworks
Last active July 30, 2021 10:17
Show Gist options
  • Save mfcodeworks/1a8d8abef6216cf7503c9ba17dfd21b4 to your computer and use it in GitHub Desktop.
Save mfcodeworks/1a8d8abef6216cf7503c9ba17dfd21b4 to your computer and use it in GitHub Desktop.
Dynamically get the nested value from an object, update or delete flags for modification
/**
* Traverse object path and optionally update value
* @param obj Object to traverse
* @param path Object path -
* Include array indexes as a regular dot-key notation e.g. `parent.0.key` -
* *Doesn't support keys with a . inside*
* @param flags Flags object for modifying key value
* - `newValue` New value to set the key to
* - `deleteValue` If true the key will be deleted from object
*/
export const traverseObject = <T = any>(
obj: Record<string | number | symbol, T>,
path: string,
{
newValue,
deleteValue
}: {
newValue?: any;
deleteValue?: boolean;
} = {}
): T => {
// Seperate keys into array
const keys = path.split('.');
// Get next key
const [key] = keys;
// If more keys remain, recurse through object
if (keys.length > 1) {
return traverseObject<T>(
obj[key] as Record<string | number | symbol, any>,
keys.slice(1).join('.'),
{
newValue,
deleteValue
}
);
} else {
// If a newValue is set, update the key value
if (typeof newValue !== 'undefined') {
obj[key] = newValue;
// If delete is true, delete value
} else if (deleteValue) {
delete obj[key];
}
// Return value
return obj[key];
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment