Reputation: 1621
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.
Upvotes: 1
Views: 42863
Reputation: 74187
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.
Upvotes: 1
Reputation: 22866
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 )
Upvotes: 2
Reputation: 663
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));
Upvotes: 2
Reputation: 1680
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);
Upvotes: 1