去重和合并JSON对象

4
我有以下JSON对象。我需要使用纯JavaScript移除重复项并合并内部对象。我该如何操作?
[{
    "id" : 1,
    "name" : "abc",
    "nodes" :[
        {
            "nodeId" : 20,
            "nodeName" : "test1"
        }
    ]
},
{
    "id" : 1,
    "name" : "abc",
    "nodes" :[
        {
            "nodeId" : 21,
            "nodeName" : "test2"
        }
    ]
}]

以下是我期望得到的输出对象。
[{
    "id" : 1,
    "name" : "abc",
    "nodes" :[
        {
            "nodeId" : 20,
            "nodeName" : "test1"
        },
        {
            "nodeId" : 21,
            "nodeName" : "test2"
        },
    ]
}]

Regards.

Shreerang


也许你可以在数组上使用循环,检查项目是否已经完成并按ID将其存储在另一个数组中,然后执行合并函数或搜索相关资料。 - Loenix
1
那么,你会如何处理像{id:1, name: "def"...}这样的输入呢?这是否匹配? - Adrian May
你要求的太多了。请给出你的代码尝试一下。 - Giannis Grivas
@AdrianMay 那种情况不会出现... - Shreerang
@Csdtesting 我正在准备一个代码片段,很快就会发布。 - Shreerang
我会使用underscore.js和deep_extend_javascript_objects_underscore_mixin.js。稍后我会尝试它。 - Giannis Grivas
2个回答

3

首先将JSON转换为Javascript数组,以便您可以轻松访问它:

var arr = JSON.parse(json);

然后创建一个用于存放结果的数组,遍历所有项并与您放入结果的项进行比较:

var result = [];

for (var i = 0; i < arr.length; i++) {
  var found = false;
  for (var j = 0; j < result.length; j++) {
    if (result[j].id == arr[i].id && result[j].name == arr[i].name) {
      found = true;
      result[j].nodes = result[j].nodes.concat(arr[i].nodes);
      break;
    }
  }
  if (!found) {
    result.push(arr[i]);
  }
}

如果JSON是您需要的最终结果,那么您可以从数组中创建JSON:

json = JSON.stringify(result);

整个循环可以使用Array.prototype.filter进行简化,特别是因为您的示例已经在使用concat - Sukima
@Sukima:是的,它可以,但是与“concat”相比,“filter”在许多浏览器中都不受支持。例如,IE 5.5支持“concat”,但您需要IE 9或更高版本才能获得对“filter”的支持。 - Guffa
你们还在支持IE 5??!!天哪,我向你们表示慰问。另外,我注意到继续教育“旧”的事物的趋势,而不是拥抱更近期的事物。此外,有一些poly-fills值得学习。以身作则。 - Sukima
2
@Sukima:别傻了。我不支持IE 5,但支持IE 8,除非有充分的理由不这样做。在这种情况下,没有不这样做的好理由。 - Guffa

0
如果您的字符串被称为input,那么这个代码是:
var inter = {};
for (var i in input) {
    if (!inter.hasOwnProperty(input[i].name)) {
        inter[input[i].name] = input[i].nodes;
        inter[input[i].name].name = input[i].name;
        inter[input[i].name].id = input[i].id;
    }
    else
        inter[input[i].name] = inter[input[i].name].concat(input[i].nodes)
}

结果为: {"abc":[{"nodeId":20,"nodeName":"test1"},{"nodeId":21,"nodeName":"test2"}]}

你可以看到我是如何使用一个中间对象,由匹配标准进行键控的。它是一个对象而不是一个数组,但你仍然可以迭代它。实际上,这种结构比你要求的数组更好。

顺便说一句,我在那里将一些文本命名的属性:"id"和"name"推入了一个数组中。它们不会出现在JSON.stringify中,但它们确实存在。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接