Skip to content

Instantly share code, notes, and snippets.

@westc
Last active September 16, 2024 22:39
Show Gist options
  • Save westc/da1572761174e1e5be06e2ba7674492e to your computer and use it in GitHub Desktop.
Save westc/da1572761174e1e5be06e2ba7674492e to your computer and use it in GitHub Desktop.
Destructures values from a `root` object based on one or more `nestedMaps` structures.
/**
* Destructures values from a `root` object based on one or more `nestedMaps`
* structures.
* @param {Object} root
* The root object or array containing the data to destructure.
* @param {...NestedMap} nestedMaps
* One or more nested mapping objects. Each key in the `NestedMap` is a
* string, and each value is either:
* - A string (which specifies the key in the result object), or
* - A `NestedMap` (which specifies further nested extraction).
* @returns {Record<string, any>}
* An object containing the extracted values, with keys as specified by the
* `nestedMaps`.
* @throws {Error}
* Throws an error if a recursive structure is detected in the `root` object.
* @template {Record<string, string | NestedMap>} NestedMap
*/
function destruct(root, ...nestedMaps) {
function recurse(root, nestedMap, seen) {
for (const [key, value] of Object.entries(nestedMap)) {
const rootValue = (+key < 0 && Array.isArray(root)) ? root.at(+key) : root[key];
if (typeof value !== 'object') {
returnValue[value] = rootValue;
}
else if (rootValue != null) {
if (seen.includes(rootValue)) {
throw new Error('Cannot use a recursive structure as the nested map.');
}
seen.push(rootValue);
recurse(rootValue, value, seen);
}
}
}
// The object that will store the extracted values.
const returnValue = {};
// Iterate over each nested map and apply the recursion
for (const nestedMap of nestedMaps) {
recurse(root, nestedMap, []);
}
return returnValue;
}
var data = {
event: {
app: "monday",
type: "update_column_value",
triggerTime: "2024-09-16T15:03:05.631Z",
subscriptionId: 409408840,
userId: -4,
originalTriggerUuid: "1c097ddf26d7db04e785b6c3910812b6",
boardId: 7438104037,
groupId: "topics",
pulseId: 7438104160,
pulseName: "Item 1",
columnId: "status",
columnType: "color",
columnTitle: "Status",
value: {
label: {
index: 0,
text: "Working on it",
style: {
color: "#fdab3d",
border: "#e99729",
var_name: "orange"
},
is_done: false
},
post_id: null
},
previousValue: {
label: {
index: 5,
text: null,
style: {
color: "#c4c4c4",
border: "#b0b0b0",
var_name: "grey"
},
is_done: false
},
post_id: null
},
changedAt: 1726498985.1396656,
isTopGroup: true,
triggerUuid: "c48d7a18702d068c3a477cc8b7091b9c"
},
people: [
'Chris',
'Jamie',
'Stacey'
]
};
console.log(
extract(
data,
{
people: {
0: 'firstPerson',
'-1': 'lastPerson'
},
event: {
app: 'app',
type: 'type',
triggerTime: 'triggerTime',
}
},
{people: 'people'}
)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment