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:
[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:
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