如何在键 id 的基础上合并 Json 对象?



我有一个这样的json。现在我想在 articleId 的基础上合并它。

[{
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [
{
"level1": "tt",
"description": "I am well"
}
],
"isAlert": false
},
{
"articleId": "46",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [
{
"level1": "ty",
"description": "I am fine"
}
],
"isAlert": false
},
{
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [
{
"level1": "tt",
"description": "I am beautiful"
}
],
"isAlert": false
}];

我们在这里看到文章 id 45 是两次,尽管描述字段不同。所以我想在一个数组中添加描述。合并后,我想得到这样的输出。

[{
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [
{
"level1": "tt",
"description":[
"I am well",
"I am beautiful"
]
}
],
"isAlert": false
},
{
"articleId": "46",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [
{
"level1": "ty",
"description": "I am fine"
}
],
"isAlert": false
}];

我正在尝试直接字符串解析。还有其他办法吗?顺便说一下,我正在使用节点js。有没有内置方法可以合并两个 json 对象?

使用映射按 articleId 分组,其中键是 articleId:

const source = [{"articleId":"45","isA":false,"flags":{"isDema":false,"isCont":true},"Proc":[{"level1":"tt","description":"I am well"}],"isAlert":false},{"articleId":"46","isA":false,"flags":{"isDema":false,"isCont":true},"Proc":[{"level1":"ty","description":"I am fine"}],"isAlert":false},{"articleId":"45","isA":false,"flags":{"isDema":false,"isCont":true},"Proc":[{"level1":"tt","description":"I am beautiful"}],"isAlert":false}];
const bucket = {}
source.map((item) => {
const merged = bucket[item.articleId];
if (!merged) {
item.Proc[0].description = [item.Proc[0].description]
bucket[item.articleId] = item;
return;
}
merged.Proc[0].description.push(item.Proc[0].description)
});
const out = [];
for (const key in bucket) {
const val = bucket[key];
if (val.Proc[0].description.length === 1) {
val.Proc[0].description = val.Proc[0].description.pop();
}
out.push(val);
}
console.log(JSON.stringify(out));

您可能必须编写自己的合并函数 - 如下所示:

var json = [{
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [{
"level1": "tt",
"description": "I am well"
}],
"isAlert": false
}, {
"articleId": "46",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [{
"level1": "ty",
"description": "I am fine"
}],
"isAlert": false
}, {
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [{
"level1": "tt",
"description": "I am beautiful"
}],
"isAlert": false
}];
const merged = json.reduce((acc,item)=>{
const found = acc.find(article=>article.articleId === item.articleId)
if (!found) {
acc.push(item)
} else if (found.Proc[0].description !== item.Proc[0].description) {
found.Proc[0].description = [found.Proc[0].description, item.Proc[0].description]
}
return acc;
}
, [])
console.log(merged)

但是,此示例假设您Proc中的项目永远不会超过 1 个,因此您必须处理这个问题。此外,如果合并时其他一些键不同,则必须编写如何处理这些键的逻辑。如果"isA"不同怎么办?最终会"isA": [false, true]吗?

最后,在合并后将数据类型从字符串更改为字符串数组是一种不好的做法。这将最终导致意大利面条代码

因此,您希望根据子对象 articleId 消除重复项。现在假设您已将初始数组存储在变量数据中。

这可能会解决您的问题。

let articleIdSet = new Set();
let newData = [];
data.map((item) => {
const { articleId }= item;
if(articleIdSet.has(articleId)) return; // return if the id is already present
else {
articleIdSet.add(articleId); // else add new id into the set
newData.push(item);          // and push the item into new array
}
})

现在,newData 将包含非重复项。

尝试以下操作:

var arr = [{
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [{
"level1": "tt",
"description": "I am well"
}],
"isAlert": false
},
{
"articleId": "46",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [{
"level1": "ty",
"description": "I am fine"
}],
"isAlert": false
},
{
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [{
"level1": "tt",
"description": "I am beautiful"
}],
"isAlert": false
}
];
var fianlArr = [];
arr.map(function(element) {
var filterArr = fianlArr.filter(finalArrEle => finalArrEle.articleId === element.articleId);
if (filterArr.length) {
var proc = [];
var desc = [];
var obj = {};
obj.level1 = element.Proc[0].level1;
desc.push(filterArr[0].Proc[0].description);
desc.push(element.Proc[0].description);
obj.description = desc;
proc.push(obj);
fianlArr[fianlArr.indexOf(filterArr[0])].Proc = proc;
} else {
fianlArr.push(element);
}
})
console.log("fianlArr", fianlArr)

上述结构JSON应始终具有相同的结构。

var before = [{
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [
{
"level1": "tt",
"description": "I am well"
}
],
"isAlert": false
},
{
"articleId": "46",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [
{
"level1": "ty",
"description": "I am fine"
}
],
"isAlert": false
},
{
"articleId": "45",
"isA": false,
"flags": {
"isDema": false,
"isCont": true,
},
"Proc": [
{
"level1": "tt",
"description": "I am beautiful"
}
],
"isAlert": false
}];
var articles = [];
let results = [];
before.forEach((item) => {
if (!articles.includes(item.articleId)) {
articles.push(item.articleId);
var obj = {
"articleId": item.articleId,
"isA": item.isA,
"flags": {
"isDema": item.flags.isDema,
"isCont": item.flags.isCont,
},
"Proc": [
{
"level1": item.Proc.level1,
"description": [item.Proc[0].description]
}
],
"isAlert": false
}
results.push(obj);
}
else {
var index = articles.indexOf(item.articleId);
results[index].Proc[0].description.push(item.Proc[0].description);
}
})
console.log(JSON.stringify(results));

上述解决方案是您的解决方案的答案。但我宁愿你让Proc只是一个对象,因为它中没有多个对象。如果它在不同情况下有多个对象,请告诉我我会改进这个答案。

最新更新