2

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, i.e:

[{
"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!

2
  • So the dob is 1990 since you are doing a calculation. 2003-09-04 = 1990 Commented Jan 7, 2022 at 16:54
  • Good catch - I just went through and changed the dates. Thank you! Commented Jan 7, 2022 at 16:59

3 Answers 3

2

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 the data exists in the map, then we should merge the data
  if (array1Data) {
    arr.push({...array1Data, ...userData});
  }
  return arr;
}, []);


console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

1

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/[email protected]/lodash.min.js"></script>

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.