Working with deeply nested objects
Published: Sun Feb 11 2024
Topics:
The ability to access a deeply nested property is very useful in JavaScript. For instance, consider the following object:
const obj = {
id: 1,
details: {
info: {
category: 'A'
}
}
};
You could access the category
property by using either the bracket notation or the dot notation:
// Using dot notation
obj.details.info.category // Produces value 'A'
// Using bracket notation
obj['details']['info']['category'] // Produces value 'A'
However, sometimes you don't know the property path structure in advance. In those cases, it is useful to have a helper function (which I have called accessNested
) that accepts an arbitrarily long string containing the property path:
// Using helper function
// Produces value 'A'
accessNested(obj, 'details.info.category')
Here is the implementation of the accessNested
function:
// Access and return the value of a nested object property by its path
function accessNested(object, prop_path) {
let parts = prop_path.split('.');
let value = object;
for (let i=0; i < parts.length; i++) {
value = value[parts[i]];
}
return value;
}
The cool thing about this is that you can use the accessNested
function to filter an array of objects that share a specific property, no matter how deeply nested it may be.
Consider the following array of objects:
const arr = [
{
id: 1,
details: {
info: {
category: 'A'
}
}
},
{
id: 2,
details: {
info: {
category: 'B'
}
}
},
{
id: 3,
details: {
info: {
category: 'A'
}
}
}
];
You can get the set of objects whose property details.info.category
is equal to A
:
arr.filter(item => accessNested(item, 'details.info.category') == 'A');
You could go even further and create another helper function (let's call it filterByPropertyTest
), so that you could do this:
filterByPropertyTest(
arr,
'details.info.category',
(value) => value === 'A'
)
whose arguments are (in sequential order):
- the array of objects to be filtered
- the property path to be inspected
- a function that accepts a value, performs any kind of test and returns a boolean that needs to be true if the item is to be kept in the resulting set.
The implementation of filterByPropertyTest
would be:
// Filter items from an array of objects by testing the value of a nested property
function filterByPropertyTest(array, prop_path, test_function) {
return array.filter( item => {
let value = accessNested(item, prop_path);
return test_function(value);
});
}