4

I've searched for a long time, but cannot find any solution for my problem... I got a random nested json object like this:

var obj = { a: 1, b: 2, c: { a: 1, b: 2, c: {a: 'hello', b: 'HowAreYou?'} } };
someValue = 'hello';
newValue = 'bye';

Now I'm going to search for 'someValue'. If 'obj' contains this value the alert will be triggered. Here's my example:

function wannaChangeValue(obj) {
    var itemKey;
    if (obj instanceof Object) {
        for (itemKey in obj) {
            if (obj.hasOwnProperty(itemKey)) {
                wannaChangeValue(obj[itemKey]);
            }
        }
    } else {
        alert(obj);
        if (obj == someValue) {
            alert('got it! now change...')
            //change someValue to newValue 
        }
    }
    return obj
}

wannaChangeValue(obj)

This works really fine, but how can I change 'someValue' to 'newValue' and return the whole json-file again? I've seen many examples how to handle this, but I need a solution for ANY kind of nested json object WITHOUT knowing the path for changing this value. Maybe this is a completely wrong approach... Thanks in advance!

1

6 Answers 6

4

You could use a recursice approach for any found object, call the function again.

function update(object, search, replace) {
    Object.keys(object).forEach(function (k) {
        if (object[k] && typeof object[k] === 'object') {
            return update(object[k], search, replace)
        }
        if (object[k] === search) {
            object[k] = replace;
        }
    });
    
}

var object = { a: 1, b: 2, c: { a: 1, b: 2, c: {a: 'hello', b: 'HowAreYou?'} } };
    
update(object, 'hello', 'bye');

console.log(object)
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

8 Comments

What is the purpose of this: object[k] &&?
it prevents null values to gets iterated by keys.
I think, my comment on @Alexandru-Ionut Mihai's answer would not only solve your usecase, but will also optimize as there should be no need to traverse node tree that does not have the key
hm. yes and no. yes, because it shortens the iteration and no, because of the overhead for every nested object.
@HassanImam, it prevents the next if clause to be evaluated.
|
2

You can create function using for...in loop and if current value match oldValue change that value.

var obj = { a: 1, b: 2, c: { a: '1', b: 2, c: {a: 'hello', b: 'HowAreYou?'} } };
var someValue = 'hello';
var newValue = 'bye';

function changeVal(data, oldV, newV) {
  for(var i in data) {
    if(typeof data[i] == 'object') changeVal(data[i], oldV, newV);
    if(data[i] == oldV) data[i] = newV
  }
  return data
}

console.log(changeVal(obj, someValue, newValue))

Comments

0

You can define a function which search recursively the value through your object and then replace this value.

function replaceObj (obj, valueForSearch,valueForReplace) {
    for (var key in obj) {
        var value = obj[key];
        if (typeof value === 'object') {
            replaceObj(value, valueForSearch,valueForReplace);
        }
        if (value === valueForSearch) {
            obj[key]=valueForReplace;
        }
    }
}
let obj = { a: 1, b: 2, c: { a: 1, b: 2, c: {a: 'hello', b: 'HowAreYou?'} } };
let someValue = 'hello';
let newValue = 'bye';
replaceObj(obj,someValue,newValue);
console.log(obj);

1 Comment

You can even optimize it as typeof value === 'object' && JSON.stringify(value).indexOf(query)>=0
0

This is a quick solution:

function wannaChangeValue(obj) {
    var itemKey;
    if (obj instanceof Object) {
        for (itemKey in obj) {
            if (obj.hasOwnProperty(itemKey)) {
                obj[itemKey] = wannaChangeValue(obj[itemKey]);
            }
        }
    } else {
        alert(obj);
        if (obj == someValue) {
            alert('got it! now change...')
            //change someValue to newValue
            obj = someValue;
        }
    }
    return obj
}

wannaChangeValue(obj)

Obviously this will mutate the value on the object itself, so if you want an entirely new object you will have to do something different.

Comments

0

You could use recursive call for your object.

Demo

var object = { a: 1, b: 2, c: { a: '1', b: 2, c: {a: 'hello', b: 'HowAreYou?'} } },
  someValue = 'hello',
  newValue = 'bye';

function wannaChangeValue(obj) {
  var itemKey;
  if (obj instanceof Object) {
    for (itemKey in obj) {
      if (obj.hasOwnProperty(itemKey)) {
        if (!(obj[itemKey] instanceof Object) && obj[itemKey] == someValue) {
          //alert(someValue + ' got it! now change...')
          //change someValue to newValue
          obj[itemKey] = newValue;
          break;
        } else {
          wannaChangeValue(obj[itemKey]);
        }
      }
    }
  }
}
wannaChangeValue(object);
console.log(object)
.as-console-wrapper {max-height: 100% !important;top: 0;}

1 Comment

Dude you have to just need to some change your code like below code it will work for you. This is a comment line, which would be flagged as Too Chatty. An answer should have an Explanation.
0

Here is a solution using object-scan

// const objectScan = require('object-scan');

const obj = { a: 1, b: 2, c: { a: 1, b: 2, c: { a: 'hello', b: 'HowAreYou?' } } };

const replace = (input, oldValue, newValue) => objectScan(['**'], {
  abort: true,
  rtn: 'bool',
  filterFn: ({ value, parent, property }) => {
    if (value === oldValue) {
      parent[property] = newValue;
      return true;
    }
    return false;
  }
})(input);

console.log(replace(obj, 'hello', 'bye')); // returns true iff replace happened
// => true
console.log(obj);
// => { a: 1, b: 2, c: { a: 1, b: 2, c: { a: 'bye', b: 'HowAreYou?' } } }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Disclaimer: I'm the author of object-scan

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.