I have a JSON object that is being passed to me as a String, but the Object in its String form contains duplicate properties. I need to temporarily add incrementing numbers to the Properties in order to avoid the problem of duplicate JSON properties. Once I am done editing the Object, I will JSON.Stringify the object back to a String and remove the numbers.
Here is the String I am passed:
{
"View":{
"Image":{
"BackgroundImage":"Image.png",
"Position":[0,0],
"Width":320,
"Height":480
},
"Button":{
"BackgroundImage":"ButtonTop.png",
"Position":[61,83],
"Width":217,
"Height":58
},
"Button":{
"BackgroundImage":"ButtonBottom.png",
"Position":[61,214],
"Width":205,
"Height":73
},
"TextField":{
"BackgroundImage":"TextFieldLogin.png",
"Position":[102,336],
"Width":189,
"Height":31
},
"Label":{
"Position":[137,100],
"Width":72,
"Height":20,
"Text":"Hi Steve",
"FontSize":18,
"Color":[0,0,0,1]
},
"Label":{
"Position":[43,342],
"Width":54,
"Height":20,
"Text":"Login:",
"FontSize":18,
"Color":[0,0,0,1]
},
"Label":{
"Position":[115,234],
"Width":54,
"Height":20,
"Text":"Button",
"FontSize":18,
"Color":[0,0,0,1]
}
}
}
Here is how I would like the output to be:
{
"View_1":{
"Image_1":{
"BackgroundImage":"Image.png",
"Position":[0,0],
"Width":320,
"Height":480
},
"Button_1":{
"BackgroundImage":"ButtonTop.png",
"Position":[61,83],
"Width":217,
"Height":58
},
"Button_2":{
"BackgroundImage":"ButtonBottom.png",
"Position":[61,214],
"Width":205,
"Height":73
},
"TextField_1":{
"BackgroundImage":"TextFieldLogin.png",
"Position":[102,336],
"Width":189,
"Height":31
},
"Label_1":{
"Position":[137,100],
"Width":72,
"Height":20,
"Text":"Hi Steve",
"FontSize":18,
"Color":[0,0,0,1]
},
"Label_2":{
"Position":[43,342],
"Width":54,
"Height":20,
"Text":"Login:",
"FontSize":18,
"Color":[0,0,0,1]
},
"Label_3":{
"Position":[115,234],
"Width":54,
"Height":20,
"Text":"Button",
"FontSize":18,
"Color":[0,0,0,1]
}
}
}
How could I use javascript .replace() to add the numbering on demand, and then remove the numbering on demand?
I have a JSON object that is being passed to me as a String, but the Object in its String form contains duplicate properties. I need to temporarily add incrementing numbers to the Properties in order to avoid the problem of duplicate JSON properties. Once I am done editing the Object, I will JSON.Stringify the object back to a String and remove the numbers.
Here is the String I am passed:
{
"View":{
"Image":{
"BackgroundImage":"Image.png",
"Position":[0,0],
"Width":320,
"Height":480
},
"Button":{
"BackgroundImage":"ButtonTop.png",
"Position":[61,83],
"Width":217,
"Height":58
},
"Button":{
"BackgroundImage":"ButtonBottom.png",
"Position":[61,214],
"Width":205,
"Height":73
},
"TextField":{
"BackgroundImage":"TextFieldLogin.png",
"Position":[102,336],
"Width":189,
"Height":31
},
"Label":{
"Position":[137,100],
"Width":72,
"Height":20,
"Text":"Hi Steve",
"FontSize":18,
"Color":[0,0,0,1]
},
"Label":{
"Position":[43,342],
"Width":54,
"Height":20,
"Text":"Login:",
"FontSize":18,
"Color":[0,0,0,1]
},
"Label":{
"Position":[115,234],
"Width":54,
"Height":20,
"Text":"Button",
"FontSize":18,
"Color":[0,0,0,1]
}
}
}
Here is how I would like the output to be:
{
"View_1":{
"Image_1":{
"BackgroundImage":"Image.png",
"Position":[0,0],
"Width":320,
"Height":480
},
"Button_1":{
"BackgroundImage":"ButtonTop.png",
"Position":[61,83],
"Width":217,
"Height":58
},
"Button_2":{
"BackgroundImage":"ButtonBottom.png",
"Position":[61,214],
"Width":205,
"Height":73
},
"TextField_1":{
"BackgroundImage":"TextFieldLogin.png",
"Position":[102,336],
"Width":189,
"Height":31
},
"Label_1":{
"Position":[137,100],
"Width":72,
"Height":20,
"Text":"Hi Steve",
"FontSize":18,
"Color":[0,0,0,1]
},
"Label_2":{
"Position":[43,342],
"Width":54,
"Height":20,
"Text":"Login:",
"FontSize":18,
"Color":[0,0,0,1]
},
"Label_3":{
"Position":[115,234],
"Width":54,
"Height":20,
"Text":"Button",
"FontSize":18,
"Color":[0,0,0,1]
}
}
}
How could I use javascript .replace() to add the numbering on demand, and then remove the numbering on demand?
Share Improve this question edited Jan 13, 2013 at 1:22 Danilo Valente 11.4k8 gold badges54 silver badges70 bronze badges asked Jan 13, 2013 at 1:18 RobRob 11.5k10 gold badges40 silver badges56 bronze badges 5-
Are you able to modify the input string? Can't you just pass a collection of buttons, labels and image? like
{ 'view': { 'buttons':[{"Position":[123:423]}, {"Position":[25:335]}], 'images': [...] }}
– Pavel Nikolov Commented Jan 13, 2013 at 1:26 - negative. That has been discussed, but the ordering of the object is extremely important and must be delivered the way I specified above. Adding unique incrementing numbers is the best way that I can think of. It must also be predictable numbering so that I can target the desired property. Hope that makes sense. – Rob Commented Jan 13, 2013 at 1:33
- You probably know this, but you shouldn't be passed such a JSON string in the first place. It can't be parsed without losing information, which is why you will need to resort to ugly string manipulations. – bfavaretto Commented Jan 13, 2013 at 1:49
-
I've got to say, pretty much anything you do here is going to be a dirty hack. Why is it impossible to say something like
View : { children : [ { type : "Button", data : { /* position : ... */ } }, { type : "Image", data : { /* ... */ } } ] }
-- now everything can be in order, you have no duplicate names, and looping through the results is as simple as looping through, constructing an element/object ofnode.type
, and then setting all of thenode.data
properties (or passing them to the constructor fornode.type
), and then appending to the view in-order. If you own the JSON, it's easier. – LetterEh Commented Jan 13, 2013 at 2:23 - To wit, you're not even being passed valid JSON... So somebody/s dropped one or various balls. – LetterEh Commented Jan 13, 2013 at 2:29
2 Answers
Reset to default 2How's this? I agree with the other voices here remending that whoever is supplying this "JSON" be responsible for providing valid syntax, but barring that possibility this might get you started:
function formatJSON(input) {
return input.replace(/"([^"]+?)":{(.+)}/g, function(string, key, value) {
var dict = {};
return '"' + key + '":{' + value.replace(/"([^"]+?)":{(.+?)}/g, function(string, key, value) {
dict[key] = dict[key] == undefined ? 1 : ++dict[key];
return '"' + key + '_' + dict[key] + '":{' + formatJSON(value) + '}';
}) + '}';
});
};
JSFiddle: http://jsfiddle/WYkAT/
Note that this will fail to rename all keys on a more plex, deeper JSON string. It could be easily modified to be more recursive and less specific to your particular situation, but would likely result in some performance degradation. If you need a fully fledged solution, I'd look to modifying an existing JSON.parse polyfill. Here are two (JSON2 and JSON3):
- https://github./douglascrockford/JSON-js
- https://github./bestiejs/json3
You can use a RegEx expression and pass a function in to the replace()
method to generate the new name. Assuming json
contains the string;
var i = 0;
json.replace(/\"Button\"/g, function(match) { return '"Button_' + i++ + '"'; });
For more info see the part Find & replace with style… in this article Regular Expressions in JavaScript, part 2.
EDIT:
To get an array of the possible object names use this;
var names = json.match(/\"(\w*)\"\s?:\s?{/g)
You can then loop through the array to do all the replacements;
for(n = 0; n < names.length; n++) {
var i = 0;
var name = names[n].replace(/\s?:\s?{/g,'');
var re = new RegExp(name,'g');
json = json.replace(re, function(match) { return '"' + name.replace(/"/g,'') + '_' + i++ + '"'; });
}
You have to create the RegEx object this time to insert the variable.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745113066a4611961.html
评论列表(0条)