In my dataset, there are objects nested deeply with arrays, objects within arrays, and so on.
Each nested object includes a property called sys
, which contains another property called id
.
I have a list of specific id
values that I want to remove from the original object. How can I recursively loop through the entire structure and adjust it to exclude these unwanted values?
For instance, consider the following data:
let data = {
sys: {
id: '1'
},
items: [
{
sys: {
id: '2'
},
fields: {
title: 'Item title',
sponsor: {
sys: {
id: '3'
},
fields: {
title: 'Sponsor Title'
}
},
actions: [
{
sys: {
id: '4'
},
fields: {
title: 'Google',
url: 'google.com'
}
},
{
sys: {
id: '5'
},
fields: {
title: 'Yahoo',
url: 'yahoo.com'
}
}
]
}
}
]
}
And here is an array of id
's to delete:
const invalidIds = ['3', '5'];
After running the function, the resulting object should have the property with sys.id
of '3'
set to null
, while the object with sys.id
of '5'
should be removed entirely from its containing array:
// Expected Output:
{
sys: {
id: '1'
},
items: [
{
sys: {
id: '2'
},
fields: {
title: 'Item title',
sponsor: null,
actions: [
{
sys: {
id: '4'
},
fields: {
title: 'Google',
url: 'google.com'
}
}
]
}
}
]
}
Utilizing guidance from this solution, I am able to recursively search throughout the object and its nested arrays:
const process = (key, value) => {
if (typeof value === 'object' && value.sys && value.sys.id && invalidIds.includes(value.sys.id)) {
console.log('found one', value.sys.id);
}
};
const traverse = (obj, func) => {
for (let key in obj) {
func.apply(this, [key, obj[key]]);
if (obj[key] !== null) {
if (typeof obj[key] === 'object') {
traverse(obj[key], func);
} else if (obj[key].constructor === Array) {
obj[key].map(item => {
if (typeof item === 'object') {
traverse(item, func);
}
});
}
}
}
};
traverse(data, process);
However, I am struggling to properly alter the array. Furthermore, I would prefer to create a completely new object rather than modifying the existing one to maintain immutability.