Cómo obtener un solo objeto de esta matriz de objetos, y si es verdadero en alguna de las propiedades, debe establecerse en verdadero.
Por ejemplo, si BILLING_CYCLE para la propiedad de vista tiene un valor verdadero en uno de los objetos, el objeto devuelto debe tener un valor verdadero.
Como puede ver, los grupos se pueden anidar, por lo que se necesita recursividad. Estas son interfaces de objeto.
interface UserPermissions { [key: string]: UserPermission; } interface UserPermission { view: boolean; modify: boolean; delete?: boolean; additionalActions?: { [key: string]: boolean }; groups?: { [key: string]: UserPermission }; } const data = [ { "BILLING": { "view": false, "modify": false, "additionalActions": {}, "groups": { "BILLING_CYCLE": { "view": false, "modify": false, "additionalActions": { "CONFIRM": false }, "groups": {} }, "ACCOUNT": { "view": false, "modify": false, "additionalActions": {}, "groups": {} }, "ADMIN": { "view": true, "modify": true, "additionalActions": {}, "groups": {} } } } }, { "BILLING": { "view": true, "modify": true, "additionalActions": {}, "groups": { "BILLING_CYCLE": { "view": true, "modify": true, "additionalActions": { "CONFIRM": true }, "groups": {} }, "ACCOUNT": { "view": true, "modify": true, "additionalActions": {}, "groups": {} }, "ADMIN": { "view": false, "modify": false, "additionalActions": {}, "groups": {} } } } } ] const expectation = { "BILLING": { "view": true, "modify": true, "additionalActions": {}, "groups": { "BILLING_CYCLE": { "view": true, "modify": true, "additionalActions": { "CONFIRM": true }, "groups": {} }, "ACCOUNT": { "view": true, "modify": true, "additionalActions": {}, "groups": {} }, "ADMIN": { "view": true, "modify": true, "additionalActions": {}, "groups": {} } } } } }Sugeriría crear una función de fusión, digamos, mergePermissions() , luego llame a Array.reduce() en la entrada, fusionando cada objeto con el objeto acumulador de forma recursiva.
Para cada propiedad, mantendremos el valor existente, a menos que sea un valor booleano. Si es así, realizaremos una comparación or (||), por lo que si es verdadero, entonces el resultado también será verdadero.
const data = [ { "BILLING": { "view": false, "modify": false, "additionalActions": {}, "groups": { "BILLING_CYCLE": { "view": false, "modify": false, "additionalActions": { "CONFIRM": false }, "groups": {} }, "ACCOUNT": { "view": false, "modify": false, "additionalActions": {}, "groups": {} }, "ADMIN": { "view": true, "modify": true, "additionalActions": {}, "groups": {} } } } }, { "BILLING": { "view": true, "modify": true, "additionalActions": {}, "groups": { "BILLING_CYCLE": { "view": true, "modify": true, "additionalActions": { "CONFIRM": true }, "groups": {} }, "ACCOUNT": { "view": true, "modify": true, "additionalActions": {}, "groups": {} }, "ADMIN": { "view": false, "modify": false, "additionalActions": {}, "groups": {} } } } } ] function mergePermissions(obj1, obj2) { let result = {}; for(let k in obj1) { if (obj1[k] && typeof(obj1[k]) === 'object') { result[k] = mergePermissions(obj1[k], (obj2?.[k])) ; } else if ((typeof(obj1[k]) === 'boolean') && (typeof(obj2?.[k]) === 'boolean')) { result[k] = obj1[k] || (obj2?.[k]); } else { result[k] = obj1[k]; } } return result; } let result = data.reduce((acc, el) => { return mergePermissions(el, acc); }, {}) console.log('Result:', result);