提问人:raj.rajpurohit6 提问时间:10/28/2020 最后编辑:Eleraj.rajpurohit6 更新时间:2/25/2022 访问量:234
将源 JSON 字符串合并到具有相似键但 javascript 结构不同的目标
Merge source JSON string to target with similar keys but different structure in javascript
问:
我有两个JSON字符串,如下所示:
source = [
{
"name": "test1",
"values": ["User Support"],
"enabled": false
},
{
"name": "test2",
"values": ["M"],
"enabled": true
},
{
"name": "test3",
"values": ["CA"],
"enabled": false
}
]
target = [{
"name": "test1",
"values": [{
"value": "User Support",
"selected": false
},
{
"value": "Engineering",
"selected": false
},
{
"value": "Implementation",
"selected": false
}
],
"enabled": false
},
{
"name": "test2",
"values": [{
"value": "M",
"selected": false
},
{
"value": "F",
"selected": false
}
],
"notEnabled": false
},
{
"name": "test3",
"values": [{
"value": "CA",
"selected": false
},
{
"value": "EN",
"selected": false
}
],
"enabled": false
}
]
我想将这两个JSON字符串合并到目标中,结果应如下所示:
target = [{
"name": "test1",
"values": [{
"value": "User Support",
"selected": true
},
{
"value": "Engineering",
"selected": false
},
{
"value": "Implementation",
"selected": false
}
],
"enabled": false
},
{
"name": "test2",
"values": [{
"value": "M",
"selected": true
},
{
"value": "F",
"selected": false
}
],
"enabled": true
},
{
"name": "test3",
"values": [{
"value": "CA",
"selected": true
},
{
"value": "EN",
"selected": false
}
],
"enabled": false
}
]
所以,我试图做的是在目标字符串中搜索名称为 test1、test2......然后,如果在源 JSON 字符串中找到该值,则将所选字段设置为 true。enabled 字段也是如此。
我想到的第一件事是为每个循环使用嵌套并检查键。 在 Javascript 中还有其他更好的方法可以做到这一点吗?
请注意,目标字符串中可能存在其他键,但除非它们存在于源字符串中,否则我们不会理会它们。
答:
0赞
A1exandr Belan
10/28/2021
#1
如果你不介意 lodash:
const _ = require('lodash');
const sourceJSON = '[{"name":"test1","values":["User Support"],"enabled":false},{"name":"test2","values":["M"],"enabled":true},{"name":"test3","values":["CA"],"enabled":false}]';
const targetJSON = '[{"name":"test1","values":[{"value":"User Support","selected":false}, {"value":"Engineering","selected":false},{"value":"Implementation","selected":false}],"enabled":false},{"name":"test2","values":[{"value":"M","selected":false}, {"value":"F","selected":false} ],"notEnabled":false},{ "name":"test3","values": [{"value":"CA","selected":false},{"value":"EN","selected":false}],"enabled":false}]';
const source = JSON.parse(sourceJSON);
const target = JSON.parse(targetJSON);
const sourceNormalized = source.map((obj) => (
{ ...obj, values: [{value: obj.values[0], selected: true}] }
));
const merged = _.defaultsDeep(sourceNormalized, target);
console.dir(merged, {depth: null});
// [ { name: 'test1',
// values: [
// { value: 'User Support', selected: true },
// { value: 'Engineering', selected: false },
// { value: 'Implementation', selected: false }
// ],
// enabled: false
// },
// { name: 'test2',
// values: [
// { value: 'M', selected: true },
// { value: 'F', selected: false }
// ],
// enabled: true,
// notEnabled: false
// },
// { name: 'test3',
// values: [
// { value: 'CA', selected: true },
// { value: 'EN', selected: false }
// ],
// enabled: false} ]
result = JSON.stringify(merged);
0赞
jsN00b
1/1/2022
#2
之前使用 lodash 的答案是一个非常好的方法。如果你遇到像我这样的情况(被困在一个代码库上,其中包,包括 lodash,很难获得批准使用),这里有一个使用 Vanilla-javascript (+ JSON.stringify) 的方法:
const delta = [{
"name": "test1",
"values": ["User Support"],
"enabled": false
},
{
"name": "test2",
"values": ["M"],
"enabled": true
},
{
"name": "test3",
"values": ["CA"],
"enabled": false
}
];
const orig = [{
"name": "test1",
"values": [{
"value": "User Support",
"selected": false
},
{
"value": "Engineering",
"selected": false
},
{
"value": "Implementation",
"selected": false
}
],
"enabled": false
},
{
"name": "test2",
"values": [{
"value": "M",
"selected": false
},
{
"value": "F",
"selected": false
}
],
"notEnabled": false
},
{
"name": "test3",
"values": [{
"value": "CA",
"selected": false
},
{
"value": "EN",
"selected": false
}
],
"enabled": false
}
];
const getTargetJSON = (delta, orig, debug = true) => { // method signature
const deltaMapper = delta.reduce((f, i) => ({
...f,
[i.name]: {
values: [...i.values],
enabled: i.enabled
}
}), {});
const target = orig.map(itm => ({
...itm,
values: itm.values.map(it2 => ({
...it2,
selected: deltaMapper[itm.name].values.includes(it2.value) || false
})),
enabled: deltaMapper[itm.name].enabled || false
}));
debug && console.log('Merged Target:\n', target);
return JSON.stringify(target);
};
getTargetJSON(delta, orig); // method call
方法/解释:
我们将问题分解为更小的问题。
- 首先,使用源(在 代码片段)
- 接下来,遍历目标(名为“orig”)并利用 map(在上面创建)以确定值是否被“选中”,并且 item 为“已启用”。
评论
values
values
Map
for(let i = 0; i < source.length; ++i) for(let j = 0; j < target.length; ++j){ if(_.isEqual(source[i]["name"], target[j]["name"])){ target[j]["enabled"] = source[i]["enabled"]; for(let k = 0; k < target[j]["values"].length; ++k) for(let l = 0; l < source[i]["values"].length; ++l) if(_.isEqual(target[j]["values"][k]["value"],source[i]["values"][l])) target[j]["values"][k]["selected"] = true; } }