我有一个这样的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只是一个对象,因为它中没有多个对象。如果它在不同情况下有多个对象,请告诉我我会改进这个答案。