Problem overview
The method legalAge takes an age and returns a Bool: true when the age is 18 or more, and false otherwise. The exercise asks you to write it in a single line, with no if or else.
Approach: the comparison already is the answer
The first version most people write looks like this:
func legalAge(_ age: Int) -> Bool {
if age >= 18 {
return true
} else {
return false
}
}
It works, but it says the same thing twice. The expression age >= 18 already has the value true when the age is legal and false when it is not. The if reads that value, then returns a hand-written copy of it. Returning the expression itself removes the middle step.
The rule is general. Whenever an if returns true in one branch and false in the other, return the condition. If the branches are swapped (false for the condition, true otherwise), return the opposite: !condition, or the opposite comparison.
Step by step
- Take the condition the
ifwould have tested:age >= 18. - Put
returnin front of it. The comparison produces aBool, which matches the declared return type. - Delete the rest. There are no branches, no braces and no literals
trueandfalseleft to write.
The solution in Swift
class Solution {
func legalAge(_ age: Int) -> Bool {
return age >= 18
}
}
Swift details worth knowing:
- A comparison is a value.
age >= 18is an expression of typeBool, just like3is an expression of typeInt. It can be returned, stored in a constant, as inlet adult = age >= 18, or passed to another function. - Return type. The signature says
-> Bool, so anything returned must be aBool. The comparison qualifies without conversion. - Calling it. After
let s = Solution(),s.legalAge(17)returnsfalse, and boths.legalAge(18)ands.legalAge(40)returntrue. - Single-expression functions. Swift also lets a function whose body is one expression leave out the word
return. The lesson keeps it, which is valid and explicit.
Reading the shortened code
A beginner sometimes worries that the short version hides the logic. It doesn't, if you read it aloud: "return whether the age is at least 18". The method answers a yes-or-no question, and the return value is that answer. The long version spells out the same sentence in two extra branches.
The same idea applies to combined conditions. A method that decides whether a number is a single digit could return n >= 0 && n <= 9 directly. Any expression built from comparisons, &&, || and ! is a Bool, so any of them can be returned or stored without an if.
Edge cases and common mistakes
- The boundary. The task says 18 or more, so
legalAge(18)istrue. Writingage > 18would reject exactly 18. - Redundant comparison with a Boolean. Code such as
return (age >= 18) == trueworks but adds noise. A Boolean value doesn't need to be compared withtrue. - Keeping the
if"to be safe". The long version and the short version behave identically for every input, so there is nothing to gain by keeping it. - Negative ages.
legalAge(-5)returnsfalse, since -5 is less than 18. The method does no validation. - When not to reduce. If a branch does more than return a Boolean, such as printing or computing a value, the
ifis needed.
Testing
legalAge(17)returnsfalse.legalAge(18)returnstrue.legalAge(40)returnstrue.legalAge(0)returnsfalse.
Key takeaways
- A comparison is an expression with a
Boolvalue, so you can return it directly. - An
ifthat returnstruein one branch andfalsein the other can always become a singlereturn. - Shorter code leaves fewer places for a mistake.
