= Solution
Make two separate character <iterators> so that scanning uppercase letters does not consume the lowercase pass:
``
def upperLower(s: String): Iterator[Char] = {
val upper = new FilterIterator[Char]((c: Char) => c.isUpper, s.iterator)
val lower = new FilterIterator[Char]((c: Char) => c.isLower, s.iterator)
new ConcatIterator[Char](upper, lower)
}
``
Each filtering <iterator> preserves the original order of its selected characters. Concatenation therefore yields \b[all uppercase letters in source order, then all lowercase letters in source order], omitting other characters. The two `s.iterator` calls are essential: reusing a single consuming <iterator> would let the first pass discard lowercase characters before the second pass could return them. Construction remains lazy; an empty <string> yields an exhausted <iterator> without a special case.
Back to article page