Here is a recursive solution that filters and returns all elements from a given list of elements that contain matching data in a given subset object.
export const containsSubset = (superset: any, subset: any): boolean => {
return Object.keys(subset).reduce((subsetInSuperset: boolean, key: string) => {
// In case the property is an object, check inside that object
if (isObject(subset[key])) {
return subsetInSuperset && containsSubset(superset[key], subset[key]);
}
// In case the property is an array, check for every element
if (Array.isArray(subset[key])) {
return subsetInSuperset &&
subset[key].reduce((subsetArrayInSupersetArray: boolean, arrayElement: any, i: number) =>
subsetArrayInSupersetArray && containsSubset(superset[key][i], arrayElement),
true,
);
}
// In case the property is a primitive, we can simply compare directly
return subsetInSuperset && superset[key] === subset[key];
}, true); // The initialization value must be true (since we use &&)
};
I nicked this function from another Stackoverflow question (Check if a value is an object in JavaScript):
export const isObject = (variable: any) =>
typeof variable === 'object' && !Array.isArray(variable) && variable !== null;
With your test data (modified)
const list = [
{
id: 152956,
appname: 'tst',
approvalStatus: 'Validated',
children: [],
clapp: { owner: '07D', code: 'TST', fullCLAPP: '07D/TST/G-PM' },
company: { id: 9705, name: 'Dot Com', code: '07D' },
connectionType: '',
dnsNode: '',
kind: 'Standard',
validatedOnce: true,
},
{
id: 19876,
appname: 'comptest',
approvalStatus: 'Validated',
children: [],
clapp: { owner: '07D', code: 'CMP', fullCLAPP: '07D/CMP/G-PM' },
company: { id: 765, name: 'IT jira', code: '07D' },
connectionType: '',
dnsNode: '',
kind: 'Standard',
validatedOnce: true,
testArray: ['a', 'q', { id: 3, name: 'a' }],
},
];
const testFalse = {
appname: 'airline',
code: '07',
company: { name: 'abcd' },
};
const testTrue = {
appname: 'comptest',
clapp: { code: 'CMP' },
company: { name: 'IT jira', code: '07D' },
testArray: ['a', 'q', { id: 3, name: 'a' }],
};
Run code
// Empty array
const elementsWithSubsetEmpty = list.filter((x) => containsSubset(x, testFalse));
// Array with filtered elements of your "list" variable that contain the properties of "testTrue"
const elementsWithSubset = list.filter((x) => containsSubset(x, testTrue));