Reputation: 10466
This is an update to my previous question Find and update in nested json object
Sample Data
TestObj = {
"Categories": [{
"Products": [{
"id": "a01",
"name": "Pine",
"description": "Short description of pine."
},
{
"id": "a02",
"name": "Pine",
"description": "Short description of pine."
},
{
"id": "a03",
"name": "Poplar",
"description": "Short description of poplar."
}],
"id": "A",
"title": "Cheap",
"description": "Short description of category A."
},
{
"Product": [{
"id": "b01",
"name": "Maple",
"description": "Short description of maple."
},
{
"id": "b02",
"name": "Oak",
"description": "Short description of oak."
},
{
"id": "b03",
"name": "Bamboo",
"description": "Short description of bamboo."
}],
"id": "B",
"title": "Moderate",
"description": "Short description of category B."
}]
};
My Function
function getObjects(obj, key, val, newVal) {
var newValue = newVal;
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val, newValue));
} else if (i == key && obj[key] == val) {
obj[key] = newValue;
}
}
return obj;
}
called as
getObjects(TestObj, 'id', 'A', 'B');
It works fine if I'm going to update id; since id don't have duplicates. But if I'm updating name all data matching key value pair is updated. But how to constrain it into a particular key-pair value.
What shall i provide to the function to constrain the update scope and how to implement it. Please help me.
Note: The json that I will b manipulating will be dynamically generated so I can't have any hard coded value in the function
Upvotes: 3
Views: 4519
Reputation: 54524
I think you can somehow use a path to locate the value and then do the update. I got the idea from this post. (answered by @shesek)
var getPath = function (obj, path, newValue) {
var parts = path.split('.');
while (parts.length > 1 && (obj = obj[parts.shift()]));
obj[parts.shift()] = newValue;
return obj;
}
console.log(getPath(TestObj, 'Categories.0.Products.1.id', 'AAA'))
console.log(TestObj)
So you can pass in the path to the object, for example, if you want to update the id
of the following object to "AAA", you can pass in Categories.0.Products.1.id
{
"id": "a02",
"name": "Pine",
"description": "Short description of pine."
}
then, the object will become
{
"id": "AAA",
"name": "Pine",
"description": "Short description of pine."
}
Hope it can shed some light on!
Upvotes: 7