Home > Software design >  Set all keys of an object to false or true including nested objects
Set all keys of an object to false or true including nested objects

Time:11-06

I am trying to set all the keys to either false or true based on an event.

const odba = {
  "all": false,
  "allA": false,
  "allB": false,
  "allC": {
    "allD": false,
    "allE": { "allF": true },
  }
}

Object.keys(odba).forEach(function(key, value) {
  return odba[key] = false;
})

console.log(odba);

The above code results in:

{
  all: false,
  allA: false,
  allB: false,
  allC: false
}

however this is not correct since nested objects were ignored. I tried the following as well:

Object.keys(odba).forEach(function(key, value) {
        if(typeof key === 'object')
    {
            Object.keys(key).forEach(function(k, v){
        return odba[k] = false;
        })
    }
    return odba[key] = false;
})

CodePudding user response:

You can create a function that you can recursively call on your nested object values to set their values to false. By checking if a value is an object, you can call the function again with the object value, for example:

function allToFalse(obj) {
  Object.keys(obj).forEach(function(key) {
    const value = obj[key];
    if(Object(value) === value) // if value is an object
      allToFalse(value);
    else
      obj[key] = false;
  });
}

const odba = { "all": false, "allA": false, "allB": false, "allC": { "allD": false, "allE": { "allF": true }, } }
allToFalse(odba);
console.log(odba);

The above will modify your object in place (as your current code does). If you want to create a function that produces a new object and leaves the old one as is, then you can use Object.fromEntries() with .map() to build a new object, again using recursion to build your nested objects also. For example:

function allToFalse(obj) {
  return Object.fromEntries(Object.entries(obj).map(([key, val]) =>
    [key, Object(val) === val ? allToFalse(val) : false]
  ));
}

const odba = { "all": false, "allA": false, "allB": false, "allC": { "allD": false, "allE": { "allF": true }, } }
console.log(allToFalse(odba));

There's also a "hack" that you can do with JSON.parse() and its reviver function. Firstly, you can stringify your object into a JSON string, and then parse it back into an object, where you use the reviver to specify false as the new value. JSON.parse() will handle the recursion for you, but this method isn't very efficient and can potentially make you lose some properties (see here):

function allToFalse(obj) {
  return JSON.parse(JSON.stringify(obj), (key, val) => typeof val === "boolean" ? false : val);
}

const odba = { "all": false, "allA": false, "allB": false, "allC": { "allD": false, "allE": { "allF": true }, } }
console.log(allToFalse(odba));

  • Related