使用重复键(PHP或JS)解析嵌套的JSON对象

时间:2016-08-17 08:54:05

标签: javascript php arrays json regex

我正在构建一个基于我从API形成的数据的应用程序,该API形成为与json_encode()函数相似的响应。现在,我不知道(我知道这是可能的),API会不时返回重复的密钥。由于不是我的站点来修复重复键,我必须找到一个解决方案,如何将此响应解析为包含发送给我的所有数据的可用数组。 我想通过在其键中添加" x01"," x02"," x03" ...来重命名重复键。 到目前为止,我找到了一个可以提供帮助的解决方案(here),但它告诉我它只适用于更简单的数组 - 我处理嵌套数组。 所以,这是一个演示API响应:

{"boss":"mike",
    "employees":{
       "Josh":{
           "active":"1",
           "hours":"12",
           "name":"Josh"},
       "Josh":{
           "active":"1",
           "hours":"3",
           "name":"Josh"}
    }
}

所以,正如你所看到的,几乎整个" Josh"密钥重复("小时"子密钥除外)。即使它看起来像一个错误,这两个值对我来说都很重要。 所以,这是我想要获得的数组:

array (
  "boss" => "mike",
  "employees" = array (
    "x01Josh" = array ("active" => "1", "hours" => "12", "name" => "Josh")
    "x02Josh" = array ("active" => "1", "hours" => "3", "name" => "Josh")
  )
)

我有一个想法,即使一次只检查一个单词,检查它是否为字符串,双引号,逗号或任何花括号,并相应地构建一个函数。我认为它需要一个非常长且效率低下的代码(处理速度很慢)。

由于我是RegEx的新手,因为我也没有找到解决方案(我确信它存在,但我没有找到它),我请求你帮忙。

我打算用JavaScript / jQuery或PHP解析它(使用另一个JSON请求)。 提前谢谢。

更新我忘了提及 - 我之所以这样做是因为第二个键会覆盖第一个键(重复)。此外,我无法更改API(它不是我网站的API)。我已经要求他们对这些问题进行一些修改,但与此同时,我必须从我这边做。

3 个答案:

答案 0 :(得分:2)

使用String.replaceString.matchArray.filterArray.shift函数的 JS 解决方案:



var jsonData = '{"boss":"mike","employees":{"Josh":{"active":"1","hours":"12","name":"Josh"},"Josh":{"active":"1","hours":"3","name":"Josh"}}}',
    re = /\"(\w+?)(?=\":\{)/g, names = {}, dups;

jsonData.match(re).forEach(function(v){
    v = v.replace(/\"/, "");
    (!names[v])? names[v] = 1 : names[v]++;
});

dups = Object.keys(names).filter(function(k) { return names[k] > 1; }); // getting duplicated keys
dups.forEach(function (k) {
    var count = names[k], i;
    names[k] = [];

    for (i = 0; i < count; i++) {
        names[k].push("x0" + (i+1));
    }
});

jsonData = jsonData.replace(re, function (p1) { // replacing duplicate keys
    p1 = p1.substr(1);
    if (dups.indexOf(p1) !== -1) {
        return '"' + names[p1].shift() + p1;
    } else {
        return '"' + p1;
    }
});

console.log(JSON.parse(jsonData));
&#13;
&#13;
&#13;

答案 1 :(得分:1)

是否无法更改API?您发布的内容并非标准JSON。它返回一个包含重复键的映射,而不是一个对象数组。

如果你需要“与所得到的一起工作”。然后你可能需要研究构建自己的解析器。对嵌套结构使用正则表达式并不理想。

答案 2 :(得分:0)

试试这个

{"boss":"mike",
    "employees":[
       {   
           "active":"1",
           "hours":"12",
           "name":"Josh"},
       {
           "active":"1",
           "hours":"3",
           "name":"Josh"}
    ]
}