微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将2个大小不等的JSON对象与ID合并

如何解决将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"
   }
]

解决方法

您可以很容易地做到这一点,而不必太花哨。这是算法:

  1. 通过id将json1中的项目放入对象中,以便您快速查找它们。
  2. 对于json2中的每个项目:如果已经存在,请将其与现有项目合并。否则,将其添加到objectsById
  3. 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] 举报,一经查实,本站将立刻删除。