简体   繁体   中英

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

I have two arrays containing objects like so:

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"
}
]

I would like to merge them such that a combined array only contains data where the id appears in both array1 and array2.

So far I'm using lodash _.merge which 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" ,
}
]

I would just like merged to contain data where id appears in both, ie:

[{
"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"
}]

I believe the equivalent function in something like SQL would be an "Inner join"

Any help would be greatly appreciated!

You can filter your first array with Array.filter to only include objects that are present in your second array before performing the same merge.

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>

You need to map them from one to the other. Basic idea using reduce where we track the item by the 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);

Now that will include everything. If you only want the items that are in both, you can do it in two loops.

 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 (array1Data) { arr.push({...array1Data, ...userData}); } return arr; }, []); console.log(result);

this will merge the data where the id is the same id

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

console.log(merged);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM