David R
David R

Reputation: 193

Calculate total duration for a workouts in an array

I would like to calculate the total duration of exercises based on the "rest" and "rep" values.

Here is an example json object for "exercises"

{
"warmUp": [
    {
        "title": "Abdominal Crunch",
        "id": "4YRrftQysvE1Kz8XACtrq4",
        "rest": [
            "30",
            "30",
            "30",
            "30",
            "30",
            "",
            "",
            "",
            "",
            ""
        ],
        "reps": [
            "5",
            "5",
            "5",
            "5",
            "5",
            "",
            "",
            "",
            "",
            ""
        ],
        "time": false,
    },
    {
        "title": "Bicep curl",
        "rest": [
            "30",
            "30",
            "30",
            "",
            "",
            "",
            "",
            "",
            "",
            ""
        ],
        "reps": [
            "5",
            "5",
            "",
            "5",
            "",
            "",
            "",
            "",
            "",
            ""
        ],
        "time": false
    }
]}

The difficult I'm having is that the values are in a nested and I'm currently mapping them out in a .map function which is returning individual durations for each item

You can see the 2 durations beneath, I would like to have a total duration

I would like to get the combined total duration for all exercises added.

The calculation I'm doing is const Total = totalReps * 4 + parseInt(totalRest);

      {exercises.map((exercise) => {
        const reps = exercise.reps.map((i) => Number(i));
        const rest = exercise.rest.map((i) => Number(i));
        // console.log("reps ", reps);
        // console.log("rest ", rest);

        const totalReps = reps.reduce((a, b) => a + b, 0);
        const totalRest = rest.reduce((a, b) => a + b, 0);
        // console.log("totalReps ", totalReps);
        // console.log("totalRest ", totalRest);

        const Total = totalReps * 4 + parseInt(totalRest);
        // console.log("total ", Total);

        let sec_num = parseInt(Total, 10); // don't forget the second param
        let hours = Math.floor(sec_num / 3600);
        let minutes = Math.floor((sec_num - hours * 3600) / 60);
        let seconds = sec_num - hours * 3600 - minutes * 60;

        if (hours < 10) {
          hours = "0" + hours;
        }
        if (minutes < 10) {
          minutes = "0" + minutes;
        }
        if (seconds < 10) {
          seconds = "0" + seconds;
        }
        return (
          <Paragraph>
            Total Workout Duration: {hours}:{minutes}:{seconds}
          </Paragraph>
        );
      })}

Upvotes: 0

Views: 104

Answers (2)

Always Learning
Always Learning

Reputation: 5591

Here's an example that simplifies the code and collects the grand total.

Also you were doing a return statement of the html output. I added a console.log. I commented out the return of html for the purposes of a short example that just outputs to the console.

const exercises = [
  {
    title: 'Abdominal Crunch',
    id: '4YRrftQysvE1Kz8XACtrq4',
    rest: ['30', '30', '30', '30', '30', '', '', '', '', ''],
    reps: ['5', '5', '5', '5', '5', '', '', '', '', ''],
    time: false
  },
  {
    title: 'Bicep curl',
    rest: ['30', '30', '30', '', '', '', '', '', '', ''],
    reps: ['5', '5', '', '5', '', '', '', '', '', ''],
    time: false
  }
];

function showTotal(total, prefix) {
  let sec_num = parseInt(total, 10); 
  let hours = Math.floor(sec_num / 3600);
  let minutes = Math.floor((sec_num - hours * 3600) / 60);
  let seconds = sec_num - hours * 3600 - minutes * 60;

  if (hours < 10) {
    hours = "0" + hours;
  }
  if (minutes < 10) {
    minutes = "0" + minutes;
  }
  if (seconds < 10) {
    seconds = "0" + seconds;
  }
  console.log(`${prefix}: ${hours}:${minutes}:${seconds}`)
  /* return (
      <Paragraph>
        {prefix}: {hours}:{minutes}:{seconds}
      </Paragraph>
    ); */
}

let grandTotal = 0
exercises.map((exercise) => {
  const totalReps = exercise.reps.reduce((a, b) => a + parseInt(b || 0, 10), 0);
  const totalRest = exercise.rest.reduce((a, b) => a + parseInt(b || 0, 10), 0);

  const total = totalReps * 4 + parseInt(totalRest);
  grandTotal += total
  return showTotal(total, `Total ${exercise.title} Duration`);        
})

showTotal(grandTotal, "Grand Total");

Upvotes: 2

Aion
Aion

Reputation: 681

I dont realy understand your problem here since every thing you have work ...

The only thing you have to do is to externalize your total calculation in a function like :

     function retrieveWorkoutDuration(total) {
        let sec_num = parseInt(total, 10); // don't forget the second param
        let hours = Math.floor(sec_num / 3600);
        let minutes = Math.floor((sec_num - hours * 3600) / 60);
        let seconds = sec_num - hours * 3600 - minutes * 60;

        if (hours < 10) {
          hours = "0" + hours;
        }
        if (minutes < 10) {
          minutes = "0" + minutes;
        }
        if (seconds < 10) {
          seconds = "0" + seconds;
        }
        return (
          <Paragraph>
            Total Workout Duration: {hours}:{minutes}:{seconds}
          </Paragraph>
        );
     }

And at the end, you just have to sum all of your workout duration and send the number to your 'retrieveWorkoutDuration' function

Upvotes: 1

Related Questions