【问题标题】:Merge 2 JS Arrays of Objects by value按值合并 2 个 JS 对象数组
【发布时间】:2019-09-04 03:06:03
【问题描述】:

问题

我有两个需要合并的对象的 Javascript 数组。我需要通过匹配每个数组中包含的单个键:值对的唯一值来合并。我要合并的值的键不同

我想根据匹配的唯一值将数组 2 中的键:值对添加到数组 1 中的正确对象。 array1.user 和 array2._id 的值是我需要匹配的值。

数组

const array1 = [ { _id: 5c6c7132f9bf4bdab9c906ff,
    user: 5c65d9438e4a834c8e85dd7d },
  { _id: 5c6ccd6d3a0dc4e4951c2bee,
    user: 5c65d9438e4a834c8e85dd7e } ]

const array2 = users [ { _id: 5c65d9438e4a834c8e85dd7d,
    info: { name: 'John', city: 'New York' } },
  { _id: 5c65d9438e4a834c8e85dd7e,
    info: { name: 'Paneer', city: 'San Fran' } } ]

我的尝试

我尝试过像这样使用 lodash 的 _.map 和 _.extend 函数,但我是 lodash 新手,它没有给我正确的输出

  const mergedArray = _.map(array1, function(item){
    return _.extend(item, _.find(array2, {_id: item.user}));
  });

结果

mergedArray [ { _id: 5c65d9438e4a834c8e85dd7d,
    info: { name: 'John', city: 'New York' } },
  { _id: 5c65d9438e4a834c8e85dd7e,
    info: { name: 'Paneer', city: 'San Fran' } }]

想要的结果

const mergedArray = [ { _id: 5c6c7132f9bf4bdab9c906ff,
    user: 5c65d9438e4a834c8e85dd7d,
    info: { name: 'John', city: 'New York' } } ,
  { _id: 5c6ccd6d3a0dc4e4951c2bee,
    user: 5c65d9438e4a834c8e85dd7e, 
    info: { name: 'Paneer', city: 'San Fran' } } ]

【问题讨论】:

  • 为什么它们是数组?是否有要求的排序顺序?如果没有,您似乎拥有唯一的 ID,这使得该结构作为 _id 是关键的对象更加方便。然后您可以轻松地通过 ID 查找,并避免所有重复。

标签: javascript arrays merge


【解决方案1】:

您可以使用mapfind

如果您的数组映射顺序相同,则可以避免使用find

const array1 = [ { _id: `5c6c7132f9bf4bdab9c906ff`,user: `5c65d9438e4a834c8e85dd7d` },{ _id: `5c6ccd6d3a0dc4e4951c2bee`,user: `5c65d9438e4a834c8e85dd7e` }]
const array2 =[ { _id: `5c65d9438e4a834c8e85dd7d`,info: { name: 'John', city: 'New York' } },{ _id: `5c65d9438e4a834c8e85dd7e`,info: { name: 'Paneer', city: 'San Fran' } } ]
    
const final = array1.map(e=> {
  const found = array2.find(({_id}) => e.user === _id)
  return {
    ...e,
    info : found.info
  }
})

console.log(final)

【讨论】:

  • 我需要合并的两个数组实际上是从 MongoDB 返回的,出于某种原因,我尝试过的任何方法都不起作用,即使相同的方法非常适用于 javascript 数组。您对如何将此解决方案应用于从 MongoDB 返回的数组有任何建议吗?如果有什么不同,我会使用 Mongoose。
【解决方案2】:

您可以使用Map 并为结果构建新对象。

const
    array1 = [{ _id: '5c6c7132f9bf4bdab9c906ff', user: '5c65d9438e4a834c8e85dd7d' }, { _id: '5c6ccd6d3a0dc4e4951c2bee', user: '5c65d9438e4a834c8e85dd7e' }],
    array2 = [{ _id: '5c65d9438e4a834c8e85dd7d', info: { name: 'John', city: 'New York' } }, { _id: '5c65d9438e4a834c8e85dd7e', info: { name: 'Paneer', city: 'San Fran' } }],
    users = new Map(array2.map(({ _id, info }) => [_id, { info }])),
    merged = array1.map(o => ({ ...o, ...(users.get(o.user) || {}) }));

console.log(merged);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我需要合并的两个数组实际上是从 MongoDB 返回的,出于某种原因,我尝试过的任何方法都不起作用,即使相同的方法非常适用于 javascript 数组。您对如何将此解决方案应用于从 MongoDB 返回的数组有什么建议吗?如果有什么不同,我会使用 Mongoose。
【解决方案3】:

另一种方法是使用键生成一个对象,然后直接使用该生成的对象获取值。密钥访问速度非常快。

const array1 = [ { _id: "5c6c7132f9bf4bdab9c906ff",user: "5c65d9438e4a834c8e85dd7d" },{ _id: "5c6ccd6d3a0dc4e4951c2bee",user: "5c65d9438e4a834c8e85dd7e" } ];
const ids = array1.reduce((a, {user, _id}) => ({...a, [user]: _id}), {});
const array2 = [ { _id: "5c65d9438e4a834c8e85dd7d",info: { name:'John', city: 'New York' } },{ _id: "5c65d9438e4a834c8e85dd7e", info: { name: 'Paneer', city: 'San Fran' } } ];
    
array2.forEach(o => {
  o.user = o._id;
  o._id = ids[o._id];
});

console.log(array2);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多