How to find and replace value in JSON?

26,802

Solution 1

Do something like this. Convert to string replace using regex (add key to regex as well) and then convert back.


var data = {
  "responses": {
    "firstKey": {
      "items": {
        "name": "test name one"
      }
    },
    "anotherKey": {
      "items": {
        "name": "test name two"
      }
    },
    "oneMoreKey": {
      "items": {
        "name": "John"
      }
    }
  }
};

var originalMsg = JSON.stringify(data);
console.log(data)
console.log(originalMsg)
var updatedMsg = originalMsg.replace(/test name [a-z]*/g, "N/A");
console.log(updatedMsg)
var newObj = JSON.parse(updatedMsg); 
console.log(newObj);

Solution 2

It can also be done during parsing :

var json = `{
  "responses": {
    "firstKey": {
      "items": {
        "name": "test name one"
      }
    },
    "anotherKey": {
      "items": {
        "name": "test name two"
      }
    },
    "oneMoreKey": {
      "items": {
        "name": "John"
      }
    }
  }
}`

var obj = JSON.parse(json, (k, v) => k == 'name' && /^test name/.test(v) ? 'N/A' : v)

console.log( obj )

Solution 3

A javascript object is for all intents and purposes a tree — though it can be, and may well be, a directed graph — that quite possibly may be cyclic meaning a node in the graph points back to own of its own parents. Following a cycle can result in never-ending recursion or loop.

You want to use something like traverse to do what you're talking about. It takes care of all the stuff that makes traversing a graph hassle — dealing with cycles in the graph and the like.

const traverse = require('traverse');
. . .
var scrubbed = traverse(obj).map( function(value) {
  const isTestName = this.key === 'name'
    && value
    && /^test name/i.test(value)
    ;

  if (isTestName) {
    this.update('N/A');
  }

});

NOTE: The callback function given to travese can't be an arrow function (() => {...} as that function's this context is the traverse context for the current node being inspected.

That traverse context also gives you access to the entire path from the root down to the current node, along with an upward link to the parent node's traverse context.

Solution 4

The javascript object should be iterated and then each value of name can be checked and replaced. There are checks such as hasOwnProperty() that can be used to make sure you are not iterating objects that are missing "items" or "name" for better error handling.

var data = {
  "responses": {
    "firstKey": {
      "items": {
        "name": "test name one"
      }
    },
    "anotherKey": {
      "items": {
        "name": "test name two"
      }
    },
    "oneMoreKey": {
      "items": {
        "name": "John"
      }
    }
  }
};

Given the JSON above you can use a simple for statement to iterate and then check each name for some value and replace.

for(var key in data.responses){
    if ((data.responses[key].items.name).match(/test name/)){
       data.responses[key].items.name = "N/A";
    } 
}

To check your replacements you can log data to the console.

console.log(JSON.stringify(data));
Share:
26,802
John Glabb
Author by

John Glabb

Updated on June 28, 2020

Comments

  • John Glabb
    John Glabb almost 4 years

    I have an object like this:

    {
      "responses": {
        "firstKey": {
          "items": {
            "name": "test name one"
          }
        },
        "anotherKey": {
          "items": {
            "name": "test name two"
          }
        },
        "oneMoreKey": {
          "items": {
            "name": "John"
          }
        }
      }
    }
    

    I need to find all 'name' keys and replace its value only if it starts with 'test name' then return new JSON object:

    {
      "responses": {
        "firstKey": {
          "items": {
            "name": "N/A"
          }
        },
        "anotherKey": {
          "items": {
            "name": "N/A"
          }
        },
        "oneMoreKey": {
          "items": {
            "name": "John"
          }
        }
      }
    }
    

    The problem is that the keys are not consistent through the objects, i.e. 'firstKey', 'secondKey'... I tried ForEach but it seems to be too cumbersome... So I need either lodash or vanila JavaScript to replace the values.

    • Pointy
      Pointy almost 5 years
      You have a JavaScript object. There is really no such thing as a "JSON object".
    • Dave Newton
      Dave Newton almost 5 years
      forEach was... too cumbersome? I mean, you just need the keys and then iterate an array. It's not clear to me what the specific problem you're having is--and if you know you want to use lodash then why not just use it? Are you basically asking someone to write the code?
    • sanjsanj
      sanjsanj almost 5 years
      Could you post what you've tried and what problem you have with it please?
    • Michael Paccione
      Michael Paccione almost 5 years
      I agree with Dave...code handout
    • John Glabb
      John Glabb almost 5 years
      just give me an idea how can I search with lodash the value that starts with 'xxxxx. I'll write the code myself
  • John Glabb
    John Glabb almost 5 years
    Thank you @PraveenB. I saw that solution to stringify it first.. Just thought it can be done through .find, .findindex..
  • Daniel Gale
    Daniel Gale almost 5 years
    Sure it can be done this way in this small example, but should it? You are not actually evaluating the values of SomeKey.items.name and updating. This updates values or keys anywhere in the JSON
  • PraveenB
    PraveenB almost 5 years
    @DanielGale I have not provided complete solution as i mentioned in the comment but its just adding key also to the regex. Do not want to provide the complete solution so that the person who has asked knows how it works