I have an object that can be deeply nested with objects, arrays, arrays of objects, and so on.
Every nested object has a sys property which in turn has an id property.
I have a separate list of id values that correspond to objects that I want to remove from the original object. How can I go about recursively looping through the entire object and modify it to no longer include these?
For example, say I have 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'
            }
          }
        ]
      }
    }
  ]
}
Then I have an array of id's to remove:
const invalidIds = ['3', '5'];
After I run the function, the resulting object should have the property with sys.id of '3' set to null, and the object with sys.id of '5' should simply be removed from its containing array:
// Desired Output:
{
  sys: {
    id: '1'
  },
  items: [
    {
      sys: {
        id: '2'
      },
      fields: {
        title: 'Item title',
        sponsor: null,
        actions: [
          {
            sys: {
              id: '4'
            },
            fields: {
              title: 'Google',
              url: 'google.com'
            }
          }
        ]
      }
    }
  ]
}
With help from this solution, I'm able to recursively search through the object and its various 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 can't figure out how to properly modify the array. In addition, I'd prefer to create an entirely new object rather than modify the existing one in order to keep things immutable.
 
    