kriskotoo BG
kriskotoo BG

Reputation: 321

Compare and process booleans in an object

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

Answers (3)

Nick Parsons
Nick Parsons

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

CertainPerformance
CertainPerformance

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

kelvin kantaria
kelvin kantaria

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

Related Questions