I have a function thats supposed to be merge two objects together based on certain conditions. the vitalsArray is an array of objects that are unsorted that may or may not have corresponding values (i.e systolic to diastolic and vice versa). Basically if certain conditions are met that would mean that the systolic object and the diastolic object are one BP vital and need to be merged.
My question is is there a better way of doing this than a nested forEach loop?
const mergeBloodPressures = (vitalsArray) => {
let ids = []
let finalArray = []
vitalsArray.forEach((tmpBP) => {
vitalsArray.forEach((bp) => {
let matchDate = moment(bp.takenOn).isSame(
moment(tmpBP.takenOn),
"minute"
)
if (
matchDate &&
bp.vitalType.name != tmpBP.vitalType.name &&
!ids.includes(bp.id) &&
!ids.includes(tmpBP.id)
) {
let temp = {}
if (bp.vitalType.name == "diastolic blood pressure") {
temp.diastolic = bp
temp.systolic = tmpBP
} else {
temp.diastolic = tmpBP
temp.systolic = bp
}
ids.push(bp.id)
finalArray.push(temp)
}
})
})
return finalArray
}
Sample Input:
[
{
"patient_id": 716,
"vital_type_id": 2,
"value": "78",
"taken_on": "2022-06-22T14:49:48.948-05:00",
"vitalType": {
"id": 2,
"name": "diastolic_blood_pressure",
"units": "mmHg",
"created_at": "2022-06-22T14:40:43.746-05:00",
"updated_at": "2022-06-22T14:40:43.746-05:00"
},
"id": 9101,
},
{
"patient_id": 716,
"vital_type_id": 1,
"value": "129",
"taken_on": "2022-06-22T14:49:48.948-05:00",
"vital_type": {
"id": 1,
"name": "systolic_blood_pressure",
"units": "mmHg",
"created_at": "2022-06-22T14:40:43.740-05:00",
"updated_at": "2022-06-22T14:40:43.740-05:00"
},
"id": 9102,
}
]
Sample Output:
[
{
"diastolic": {
"patient_id": 716,
"vital_type_id": 2,
"value": "78",
"taken_on": "2022-06-22T14:49:48.948-05:00",
"vitalType": {
"id": 2,
"name": "diastolic_blood_pressure",
"units": "mmHg",
"created_at": "2022-06-22T14:40:43.746-05:00",
"updated_at": "2022-06-22T14:40:43.746-05:00"
},
"id": 9101,
},
"systolic": {
"patient_id": 716,
"vital_type_id": 1,
"value": "129",
"taken_on": "2022-06-22T14:49:48.948-05:00",
"vitalType": {
"id": 1,
"name": "systolic_blood_pressure",
"units": "mmHg",
"created_at": "2022-06-22T14:40:43.740-05:00",
"updated_at": "2022-06-22T14:40:43.740-05:00"
},
"id": 9102
}
}
]
Your input only shows a single patient on a single date but here is an example that extrapolates from that a little to provide a result that is grouped by patient_id
and then further grouped by taken_on
within that.
The result is of the following shape:
[
{
"patient_id": 1,
"vitals": [
{
"diastolic": {
taken_on: 1,
//...
},
"systolic": {
taken_on: 1,
//...
}
},
{
"diastolic": {
taken_on: 2,
//...
},
"systolic": {
taken_on: 2,
//...
}
}
]
},
{
"patient_id": 2,
"vitals": [
{
"diastolic": {
taken_on: 1,
//...
},
"systolic": {
taken_on: 1,
//...
}
},
//...
]
}
]
To achieve this the example below iterates each element using a for...of
loop then retrieves or creates the a patient_id
property using logical nullish assignment (??=). It then further retrieves or initializes an object to group into based on taken_on
. Finally the result is created by taking the Object.entries()
of the grouped object and mapping over it in order to also convert each taken_on
object to a an array of values.
const input = [{ "patient_id": 716, "vital_type_id": 2, "value": "78", "taken_on": "2022-06-22T14:49:48.948-05:00", "vitalType": { "id": 2, "name": "diastolic_blood_pressure", "units": "mmHg", "created_at": "2022-06-22T14:40:43.746-05:00", "updated_at": "2022-06-22T14:40:43.746-05:00" }, "id": 9101, }, { "patient_id": 716, "vital_type_id": 1, "value": "129", "taken_on": "2022-06-22T14:49:48.948-05:00", "vital_type": { "id": 1, "name": "systolic_blood_pressure", "units": "mmHg", "created_at": "2022-06-22T14:40:43.740-05:00", "updated_at": "2022-06-22T14:40:43.740-05:00" }, "id": 9102, }];
const vitalTypesById = {
1: 'systolic',
2: 'diastolic'
};
const groupedByPatient = {};
for (const o of input) {
const takenOn = new Date(o.taken_on).setSeconds(0, 0);
const patient = (groupedByPatient[o.patient_id] ??= {});
const patientByDate = (patient[takenOn] ??= {});
patientByDate[vitalTypesById[o.vital_type_id]] = { ...o };
}
const result = Object.entries(groupedByPatient).map(([patient_id, vitals]) => (
{
patient_id,
vitals: Object.values(vitals)
}
));
console.log(JSON.stringify(result, null, 2));