I've got a working code that transforms data from a MySQL database.
Currently, it's inefficient because it uses about loops, which you'll see at the bottom.
I get an array of objects from a database query. The rows look like this:
[
{
userId: 1,
WorkoutId: 1,
workoutTitle: 'Hustler',
workoutDescription: 'Goes to jail a lot',
exerciseId: 1,
exerciseTitle: 'Forward Implementation Executive',
exerciseDescription: 'directional',
SetId: 1,
setDate: 2021-07-05T23:00:00.000Z,
restTime: 60,
reps: 12,
duration: 0,
weight: 10
},
DUPLICATE for more^^^^
]
The desired output looks like:
[
{
"date": "5-Jul",
"reps": "up",
"duration": "same",
"weight": "up",
"setDetails": [
{
"weight": 10,
"reps": 12,
"duration": 0
}
]
}
]
You'll notice some of the queried data is omitted from the final result; you can assume it's not needed/relevant to the question.
The objective is to:
- Group the data by the date property.
- Do comparisons between the weight, reps, duration properties that are grouped. (objects within
setDetails
) - Append the comparison result to the grouped object. (GROUPED BY DATE)
Current code:
async function service(provider, token, exerciseId) {
// Some validation
const res = await GetTableAnalyticsTwo(id, exerciseId);
const data = res[0];
if (data.length < 1) {
return {message: "We can't provide you with Analytics until you've recorded the workout."}
}
let analytics = {}
data.map((exercise) => {
const {setDate, weight, reps, duration} = exercise;
const date = setDate.toISOString().substring(0, 10);
const dateExists = analytics[date];
if (dateExists) {
let arr = analytics[date].setDetails;
arr.push({
weight,
reps,
duration
});
} else if (!dateExists) {
analytics[date] = {
setDetails: [{
weight,
reps,
duration
}]
}
}
});
Object.entries(analytics).forEach(([key, values]) => {
let avgWeight = 0;
let totalDuration = 0;
let totalReps = 0;
let length = values.setDetails.length;
values.setDetails.forEach((sets) => {
const {weight, reps, duration} = sets;
avgWeight += weight;
totalDuration += duration;
totalReps += reps;
});
avgWeight /= length;
analytics[key].avgWeight = avgWeight;
analytics[key].totalDuration = totalDuration;
analytics[key].totalReps = totalReps;
});
let response = [];
let prevReps = 0, prevDuration = 0, prevWeight = 0;
Object.entries(analytics).forEach(([date, exercises]) => {
const {avgWeight, totalDuration, totalReps, setDetails} = exercises;
let reps, duration, weight;
prevReps < totalReps ? reps = "up" : reps = "down";
prevDuration < totalDuration ? duration = "up" : duration = "down";
prevWeight < avgWeight ? weight = "up" : weight = "down";
if (prevReps === totalReps) {
reps = "same";
}
if (prevDuration === totalDuration) {
duration = "same";
}
if (prevWeight === avgWeight) {
weight = "same";
}
const setDate = new Date(date);
const month = toMonthString(date);
const exercise = {
date: setDate.getDate() + "-" + month,
reps,
duration,
weight,
setDetails
}
response.push(exercise);
prevReps = totalReps;
prevDuration = totalDuration;
prevWeight = avgWeight;
});
return response;
}
setDetails
. It's an array of objects that's grouped by date then put into setDetails.JSON_ARRAYAGG()
might solve this but still looking into it. \$\endgroup\$