我有以下 JSON -
{
"node1":[
{
"one":"foo",
"two":"foo",
"three":"foo",
"four":"foo"
},
{
"one":"bar",
"two":"bar",
"three":"bar",
"four":"bar"
},
{
"one":"foo",
"two":"foo",
"three":"foo",
"four":"foo"
}
],
"node2":[
{
"link":"baz",
"link2":"baz"
},
{
"link":"baz",
"link2":"baz"
},
{
"link":"qux",
"link2":"qux"
},
]
};
我有以下 javascript 将从 node1
部分删除重复项 -
function groupBy(items, propertyName) {
var result = [];
$.each(items, function (index, item) {
if ($.inArray(item[propertyName], result) == -1) {
result.push(item[propertyName]);
}
});
return result;
}
groupBy(catalog.node1, 'one');
然而,这并没有说明 node2
中的重复项。
我需要的结果 JSON 看起来像 -
{
"node1":[
{
"one":"foo",
"two":"foo",
"three":"foo",
"four":"foo"
},
{
"one":"bar",
"two":"bar",
"three":"bar",
"four":"bar"
}
],
"node2":[
{
"link":"baz",
"link2":"baz"
},
{
"link":"qux",
"link2":"qux"
},
]
};
但是我无法让它工作,groupBy
只返回一个删除了重复项的字符串,而不是重组的 JSON?
最佳答案
您可能应该寻找一些很好的 JavaScript set 实现并用它来表示您的节点对象。 set 数据结构将确保您只保留唯一的项目。
另一方面,您可以尝试编写自己的重复数据删除算法。这是一个例子
function dedup(data, equals){
if(data.length > 1){
return data.reduce(function(set, item){
var alreadyExist = set.some(function(unique){
return equals(unique, item);
});
if(!alreadyExist){
set.push(item)
}
return set;
},[]);
}
return [].concat(data);
}
不幸的是,这个算法的性能不太好,我认为有点像 O(n^2/2),因为我每次都检查唯一项的集合以验证给定项是否存在。如果您的结构真的那么小,这没什么大不了的。但无论如何,这是基于散列或基于树的算法可能更好的地方。
您还可以看到,我已经抽象掉了“相等”的定义。所以你可以在辅助功能中提供它。很可能使用 JSON.stringify 不是一个好主意,因为它需要时间来序列化一个对象。如果您可以编写自己的自定义算法来逐个键地进行比较,那可能会更好。
因此,equals 的天真(不推荐)实现可能有点像其他答案中提出的建议:
var equals = function(left, right){
return JSON.stringify(left) === JSON.stringify(right);
};
然后你可以简单地做:
var res = Object.keys(source).reduce(function(res, key){
res[key] = dedup(source[key], equals);
return res;
},{});
关于javascript - 删除重复项后重建 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25427838/