For loop patterns

The primordial for loop

for (int i = 0; i < n; i++) {
  // code here that uses i
}

You should be able to look at this and immediately know that it executes n times.

The primordial for loop over a string

for (int i = 0; i < s.length(); i++) {
  // code here that uses i, e.g. s.substring(i, i + 1)
}

The primordial for loop over an array

for (int i = 0; i < a.length; i++) {
  // code here that uses i, e.g. a[i]
}

If you haven’t peeked at Unit 6 yet, don’t worry about this one.

A counting for loop

Count the number of things that match some criteria.

public int countVowels(String s) {
  int  count = 0;
  for (int i = 0; i < s.length(); i++) {
    String letter = s.substring(i, i + 1);
    if (isVowel(letter)) {
      count++;
    }
  }
  return count;
}

A summing for loop

Accumulate a total.

public int totalBelow(int n) {
  int total = 0;
  for (int i = 0; i < n; i++) {
    total += someNumberComputedFromI(i);
  }
  return total;
}

A mapping for loop

public int[] lengths(String[] strings) {
  int[] lengths = new int[strings.length];
  for (int i = 0; i < strings.length; i++) {
    lengths[i] = strings[i].length();
  }
  return lengths;
}

A filtering for loop

public String[] elementsStartingWithX(String[] strings) {
  String[] result = new String[countStartsWithX(strings)];
  int j = 0;
  for (int i = 0; i < strings.length; i++) {
    if (startsWithX(strings[i])) {
      result[j] = strings[i];
      j++;
    }
  }
  return results;
}

Note that we need another index (j here) to index into the result array since there is not a one-to-one mapping between elements of strings and the elements of result.

An accumulating for loop

public String justVowels(String s) {
  String vowels = "";
  for (int i = 0; i < s.length(); i++) {
    String letter = s.substring(i, i + 1);
    if (isVowel(letter)) {
      vowels += letter;
    }
  }
  return vowels;
}

This is like a summing loop except insted of adding to a number we add to something else, in this case a String that we’re building up.

A finding for loop

Find an element that matches some criteria.

public String findVowel(String s) {
  for (int i = 0; i < s.length(); i++) {
    String letter = s.substring(i, i + 1);
    if (isVowel(letter)) {
      return letter;
    }
  }
  // need some distinguished value for when not found
  return null;
}

Checking for some

Return true if some element matches our criteria.

public boolean someVowels(String s) {
  for (int i = 0; i < s.length(); i++) {
    String letter = s.substring(i, i + 1);
    if (isVowel(letter)) {
      // Found one
      return true;
    }
  }
  // Didn't find any.
  return false;
}

Checking for all

Return true if all elements match our criteria.

public boolean allVowels(String s) {
  for (int i = 0; i < s.length(); i++) {
    String letter = s.substring(i, i + 1);
    if (!isVowel(letter)) {
      // Found counter example
      return false;
    }
  }
  // No counter examples found.
  return true;
}

Nested for loops

for (int i = 0; i < n; i++) {
  for (int j = 0; j < m; j++) {
    // something using both i and j
    // happens n * m times.
  }
}

Appendix: Reversing a string

Forwards

Traverse the string in normal order but accumulate the new value in reverse order by sticking each letter on the front of what we’ve accumulated.

public String reversed(String s) {
  String r = "";
  for (int i = 0; i < s.length(); i++) {
    r = s.substring(i, i + 1) + r;
  }
  return r;
}

Or

Traverse the string backwards and stick the letters on the end of the accumulator.

public String reversed(String s) {
  String r = "";
  for (int i = s.length() - 1; i >= 0; i--) {
    r += s.substring(i, i + 1);
  }
  return r;
}

Or

Run the loop forward but then pick out the characters from the end with a bit of math.

public String reversed(String s) {
  String r = "";
  for (int i = 0; i < s.length(); i++) {
    int idx = s.length() - 1 - i;
    r += s.substring(idx, idx + 1);
  }
  return r;
}

See also

Counting Loops Summary