将递增数字添加到 JSON 对象字符串以使其唯一
Posted
技术标签:
【中文标题】将递增数字添加到 JSON 对象字符串以使其唯一【英文标题】:Add incrementing number to JSON object String to make them unique 【发布时间】:2012-12-27 07:22:09 【问题描述】:我有一个 JSON 对象作为字符串传递给我,但其字符串形式的对象包含重复的属性。我需要临时向属性添加递增数字以避免重复 JSON 属性的问题。完成对象的编辑后,我会将对象 JSON.Stringify 回字符串并删除数字。
这是我传递的字符串:
"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]
这是我希望的输出:
"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]
如何使用 javascript .replace() 按需添加编号,然后按需删除编号?
【问题讨论】:
你能修改输入字符串吗?你不能只传递按钮、标签和图像的集合吗?喜欢 'view': 'buttons':["Position":[123:423], "Position":[25:335]], 'images': [...]
否定的。这已经讨论过了,但是对象的顺序非常重要,并且必须按照我上面指定的方式交付。添加唯一的递增数字是我能想到的最好方法。它还必须是可预测的编号,以便我可以定位所需的属性。希望这是有道理的。
您可能知道这一点,但一开始就不应该向您传递这样的 JSON 字符串。它不能在不丢失信息的情况下被解析,这就是为什么你需要使用丑陋的字符串操作。
我不得不说,你在这里所做的几乎所有事情都是肮脏的。为什么不能说View : children : [ type : "Button", data : /* position : ... */ , type : "Image", data : /* ... */ ]
之类的东西——现在一切都井然有序,你没有重复的名字,循环遍历结果就像循环遍历一样简单,构造一个node.type
的元素/对象,然后设置所有node.data
属性(或将它们传递给node.type
的构造函数),然后按顺序附加到视图。如果您拥有 JSON,那就更容易了。
也就是说,你甚至没有被传递有效的 JSON ......所以有人/s 丢了一个或多个球。
【参考方案1】:
这是怎么回事?我同意这里的其他声音,建议提供这个“JSON”的人负责提供有效的语法,但除非有这种可能性,否则这可能会让你开始:
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.net/WYkAT/
请注意,这将无法重命名更复杂、更深的 JSON 字符串上的所有键。它可以很容易地修改为更具递归性并且对您的特定情况不太具体,但可能会导致一些性能下降。如果您需要一个成熟的解决方案,我会考虑修改现有的 JSON.parse polyfill。这里有两个(JSON2 和 JSON3):
-
https://github.com/douglascrockford/JSON-js
https://github.com/bestiejs/json3
【讨论】:
这正是我想要的,但我如何将相同的数字添加到顶层“视图”:? 好吧,在这种情况下(以及在所有格式正确的 JSON 的情况下)只有一个***对象。所以,在第二次“回归”之后,就让它return '"' + key + '"_1:'
...
这行得通。我不得不使用另一个正则表达式来删除空格和换行符,但它起作用了。谢谢【参考方案2】:
您可以使用 RegEx 表达式并将函数传递给 replace()
方法以生成新名称。假设json
包含字符串;
var i = 0;
json.replace(/\"Button\"/g, function(match) return '"Button_' + i++ + '"'; );
有关详细信息,请参阅本文Regular Expressions in JavaScript, part 2 中的查找和替换样式…部分。
编辑:
要获取可能的对象名称的数组,请使用 this;
var names = json.match(/\"(\w*)\"\s?:\s?/g)
然后你可以循环遍历数组来做所有的替换;
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++ + '"'; );
这次你必须创建 RegEx 对象才能插入变量。
【讨论】:
这可行,但我相信它需要我为每个可能的属性都有一个 .replace() ,这只是一个示例。我们有几十种。是否可以与您的类似,但只需在“”中的:
之前立即将数字添加到单词中?
@Rob 您需要一些方法来提取对象名称而不是属性值,即替换“按钮”而不是“位置”。您可以使用数组来存储要替换的可能名称,然后循环遍历它们。您甚至可以使用 RegEx 提取匹配的名称,请参阅我的编辑。
@Rob,抱歉,RegExp 这个名字有多余的引号,并且 json 字符串在每个循环中都被覆盖,而不是保留更改。我现在已经解决了。希望这能满足您的要求。以上是关于将递增数字添加到 JSON 对象字符串以使其唯一的主要内容,如果未能解决你的问题,请参考以下文章