js两个数组对象通过关系键值对应,合并为新的对象

新手上路,请多包涵

题目描述

通过以下关系

 num -> value
 amount -> total 

把数组对象oriData与objData根据type合并输出想到的结果

oriData = [  
  {num: 1, amount: 1, type: '1'},  
  {num: 2, amount: 2, type: '2'},  
  {num: 3, amount: 3, type: '3'}  
]
objData = [  
  {value: null, total: null, type: '1'},  
  {value: null, total: null, type: '2'},  
  {value: null, total: null, type: '3'}  
]

结果为

objData = [  
  {value: 1, total: 1, type: '1'},  
  {value: 2, total: 2, type: '2'},  
  {value: 3, total: 3, type: '3'}  
]

题目来源及自己的思路

我尝试了使用forEach遍历oriDataobjData,并把他们assign起来,这样确实可以把两个数组对象合并,但是得到的结果就是objData中出现了新的属性值numamount。数据有冗余,而且显得很low。

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)

let oriData = [  
   {num: 1, amount: 1, type: '1'},  
  {num: 2, amount: 2, type: '2'},  
  {num: 3, amount: 3, type: '3'}  
]  
let objData = [  
  {value: null, total: null, type: '1'},  
  {value: null, total: null, type: '2'},  
  {value: null, total: null, type: '3'}  
]  
  
objData.forEach(item=> {  
    oriData.forEach(oItem => {  
        if (item.type === oItem.type) {  
            item.value = oItem.num; 
            item.total = oItem.amount;  
            Object.assign(item, oItem)  
        }  
    })  
})

你期待的结果是什么?实际看到的错误信息又是什么?

有没有什么高大上的方法,可以做到通用性呢

阅读 5.3k
3 个回答

Object.assign()会把源对象的所有属性复制到目标对象上,数组是引用类型,当改变其中某个值时,整个对象会随之改变。所以你

Object.assign(item, oItem)  

这一句是多余的,去掉就可以了

你上面是2层循环,时间复杂度是O(m x n),m、n分别为oriData、objData的长度。
如果你先建立映射关系,就可以把时间复杂度缩小到O(m + n).

实现如下:

// 建立映射O(m)
let map = oriData.reduce((r, o) => (r[o.type] = o, r), {}) 

// 循环赋值 O(n)
objData.forEach(o => {
  o.value = map[o.type].num
  o.total = map[o.type].amount
})

objData.some(item => {
let index = oriData.findIndex(data => data.type === item.type)
if(index >= 0) {

item.value = oriData[index].num
item.total = oriData[index].amount

}
})
首先想到的是这个= =

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏