Reputation: 321
The problem I'm having is that I have an array couple of identical objects that looks something like:
[
{
error:null,
permissions:{
perm1:false,
perm2:true,
perm3:false,
etc...
}
},
{
error:null,
permissions:{
perm1:true,
perm2:false,
perm3:false,
etc...
}
},
{
error:null,
permissions:{
perm1:false,
perm2:false,
perm3:false,
etc...
}
},
etc..
]
I need to do is "add" all of them together and get something like:
{
error:null,
permissions:{
perm1:true,
perm2:true,
perm3:false,
etc...
}
}
I though up of this code:
var newObj = {};
for(myObject in objectArray){
for(var [key, value] of Object.entries(myObject)){
newObj[key] = (newObj[key] === true ? true : value)
}
}
return newObj;
But that doesn't seem really efficient (or like it would work...), and I need the most efficient and fast method. If you could point me in the right direction, or link me to a question that might help me.
Upvotes: 0
Views: 49
Reputation: 50884
You could use .reduce()
with the first object in your array as the accumulator. For each object in your array you can loop though the keys in your accumulator's permissions and change its true
/false
value based on whether the current object's value is true
:
const arr = [{ error: null, permissions: { perm1: false, perm2: true, perm3: false, } }, { error: null, permissions: { perm1: true, perm2: false, perm3: false, } }, { error: null, permissions: { perm1: false, perm2: false, perm3: false, } } ];
const [{error, permissions: p}] = arr;
const res = arr.reduce((acc, {permissions}) => {
for(const key in acc.permissions)
acc.permissions[key] = acc.permissions[key] || permissions[key];
return acc;
}, {error, permissions: {...p}});
console.log(res);
Upvotes: 0
Reputation: 371049
If the keys in all objects are the same, you can take an array of one of the objects' keys, then iterate over each key and identify whether it should be true or false by checking whether .some
of the objects have true for it:
const arr = [
{
error:null,
permissions:{
perm1:false,
perm2:true,
perm3:false,
}
},
{
error:null,
permissions:{
perm1:true,
perm2:false,
perm3:false,
}
},
{
error:null,
permissions:{
perm1:false,
perm2:false,
perm3:false,
}
},
];
const errorObj = arr.find(({ error }) => error);
if (errorObj) {
throw new Error(errorObj.error);
}
const keys = Object.keys(arr[0].permissions);
const permissions = Object.fromEntries(keys.map(
key => [key, arr.some(({ permissions }) => permissions[key])]
));
console.log({ error: null, permissions });
There are some optimizations that might be make that might be worthwhile in some circumstances, but this is fundamentally an O(n^2)
operation regardless, and the most important thing to do is to short-circuit a property to true
when a match is found, rather than continuing through the rest of the array, which the .some
accomplishes.
Upvotes: 1
Reputation: 1448
Please try this
var objectArray=[
{
error:null,
permissions:{
perm1:false,
perm2:true,
perm3:false
}
},
{
error:null,
permissions:{
perm1:true,
perm2:false,
perm3:false
}
},
{
error:null,
permissions:{
perm1:false,
perm2:false,
perm3:false
}
}
]
var newObj = null;
for(myObject in objectArray){
let x=objectArray[myObject]
if(newObj===null){
newObj=x;
}else{
Object.keys(x.permissions).map(i=>{
if(!newObj.permissions[i]){
newObj.permissions[i]=x.permissions[i];
}
})
}
}
console.log(newObj)
Upvotes: 1