Copying the book’s code and adding this clause, string.rangeOfCharacter(from: letters) != nil, as a comma delimited argument (if _, _, _) this clause would be evaluated as an and statement. Essentially saying (if there is a decimal and a letter). This can never be true and so a return statement will never be issued. What we want to say is (if there is a decimal or a letter). In code this would look like this:
if (this || that) { }
Now, being the case that existingTextHasDecimalSeparator and replacementTextHasDecimalSeparator both check for decimals and both clauses are dependent these clauses must be grouped in an **and** statement. Also, being the case that string.rangeOfCharacter checks for letters this can be in added as an **or** statement. These clauses can all live on a single line as:
Notice the grouping by parenthesis. Your code with the extra else-if block accomplishes the same thing and works for this example. But in other examples it would work the same because if blocks don’t fallthrough.
This is very subtle and confusing. I recommend opening a playground and trying different combinations. Here are the ones that helped me:
if ((true && true) || false) {
print("test1")
}
if (true && false) {
print("test2")
}
if (true || false) {
print("test3")
}