0
\$\begingroup\$

I have a problem where I need to display the below output

1
23
456
78910

My first solution is

let numberStepper = (stepLimit) => {
  let stepCounter = 0;
  let step = '';

  for(let row = 1; row <= stepLimit; row++) {
      step = '';
      
     for(let col = 1; col <= row; col++) {
         stepCounter++;
         
         step += `${stepCounter}`  
     }

      if(stepCounter > stepLimit) {
          break;
      }

      console.log(step);
  }
   
}

numberStepper(10) // Gives desired output 

Another solution that limits the number of steps output is below.

let numberStepper = (stepsLimit) => {
  let stepCounter = 0;
  let step = '';

  for(let row = 1; row <= stepsLimit; row++) {
      step = '';
      
     for(let col = 1; col <= row; col++) {
         stepCounter++;
         
         step += `${stepCounter}`  
     }

      console.log(step);
  }
   
}

numberStepper(4) // Gives desired output 

How can I refactor this function to have a clean implementation?

Any ideas on the first implementation? where the argument determines the numbers displayed in the steps instead of using the number of steps as the determinant of the numbers displayed?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

functions should return a value

It's unprofessional to use console.log for the output of a function. It's better to think of functions as a blackbox where you give it an input and it spits back an output.

If you were to write unit tests for your function, you would have to go out of your way to either mock console.log to see if it's used properly or to read directly from stdout. Those aren't the easiest options.

give meaningful variable and function names

It's not intuitively easy to understand what the variable names are intended to represent.

For example, step should probably be renamed to row or numbersOnRow or even rowString.


Here is an alternative way that reduces the complexity. It follows the pattern that the length of each row increases by one consecutively. So in the end, no real need to have a double for loop. You can simply populate a list with all the values, and then loop through it once to build your output.

const numberStepper = (stepLimit) => {
  // build list with prefilled values
  const list = (new Array(stepLimit))
    .fill(undefined)
    .map((_,i) => i + 1);
    
  const result = [];
  for(let i = 0, j = 1; i < list.length; i+=j, j++) {
    result.push(list.slice(i, i+j));
  }
  
  // format
  return result.map(row => row.join('')).join('\n');
}

const result = numberStepper(10);

console.log(result);

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.