Renumber Index Variable

An index variable starts at a non-standard value, causing confusion or requiring repetitive arithmetic.

Renumber the index variable to start at the standard value.

Before:

 for (int i = 2; i < maxItems + 2; i++)
 {
doSomething(i-2);
if (i < 10)
 doSomethingElse(i-2);
println(i*i + 0.75 * i + 6);
 }
After:

 for (int i = 0; i < maxItems; i++)
 {
doSomething(i);
if (i < 8)
 doSomethingElse(i);
println(calcSomething(i+2);
 }
Motivation:

Sometimes, the index of a loop is obviously not what it should be. Obvious signs are:

With this refactoring, you can quickly and safely change the index.

[Other refactorings should exist to handle changing an index passed into a method (RenumberIndexParameter?), and changing the way a data structure is indexed (RenumberDataStructureIndex?).]

Mechanics:

Example:

Before:

 for (int i = 2; i < maxItems + 2; i++)
 {
doSomething(i-2);
if (i < 10)
 doSomethingElse(i-2);
println(i*i + 0.75 * i + 6);
 }
During:

 for (int i = 2; i < maxItems + 2; i++)
 {
int j = i-2;
doSomething(j+2-2);
if (j+2 < 10)
 doSomethingElse(j+2-2);
println((j+2)*(j+2) + 0.75 * (j+2) + 6);
 }

for (int j+2 = 2; j+2 < maxItems + 2; j+2++) { doSomething(j+2-2); if (j+2 < 10) doSomethingElse(j+2-2); println((j+2)*(j+2) + 0.75 * (j+2) + 6); }
After:

 int calcSomething(int i)
 {
return (i+2)*(i+2) + 0.75 * (i+2) + 6;
 }
 ...

for (int j = 0; j < maxItems; j++) { doSomething(j); if (j < 8) doSomethingElse(j); println((j+2)*(j+2) + 0.75 * (j+2) + 6); // ^^^ candidate for ExtractMethod: println(calcSomething(j+2)); }


All the examples above stayed with integer arithmetic, at least. This is what you must never do:

  // Lousy trapezoidal rule implementation.
  double delta = (b - a) / n;
  double sum = 0.0;
  for (double x = a; x <= b; x+= delta) {
    coeff = ((x == a) || (x == b)) ? 1 : 2;
    sum += f(x) * coeff;
  }
  return sum  / (2.0 * n);
How many times will the loop be executed? Who knows? You cannot depend upon the values of x to be anything in particular. a + delta + delta + delta won't be the same as a + 3 * delta. Never use floating-point numbers to index a loop. Better is:

  double delta = (b - a) / n;
  double sum = f(a) + f(b);  // Avoid figuring out coefficients.
  for (int i = 1; i < n; ++i) {
    x = a + i * delta;
    sum += 2.0 * f(x);
  }
  return sum / (2.0 * n);
Perhaps you should use SimpsonsRule? instead.


See also RefactorMatchLoopToUsage


CategoryRefactoring


EditText of this page (last edited May 30, 2012) or FindPage with title or text search