如何解决将2个大小不等的JSON对象与ID合并
问题
我想使用ID将以下两个JSON组合在一起,并获得预期的结果,如下所述。我尝试了一些可用的解决方案,但没有一个适合我的用例。任何建议都会很棒!
尝试做: How to merge two json object values by id with plain Javascript (ES6)
var json1 = [
{
"id":"A123","cost":"5020.67","fruitName":"grapes"
},{
"id":"A456","cost":"341.30","fruitName":"apple"
},{
"id":"A789","cost":"3423.04","fruitName":"banana"
}
];
var json2 = [
{
"id":"A123","quantity":"7"
},"quantity":"10"
},{
"id":"ABCD","quantity":"22"
}
];
以下是我尝试的代码:
var finalResult = [...[json1,json2].reduce((m,a) => (a.forEach(o => m.has(o.id) && Object.assign(m.get(o.id),o) || m.set(o.id,o)),m),new Map).values()];
预期结果:
[
{
"id":"A123","fruitName":"grapes","fruitName":"banana","quantity":"22"
}
]
解决方法
您可以很容易地做到这一点,而不必太花哨。这是算法:
- 通过id将json1中的项目放入对象中,以便您快速查找它们。
- 对于json2中的每个项目:如果已经存在,请将其与现有项目合并。否则,将其添加到
objectsById
。 - 将
objectsById
转换回数组。我使用过Object.values
,但是您也可以通过循环轻松地做到这一点。
var json1 = [
{
"id":"A123","cost":"5020.67","fruitName":"grapes"
},{
"id":"A456","cost":"341.30","fruitName":"apple"
},{
"id":"A789","cost":"3423.04","fruitName":"banana"
}
];
var json2 = [
{
"id":"A123","quantity":"7"
},"quantity":"10"
}
];
const objectsById = {};
// Store json1 objects by id.
for (const obj1 of json1) {
objectsById[obj1.id] = obj1;
}
for (const obj2 of json2) {
const id = obj2.id;
if (objectsById[id]) {
// Object already exists,need to merge.
// Using lodash's merge because it works for deep properties,unlike object.assign.
objectsById[id] = _.merge(objectsById[id],obj2)
} else {
// Object doesn't exist in merged,add it.
objectsById[id] = obj2;
}
}
// All objects have been merged or added. Convert our map to an array.
const mergedArray = Object.values(objectsById);
,
我认为在reduce函数中跳过了一些步骤。而且读起来有点困难,因为许多步骤被组合在一起。
函数不能解释的一个关键问题是,当您将2个数字字符串加在一起时,它会合并这些字符串。
const stringTotal = "5020.67" + "3423.04" // result will be "5020.673423.04"
以下功能将为您提供所需的结果。
// calculating the total cost
// default values handles cases where there is no obj in array 2 with the same id as the obj compared in array1
const calcualteStringTotal = (value1 = 0,value2 = 0) => {
const total = parseFloat(value1) + parseFloat(value2)
return `${total}`
}
const calculateTotalById = (array1,array2) => {
const result = []
// looping through initial array
array1.forEach(outterJSON => {
// placeholder json obj - helpful in case we have multiple json in array2 with the same id
let combinedJSON = outterJSON;
// looping through second array
array2.forEach(innerJSON => {
// checking ids
if(innerJSON.id === combinedJSON.id) {
// calls our helper function to calculate cost
const updatedCost = calcualteStringTotal(innerJSON.cost,outterJSON.cost)
// updating other properties
combinedJSON = {
...outterJSON,...innerJSON,cost: updatedCost
}
}
})
result.push(combinedJSON)
})
return result
}
const combinedResult = calculateTotalById(json1,json2)
,
我认为通过使用reduce可以使其工作。
var finalResult = [...[json1,json2].reduce((m,a) => (a.forEach(o => m.has(o.id) && Object.assign(m.get(o.id),o) || m.set(o.id,o)),m),new Map).values()];
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。