Ali Gajani
Ali Gajani

Reputation: 15091

How can I write this function without a bunch of if else statements?

I basically just can't figure this one out and don't want to hack it.

It will look so messy if I do this for 52 weeks in a year.

Any tips?

Update

This question is not about getting the year's current week.

This question is about getting weeks elapsed since a date defined.

I want the next week's workout to show up on 6th day of the current week ;)

Example

My days since start are 99: 2018-05-30 18:39:29.

Some of your examples are showing me on week 15.

My code however shows week 16, which is right. See the caveat?

  calculateUsersCurrentWorkoutWeek: function(timestamp) {
            let daysSinceSignup = moment().diff(timestamp, "days");
            if (daysSinceSignup <= 6) {
              return 1;
            } else if (daysSinceSignup > 6 && daysSinceSignup <= 13) {
              return 2;
            } else if (daysSinceSignup > 13 && daysSinceSignup <= 20) {
              return 3;
            } else if (daysSinceSignup > 20 && daysSinceSignup <= 27) {
              return 4;
            } else if (daysSinceSignup > 27 && daysSinceSignup <= 34) {
              return 5;
            } else if (daysSinceSignup > 34 && daysSinceSignup <= 41) {
              return 6;
            } else if (daysSinceSignup > 41 && daysSinceSignup <= 48) {
              return 7;
            } else if (daysSinceSignup > 48 && daysSinceSignup <= 55) {
              return 8;
            } else if (daysSinceSignup > 55 && daysSinceSignup <= 62) {
              return 9;
            } else if (daysSinceSignup > 55 && daysSinceSignup <= 62) {
              return 10;
            } else if (daysSinceSignup > 62 && daysSinceSignup <= 69) {
              return 11;
            } else if (daysSinceSignup > 69 && daysSinceSignup <= 76) {
              return 12;
            } else if (daysSinceSignup > 76 && daysSinceSignup <= 83) {
              return 13;
            } else if (daysSinceSignup > 83 && daysSinceSignup <= 90) {
              return 14;
            } else if (daysSinceSignup > 90 && daysSinceSignup <= 97) {
              return 15;
            } else {
              return 16;
            }
          }

Upvotes: 2

Views: 182

Answers (5)

Madara&#39;s Ghost
Madara&#39;s Ghost

Reputation: 174957

Divide by 7 and ceil?

const daysSinceSignup = moment().diff(timestamp, "days");
return Math.ceil(daysSinceSignup / 7);

Did you miss out on coffee this morning? ;-)


Note: The function above will tell you "the number of the week since timestamp" which is what I understand from your text, but your code sample does not reflect it.

To get the same result of your code sample, you'll need to .floor() and add 1 instead of .ceil():

const daysSinceSignup = moment().diff(timestamp, "days");
return Math.floor(daysSinceSignup / 7) + 1;

Upvotes: 11

Ankit Agarwal
Ankit Agarwal

Reputation: 30739

The easy way could also be to create a integer array in ascending order so that the values contain the upper limit of the comparison. Then for each values of daysSinceSignup you can find the index and add 1 to it since you require the return values as 1, 2, 3, ... and so on. This will be useful if you do not have uniform interval, like currently the interval is always 7 so the division and ceil approach could also work but if the interval is not uniform then this approach could be really useful.

var indexArray = [6,13,20,27,34,41,48,55,62,69,76,83,90,97];
function calculateUsersCurrentWorkoutWeek() {
  let daysSinceSignup = 14;
  var elemIndex = indexArray.findIndex((item)=> item > daysSinceSignup);
  return elemIndex+1;
}
console.log(calculateUsersCurrentWorkoutWeek());

Upvotes: 2

Tamas Hegedus
Tamas Hegedus

Reputation: 29906

What you are looking for is

return Math.ceil((daysSinceStartup + 1) / 7);

This will give the same results as your code for any real number between -1 and 62 (because around 62 you forgot to replace the copied ranges). It returns 1 for 6 days, and 2 for 6.01 days, just as the original code.

Upvotes: 2

Jae Woo Woo
Jae Woo Woo

Reputation: 1041

As @Michel said, divide by 7 and floor + 1

calculateUsersCurrentWorkoutWeek: function(timestamp) {
    let daysSinceSignup = moment().diff(timestamp, "days");
    return Math.floor(daysSinceSignup / 7) + 1;
}

Upvotes: 2

Faly
Faly

Reputation: 13346

You can put your datas in array and use array.find:

var datas = [
    { min: -Infinity, max: 6, ret: 1 },
    { min: 6, max: 13, ret: 2 },
    { min: 13, max: 20, ret: 3 },
    { min: 20, max: 27, ret: 4 }
];

function calculateUsersCurrentWorkoutWeek(daysSinceSignup) {
    return datas.find(({min, max}) => 
        daysSinceSignup > min && daysSinceSignup <= max
    ).ret;
}

console.log(calculateUsersCurrentWorkoutWeek(5));
console.log(calculateUsersCurrentWorkoutWeek(7));
console.log(calculateUsersCurrentWorkoutWeek(14));

Upvotes: 0

Related Questions