通过ID比较两个对象并创建一个新对象

时间:2018-08-08 08:01:59

标签: javascript underscore.js lodash

所以我有两个具有这种结构的对象:

const obj1 = { data:
   [ { 
       id: 1,
       name: 'Linda'
     },
     { 
       id: 2,
       name: 'Mark'
     }
   ];

const obj2 =  [
   { 
       id: 1,
       salary: "2000, 60 USD"
   },
undefined
 ],
 [ 
   { 
       id: 2,
       salary: "4000, 50 USD"
   },
 undefined
]

我需要基于id创建一个函数,将这两个函数合并为一个对象。

所以最终结果将是:

const finalObj = { data:
       [ { 
           id: 1,
           name: 'Linda',
           salary: "2000, 60 USD"
         },
         { 
           id: 2,
           name: 'Mark',
           salary: "4000, 50 USD"
         }
       ];

我检查了其他问题,但找不到任何有帮助的内容。可以用lodash afaik完成,但不知道如何。

我尝试了以下方法:

finalObj = obj1.data.map(x => {
                    return {
                        ...x,
                        ...obj2
                    }

但是它映射不正确。

谢谢。

编辑:更新了obj2响应。

4 个答案:

答案 0 :(得分:1)

您可以array#concat既使用数组,然后使用array#reduce和具有ID的对象查找合并对象。然后返回该对象的所有值。

const obj1 = { data: [{ id: 1, name: 'Linda' }, { id: 2, name: 'Mark' }]},
      obj2 = { data: [{ id: 1, salary: "2000, 60 USD"}, { id: 2, salary: "4000, 50 USD"}]},
      result = Object.values(obj1.data.concat(obj2.data).reduce((r,o) => {
        r[o.id] = r[o.id] || {};
        r[o.id] = {...r[o.id], ...o};
        return r;
      },{}));
console.log(result);

答案 1 :(得分:1)

您可以使用Map来收集对象中同一id的所有属性。稍后获取地图的值。

const join = o => o && map.set(o.id, Object.assign(map.get(o.id) || {}, o));
var obj1 = { data: [{ id: 1, name: 'Linda' }, { id: 2, name: 'Mark' } ]},
    obj2 =  [{ id: 1, salary: "2000, 60 USD" }, undefined, { id: 2, salary: "4000, 50 USD" }, undefined],
    map = new Map,
    result;

obj1.data.forEach(join);
obj2.forEach(join);
result = { data: Array.from(map.values()) };
   
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:1)

另一种方式

const res = {
    ...obj1, // take the initial object
    data: obj1.data.map(item => ({ // rewrite data property by iterate each item 
                                   // and merge item with corresponding 
                                   // object from obj2
        ...item, // take the item object
        ...obj2.find(({ id }) => id === item.id) // find corresponding object 
    }))
};

答案 3 :(得分:0)

这是一种将对象组合在一起而不覆盖属性,而只添加缺少的对象以及避免使用undefined等的方法:

const names = {data: [{ id: 1, name: 'Linda' },{ id: 2, name: 'Mark' }]}
const salaries = [{ id: 1, salary: "2000, 60 USD" }, undefined]

var result = _.mapValues(names.data, x => {
  let hit = _.find(salaries, y => y ? y.id === x.id : null)
  return hit ? _.defaults(x, hit) : x
})

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

我们正在使用mapValues来获取names.data的值并对其进行浏览,并且每个值都会在salaries中获得成功。如果命中存在,我们用当前数据对象default命中道具并返回。希望这会有所帮助。