Reputation: 245
I have some json : data
.
I have a string build that looks like this:
sections.1.subsections.0.items.0.citation.paragraph
What I need to do is manipulate that string to be able to access that value in data
. So turn it into something usable:
data['sections'][1]['subsections'][0]['items'][0]['citation']['paragraph']
And then use it to change that value in data. So:
data['sections'][1]['subsections'][0]['items'][0]['citation']['paragraph'] = 'new value'
I can split the original string on the .
and I think that gets me somewhere but I'm not at all sure how to then re-use the parts to allow me access to that value in data
.
Thanks!
Upvotes: 0
Views: 79
Reputation: 12508
I'm still not quite sure why you're handling the JSON in this fashion but if it has to be done this way, then you'll need to use recursion to access the data. Assuming I mapped your object correctly, the example below should provide you with a method for doing this:
var data = {
sections: [
{
subsections: []
},
{
subsections: [
{
items: [
{
citation: {
paragraph: "Citation by Warlock"
}
}
]
}
]
}
]
};
var string = "sections.1.subsections.0.items.0.citation.paragraph",
parts = string.split('.');
function getValue(tree, index) {
if(index < (parts.length - 1)) {
return getValue(tree[parts[index]], index + 1);
} else {
return tree[parts[index]];
}
}
function setValue(tree, index, newValue) {
if(index < (parts.length - 1)) {
setValue(tree[parts[index]], index + 1, newValue);
} else {
tree[parts[index]] = newValue;
}
}
alert(getValue(data, 0));
setValue(data, 0, "New Citation By Warlock");
alert(getValue(data, 0));
The idea is that the getValue(...);
function steps one layer deep into your JSON and then recursively calls itself. This allows the data to be accessed one step at a time until the last part is retrieved. The value is then returned via the recursion in all the previous function calls.
The same idea is true for setting the value. The setValue(...);
function steps into the JSON one layer at a time passing the new value to set until it's reached the last nested layer. The value is then set for the specified property.
EDIT:
A better implementation would be to pass the parts
array into the getValue(...);
and setValue(...);
function to eliminate external dependencies. Then, within the function shift the array's data values to step through the nested layers. This eliminates the need for index tracking based on the original array's values:
var data = {
sections: [
{
subsections: []
},
{
subsections: [
{
items: [
{
citation: {
paragraph: "Citation by Warlock"
}
}
]
}
]
}
]
};
var string = "sections.1.subsections.0.items.0.citation.paragraph",
parts = string.split('.');
function getValue(temp, tree) {
if(temp.length > 1) {
tree = tree[temp[0]];
temp.shift();
return getValue(temp, tree);
} else {
return tree[temp[0]];
}
}
function setValue(temp, tree, newValue) {
if(temp.length > 1) {
tree = tree[temp[0]];
temp.shift();
setValue(temp, tree, newValue);
} else {
tree[temp[0]] = newValue;
}
}
alert(getValue(parts, data));
setValue(parts, data, "New Citation By Warlock");
alert(getValue(parts, data));
Upvotes: 3