3

How can I change all nested object values to "true" without using extra space Can anyone help me in this. I have tried in this way but I am not getting the logic to handle the nested object

P.S: Please don't concentrate about "true" or "false" is in string because it is mock data,I just want logic to implement which I am failing to do.

const config = {
  header:{"logo":"true","nav":"false","user":"false"},
  searchResults:{"listView":"false","favorite":"true","share":"false","pagination":"true","filters":"true","sortBy":"false"},
  sharedLinks:{},
  learnerLinks:{},
  lukePreview:{"toc":"false","controls":"false"},
  lukeLaunch:{"toc":"false","controls":"false"},
  misc:{"import":"true"}
}

function changeBoolean(obj,propName){
  for(let i in obj){
    if( typeof obj[i] === 'object'){
       changeBoolean(obj[i],i)
    }
  }
  return obj
}
console.log(changeBoolean(config,'header'))

5
  • 5
    "without modifying the original object" - What do you mean here exactly? The "nested object values" are part of that original object. Do you want a copy of the config and only modify that copy? Commented Sep 8, 2021 at 6:35
  • 1
    You changed "without modifying the original object" to "without using extra space" what does that mean? Commented Sep 8, 2021 at 6:39
  • @Andreas It means my updated object should be same object which I have created but not a new object or I don't want to create a new object for solving and I am newbie suggest if I am wrong Commented Sep 8, 2021 at 6:40
  • 2
    Your code is not changing anything to the given object. There is no property assignment in your function. Secondly, there are no boolean values in your data. Commented Sep 8, 2021 at 6:40
  • Why are you using strings ("true" and "false") instead of booleans (true/false)? Commented Sep 8, 2021 at 6:46

3 Answers 3

2

Try to assign the function's result, like this:


function changeBoolean(obj, propName) {
  for (let i in obj) {
    if (typeof obj[i] === "object") {
      obj[i] = changeBoolean(obj[i], propName);
    } else {
      obj[i] = "true";
    }
  }
  return obj;
}
Sign up to request clarification or add additional context in comments.

3 Comments

can you give some explanation why we are storing recursive function value in obj[i]
Function changeBoolean return obj, so if we need to change obj nested value, then we must change obj[i] value with the correct value.
obj[i] = changeBoolean(obj[i], propName); Here from function we are returning an object and stored in obj[i] and obj[i] is Object now and how that object is iterated I am not able to get it. Can you explain me better or provide some releavent example to understand your logic.
0

You write:

Can we modify nested object values without modifying original object?

This sounds like a contradiction. When you mutate a nested object, then that is a mutation of the original object. It looks like you want immutability. This means that as soon as you need a change in a nested object, you create a copy of it that has the change, and this change will then bubble upwards, resulting in new copies of objects as they receive a new "child" object.

...without extra space

You cannot have both: either you mutate the original object (in its nested parts), or you create a new one. If you don't want the original object to mutate, then you obviously need space for the replacing object.

Some issues

  • Your input object has no boolean values. It has strings like "false" and "true", but those are not booleans. So I suggest to work with truly boolean values, without the quotes

  • Your code is not setting any property, so it can never mutate anything to your object

  • Your data has no "header" property, so that would be another reason why your code could not have changed anything.

  • The second argument you pass to the recursive call is i, which is not the property you wanted to change. You should just pass propName there.

Some assumptions I'll make

  • The function is to return the original object when it finds that there is nothing change. This should also be the principle for nested objects.
  • When the object has a property with the given name, but it is not a boolean, then it will not be changed. Only when that property value is a boolean there will be a change
  • The change will toggle the boolean. So if it was false it should become true and vice versa.
  • No object should be mutated. If something changes, a new object should be created and returned.

Here is how I would do that. This snippet runs with 2 test cases: one that doesn't change anything, and another that does:

function changeBoolean(obj, propName) {
  if (Object(obj) !== obj) return obj; // A primitive value: nothing changes
  let changed = false;
  let pairs = Object.entries(obj).map(function ([key, value]) {
    let changedValue = key === propName && typeof value === "boolean" ? !value
                     : changeBoolean(value, propName);
    changed ||= changedValue !== value;
    return [key, changedValue];
  });
  return changed ? Object.fromEntries(pairs) : obj;
}

const config = {
  header:{logo: true, nav: false, user: false},
  searchResults:{listView: false, favorite: true, share: false, pagination: true, filters: true, sortBy: false},
  sharedLinks:{},
  learnerLinks:{},
  lukePreview:{toc: false, controls: false},
  lukeLaunch:{toc: false, controls: false},
  misc:{import: true}
};

// Test 1
let header = changeBoolean(config, 'header');
console.log("header:", header === config ? "no change" : header);

// Test 2
let toc = changeBoolean(config, 'toc');
console.log("toc:", toc === config ? "no change" : toc);

Comments

0

You can do:

const config = {
  header: { "logo": "true", "nav": "false", "user": "false" },
  searchResults: { "listView": "false", "favorite": "true", "share": "false", "pagination": "true", "filters": "true", "sortBy": "false" },
  sharedLinks: {},
  learnerLinks: {},
  lukePreview: { "toc": "false", "controls": "false" },
  lukeLaunch: { "toc": "false", "controls": "false" },
  misc: { "import": "true" }
}

const changeBoolean = o => Object.entries(o).reduce((a, [k, v]) => {
  a[k] = typeof v === 'object' ? changeBoolean(v)  : 'true'
  return a
}, {})
const newConfig = changeBoolean(config)

console.log(newConfig)

5 Comments

This code will not convert all false values to true and I asked how can we convert all nested object's "false" => "true" .
I did because of param propName but yes.. I am agree with you
Updated answer. Thank you
` a[k] = typeof v === 'object' ? changeBoolean(v, propName) ` Can you explain what propName is going on every iteration.
Added code refactor to remove parameter unused propName

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.