【问题标题】:Comparing two Objects by id and creating the new one按 id 比较两个对象并创建新对象
【发布时间】:2018-08-08 08:01:59
【问题描述】:

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

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 响应。

【问题讨论】:

  • 两个数组的长度相同吗?同一索引处的id 是否相同?
  • 没错,
  • 请添加有效的数据结构。
  • @NinaScholz,删除了obj2 中的逗号。这有帮助吗?
  • 您确定您的obj2 有效吗?

标签: javascript underscore.js lodash


【解决方案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);

【讨论】:

  • 谢谢。请检查更新的问题。这是obj2 中的实际响应。
【解决方案2】:

您可以使用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; }

【讨论】:

  • 谢谢。请检查更新的问题。这是obj2 中的实际响应。
  • 如果obj2中没有data:,我可以直接使用obj2.forEach(join);吗?
  • 奇怪,只映射了最后一个id
  • 什么只映射最后一个id
  • console.log(result); 表示只映射了最后一个id。
【解决方案3】:

另一种方式

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 
    }))
};

【讨论】:

  • 你能解释一下吗
  • @JohnSam 我被添加了 cmets
  • 关闭。 @stasovlas,你想加入聊天,这样我们就可以继续了。我在某个地方出错了吗?
【解决方案4】:

这是一种组合对象而不覆盖属性但只添加缺少的属性以及避免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 使用当前数据对象命中的道具并返回。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多