将递增数字添加到 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 对象字符串以使其唯一的主要内容,如果未能解决你的问题,请参考以下文章

用java实现字母与数字混合的唯一序号,且要递增

Unity:将着色器应用于对象以使其纹理弯曲

使用 javascript .replace 正则表达式将递增数字添加到字符串

如何修复我的代码以使其自动化?

如何修复无效的随机字符串以使其 JSON 有效

如何将 PowerShell cmdlet 或函数添加到我的计算机以使其始终可用?