"inner join" 如何通过 javascript 中的一个键来 "inner join" 两个数组?

How to "inner join" two arrays by a key in javascript?

我有两个包含如下对象的数组:

const array1 = 
[
{
    "id": 1,
    "mass": 149,
    "height": 180,
    "dob": "2003-09-04"
},
{
    "id": 2,
    "mass": 140,
    "height": 175,
    "dob": "2000-02-12",
},
{
    "id": 3,
    "mass": 143,
    "height": 170,
    "dob": "2001-11-04" 
}
]

const array2 = 
[
{
    "id": 1,
    "name": "James",
    "sport": "Football"
},
{
    "id": 2,
    "name": "Adam",
    "sport": "Tennis"
}
]

我想合并它们,这样组合数组只包含 id 出现在数组 1 和数组 2 中的数据。

到目前为止,我使用的是 lodash _.merge,其中 returns:

const merged = _.merge(array1, array2)

merged = [
{
"id": 1,
"mass": 149,
"height": 180,
"dob": "2003-09-04",
"name": "James",
"sport": "Football"
},
{
"id": 2,
"mass": 140,
"height": 175,
"dob": "2000-02-12",
"name": "Adam",
"sport": "Tennis"
},
{
"id": 3,
"mass": 143,
"height": 170,
"dob": "2001-11-04" ,
}
]

我只想 merged 包含 id 出现在两者中的数据,即:

[{
"id": 1,
"mass": 149,
"height": 180,
"dob": "2003-09-04",
"name": "James",
"sport": "Football"
},
{
"id": 2,
"mass": 140,
"height": 175,
"dob": "2000-02-12",
"name": "Adam",
"sport": "Tennis"
}]

我相信类似 SQL 的等效函数将是“内部联接”

如有任何帮助,我们将不胜感激!

您可以使用 Array.filter 过滤您的第一个数组,以便在执行相同的合并之前仅包含第二个数组中存在的对象。

let merged = array1.filter(e => array2.some(f => f.id == e.id));

const array1 = 
[
{
    "id": 1,
    "mass": 149,
    "height": 180,
    "dob": 2003-09-04
},
{
    "id": 2,
    "mass": 140,
    "height": 175,
    "dob": 2000-02-12,
},
{
    "id": 3,
    "mass": 143,
    "height": 170,
    "dob": 2001-11-04 
}
]

const array2 = 
[
{
    "id": 1,
    "name": "James",
    "sport": "Football"
},
{
    "id": 2,
    "name": "Adam",
    "sport": "Tennis"
}
]

let merged = array1.filter(e => array2.some(f => f.id == e.id));
merged = _.merge(merged, array2);

console.log(merged);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>

您需要将它们从一个映射到另一个。使用 reduce 的基本思想,我们通过 id 跟踪项目。

const array1 = [{
    "id": 1,
    "mass": 149,
    "height": 180,
    "dob": '2003-09-04'
  },
  {
    "id": 2,
    "mass": 140,
    "height": 175,
    "dob": '2000-02-12',
  },
  {
    "id": 3,
    "mass": 143,
    "height": 170,
    "dob": '2001-11-04'
  }
]

const array2 = [{
    "id": 1,
    "name": "James",
    "sport": "Football"
  },
  {
    "id": 2,
    "name": "Adam",
    "sport": "Tennis"
  }
]


const result = Object.values([...array1, ...array2].reduce((acc, userData) => {
  // have you seen the id before? If yes, use it, if no use and empty object
  const data = acc[userData.id] || {};
  //merge the objects together and store the updated data by the id
  acc[userData.id] = { ...data, ...userData };
  return acc
}, {}));

console.log(result);

现在这将包括所有内容。如果你只想要两者中的项目,你可以在两个循环中完成。

const array1 = [{
    "id": 1,
    "mass": 149,
    "height": 180,
    "dob": '2003-09-04'
  },
  {
    "id": 2,
    "mass": 140,
    "height": 175,
    "dob": '2000-02-12',
  },
  {
    "id": 3,
    "mass": 143,
    "height": 170,
    "dob": '2001-11-04'
  }
]

const array2 = [{
    "id": 1,
    "name": "James",
    "sport": "Football"
  },
  {
    "id": 2,
    "name": "Adam",
    "sport": "Tennis"
  }
]


// create a look up by the id
const array1MappedById = array1.reduce((acc, userData) => {
  acc[userData.id] = userData;
  return acc
}, {});

// Loop over the second array and make a new array with the merged data
const result = array2.reduce((arr, userData) => {
  const array1Data = array1MappedById[userData.id];
  // if the data exists in the map, then we should merge the data
  if (array1Data) {
    arr.push({...array1Data, ...userData});
  }
  return arr;
}, []);


console.log(result);

这将合并id相同id的数据

const merged = array2.reduce((arr, current) => {
    let array1Data = {...array1}[current.id];
    if (array1Data) {
      arr.push({...array1Data, ...current});
    }
    return arr;
}, []);

console.log(merged);