skip to Main Content

How to reduce the complexity of the given piece of code? I am getting this error in Sonarqube—> Refactor this method to reduce its Cognitive Complexity from 19 to the 15 allowed.

Here the daysPassed is the time which is in the form of minutes

        let output = "";
        if (daysPassed < 60) {
          output = this.formatOutput(daysPassed, "min");
        } else if (daysPassed < 60 * 24) {
          output = this.formatOutput(Math.floor(daysPassed / 60), "hour");
        } else if (daysPassed < 60 * 24 * 30) {
          output = this.formatOutput(Math.floor(daysPassed / (60 * 24)), "day");
        } else {
          output = this.formatOutput(Math.floor(daysPassed / (60 * 24 * 30)), "month");
        }
       

        formatOutput(value, unit) {
           return `${value} ${unit}${value === 1 ? '' : 's'} ago`;
        }

I tried like : this also not working

        let output = "";
        if (daysPassed < 60) {
          output = `${Math.floor(daysPassed)} mins ago`;
        } else if (daysPassed < 60 * 24) {
          output = `${Math.floor(daysPassed / 60)} hours ago`;
        } else {
          const timeUnits = [
            { unit: "day", duration: 60 * 24 },
            { unit: "month", duration: 60 * 24 * 30 }
          ];
        
          for (const unit of timeUnits) {
            if (daysPassed < unit.duration * 30) {
              output = `${Math.floor(daysPassed / unit.duration)} ${unit.unit}${Math.floor(daysPassed / unit.duration) === 1 ? '' : 's'} ago`;
              break;
            }
        }
        }

2

Answers


  1. I write sometimes code as follows:

    if (daysPassed < 60) {
        return `${Math.floor(daysPassed)} mins ago`;
    }
    
    if (daysPassed < 60 * 24) {
        return `${Math.floor(daysPassed / 60)} hours ago`;
    }
    
    ..
    
    Login or Signup to reply.
  2. Some elements that increase the cognitive complexity in your code:

    • if statements. Each of them counts. Replacing with a single for loop can decrease this complexity.
    • Sequences of operators (like *)
    • Nested calls of functions

    I believe a for loop should resolve the issue, but then you must get rid of the if statements. The loop condition can take that role.

    I present the code as a function, as I assume that is your case:

    function formatDelay(daysPassed) {
        const limits = [60, 24, 30, Infinity];
        const units = ["min", "hour", "day", "month"];
        let value = daysPassed;
        let i;
        for (i = 0; value >= limits[i]; i++) {
            value /= limits[i];
        }
        value = Math.floor(value);
        return `${value} ${units[i]}${value === 1 ? '' : 's'} ago`;
    }
    
    function formatDelay(daysPassed) {
        const limits = [60, 24, 30, Infinity];
        const units = ["min", "hour", "day", "month"];
        let value = daysPassed;
        let i;
        for (i = 0; value >= limits[i]; i++) {
            value /= limits[i];
        }
        value = Math.floor(value);
        return `${value} ${units[i]}${value === 1 ? '' : 's'} ago`;
    }
    
    // Just some tests
    for (let minutes of [15, 91, 60*10 + 10, 60*24*3 + 60, 60*24*30*8 + 100, 1000000000]) {
        console.log(formatDelay(minutes));
    }
          
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search