如何将两个对象类型数组相交,包括合并它们的项目?

问题描述

我有两个等长的数组,每个数组都包含对象数据。

这是第一个数组的示例代码...

const array1 = [{
  key: '5',value: '550',},{
  key: '6',value: '750',}];

这是第二个的代码......

const array2 = [{
  type: 'Job',status: 'Finished',key : '5',{
  type: 'Ticket',status: 'Processing',key : '6',}];

为了进一步处理我的数据,我需要将两个数组与其对应的对象项合并。结果应该是这样的......

[{
  key: '5',type: 'Job',type: 'Ticket',}]

到目前为止我想出的是..

array1.forEach(function (element) {
  array2.forEach(function (element) {
    return {
      type: 'Ticket',status: 'Processing'
    };
  });
});

我不知道如何创建预期的结果。我的问题的解决方案是什么样的?

解决方法

您可以通过 key 将对象存储在哈希表中,并将另一个数组与哈希表中的数据合并。

const
    array1 = [{ key: '5',value: '550' },{ key: '6',value: '750' }],array2 = [{ type: 'Job',status: 'Finished',key: '5' },{ type: 'Ticket',status: 'Processing',key: '6' }],temp = Object.fromEntries(array2.map(o => [o.key,o])),result = array1.map(o => ({ ...o,...temp[o.key] }));

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

,

听起来您需要通过键组合两个数组中的对象。 数组方法是一个不错的选择,但您也应该研究其他方法。

const combinedItemsArray = array1.map(item1 => {
       const matchingItem = array2.find(item2 => item2.key === item1.key) 
       return {...item1,...matchingItem }
})

这使用扩展运算符将项目的值与匹配的键组合在一起。

需要考虑的一些事项:

  • Array.find 只匹配数组 2 中满足结果的第一项。所以如果数组有重复键的项目,你需要修改这个。

  • 如果您的数组中有很多项目(1000 个中的 10 个),这将在性能水平上崩溃。在这种情况下,哈希表答案可能是更好的方法。

  • 经常在 mdn 上引用常见的数组方法是个好主意。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map 使用侧边栏找到您可能需要的那个!

,

利用 Array.prototype.map 可以将额外的 target 对象传递给 ... 这里可以使用第二个数组,从中可以检索相应的合并项。

合并是通过 Object.assign 完成的,其中将两个数组项合并到一个新创建的对象中,以便不改变任何一个相关数组的任何合并项...

const array1 = [{
  key: '5',value: '550',},{
  key: '6',value: '750',}];

const array2 = [{
  type: 'Job',key : '5',{
  type: 'Ticket',key : '6',}];

function mergeWithSameIndexItemFromBoundArray(item,idx) {
  const boundArray = this;
  return Object.assign({},item,boundArray[idx]);
}

console.log(
  'merge result of array2 and array1 ...',array2.map(mergeWithSameIndexItemFromBoundArray,array1)
);
console.log(
  'merge result of array1 and array2 ...',array1.map(mergeWithSameIndexItemFromBoundArray,array2)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

如果有不匹配的商品订单数组,可以在上述方法的基础上为 map 提供额外的目标对象。

这次不是第二个数组而是它的一个变换;通过使用标识所有项目的属性名称将第二个数组的所有项目映射到它的对象。对于 OP 的示例,此属性名称为 key

因此需要编写一个额外的函数来完成这个映射任务。下面的下一个示例选择基于 Array.prototype.reduce 的方法。

此外,必须重写映射器函数,以便通过简单地使用数组项的 key 属性而不是之前的数组索引来使用之前创建的绑定映射...

const array1 = [{
  key: '5',{
  key: '7',value: '320',}];

const array2 = [{
  type: 'Ticket',{
  type: 'Job',{
  type: 'Task',status: 'Pending',key : '7',}];

function createKeyBasedItemMap(map,item) {
  map[item.key] = item;
  return map;
}
function mergeWithKeyBasedItemFromBoundMap(item) {
  return Object.assign({},this[item.key]);
}

console.log(
  'map-based merge of unordered array2 and array1 items ...',array2.map(
    mergeWithKeyBasedItemFromBoundMap,array1.reduce(createKeyBasedItemMap,{})
  )
);
console.log(
  'map-based merge of unordered array1 and array2 items ...',array1.map(
    mergeWithKeyBasedItemFromBoundMap,array2.reduce(createKeyBasedItemMap,{})
  )
);
console.log('\n');

console.log(
  'proof of concept ... the item-map based on array1 ...',{})
);
console.log(
  'proof of concept ... the item-map based on array2 ...',{})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }