Comparison Operators in Swift

In Swift, comparison operators are used to compare two values and return a Boolean result (true or false). These operators are essential for decision-making in control flow structures like if statements, while loops, or switch statements. Below, I'll explain the basic comparison operators in Swift, provide examples for each, and keep the explanations concise yet clear.

Comparison Operators in Swift

Swift supports the following comparison operators:

  1. Equal to (==): Checks if two values are equal.
  2. Not equal to (!=): Checks if two values are not equal.
  3. Greater than (>): Checks if the left value is greater than the right value.
  4. Less than (<): Checks if the left value is less than the right value.
  5. Greater than or equal to (>=): Checks if the left value is greater than or equal to the right value.
  6. Less than or equal to (<=): Checks if the left value is less than or equal to the right value.

Examples of Comparison Operators

Below are examples demonstrating each operator with different data types (integers, doubles, and strings). I'll use simple variables and print statements to show the results.

// Integer comparisons
let a = 10
let b = 5

// Equal to (==)
print(a == b) // false, because 10 is not equal to 5
print(a == 10) // true, because a is 10

// Not equal to (!=)
print(a != b) // true, because 10 is not equal to 5
print(b != 5) // false, because b is 5

// Greater than (>)
print(a > b) // true, because 10 is greater than 5
print(b > a) // false, because 5 is not greater than 10

// Less than (<)
print(a < b) // false, because 10 is not less than 5
print(b < a) // true, because 5 is less than 10

// Greater than or equal to (>=)
print(a >= b) // true, because 10 is greater than 5
print(a >= 10) // true, because a is equal to 10
print(b >= a) // false, because 5 is not greater than or equal to 10

// Less than or equal to (<=)
print(a <= b) // false, because 10 is not less than or equal to 5
print(b <= a) // true, because 5 is less than or equal to 10
print(b <= 5) // true, because b is equal to 5

Comparing Different Data Types

Swift allows comparison operators with compatible data types. For example, you can compare strings lexicographically (based on Unicode values) or floating-point numbers.

// String comparisons
let name1 = "Apple"
let name2 = "Banana"

print(name1 == name2) // false, because "Apple" is not equal to "Banana"
print(name1 != name2) // true, because they are different
print(name1 < name2) // true, because "Apple" comes before "Banana" lexicographically
print(name2 > name1) // true, because "Banana" comes after "Apple"

// Double comparisons
let x = 3.14
let y = 2.71

print(x > y) // true, because 3.14 is greater than 2.71
print(x <= y) // false, because 3.14 is not less than or equal to 2.71

Using Comparison Operators in Control Flow

let score = 85

if score >= 90 {
    print("Grade: A")
} else if score >= 80 {
    print("Grade: B") // This will print, because 85 is >= 80
} else if score >= 70 {
    print("Grade: C")
} else {
    print("Grade: F")
}

Key Notes

Practical Example: Checking Age Eligibility

let age = 18

if age >= 18 {
    print("You are eligible to vote.")
} else if age >= 16 && age < 18 {
    print("You can get a learner's permit.")
} else {
    print("You are not eligible for voting or driving.")
}
// Output: You are eligible to vote.

You can combine comparison operators with logical operators (&&, ||, !) for more complex conditions.

Best Practices for Using Comparison Operators in Swift

Ensure Type Compatibility

Swift is a strongly-typed language, so comparison operators require operands of the same or compatible types. Always verify that the types you’re comparing are compatible to avoid compiler errors.

let number = 42
let text = "42"
// print(number == text) // Error: Binary operator '==' cannot be applied to operands of type 'Int' and 'String'
if let convertedNumber = Int(text) {
    print(number == convertedNumber) // true
}

Use Descriptive Variable Names

Choose meaningful variable names to make comparisons self-explanatory, improving code readability and reducing errors.

// Poor naming
let x = 10
let y = 5
if x > y {
    print("x is greater")
}

// Better naming
let userAge = 10
let minimumAge = 5
if userAge > minimumAge {
    print("User is above the minimum age")
}

Combine with Logical Operators for Clarity

When combining comparison operators with logical operators (&&, ||, !), use parentheses to clarify precedence and improve readability.

let score = 85
let hasExtraCredit = true
if (score >= 80) && hasExtraCredit {
    print("Eligible for advanced placement")
}

Use Guard Statements for Early Exits

For comparisons that validate conditions early in a function, use guard statements to make code cleaner and avoid nested if blocks.

func checkEligibility(age: Int) {
    guard age >= 18 else {
        print("Not eligible to vote")
        return
    }
    print("Eligible to vote")
}
checkEligibility(age: 16) // Output: Not eligible to vote

Leverage Swift’s Optional Handling

When comparing optional values, use optional unwrapping or the nil-coalescing operator (??) to handle nil cases safely.

let optionalValue: Int? = 10
let defaultValue = 5
if let value = optionalValue {
    print(value > defaultValue) // true
} else {
    print("No value to compare")
}
// Or use nil-coalescing
print((optionalValue ?? 0) > defaultValue) // true

Use Enums for Semantic Comparisons

For complex comparisons, consider using Swift enums to make comparisons more meaningful and type-safe.

enum UserRole {
    case guest, member, admin
}
let user = UserRole.admin
if user == .admin {
    print("Access granted to admin panel")
}

Limitations of Comparison Operators in Swift

Type Restrictions

Comparison operators (>, <, >=, <=) are not universally applicable to all types. For example, you cannot use them with custom structs or classes unless you conform to the Comparable protocol.

struct Person {
    let age: Int
}
let alice = Person(age: 30)
let bob = Person(age: 25)
// print(alice > bob) // Error: Binary operator '>' cannot be applied to two 'Person' operands

struct Person2: Comparable {
    let age: Int
    static func < (lhs: Person2, rhs: Person2) -> Bool {
        return lhs.age < rhs.age
    }
    static func == (lhs: Person2, rhs: Person2) -> Bool {
        return lhs.age == rhs.age
    }
}
let a1 = Person2(age: 30)
let b1 = Person2(age: 25)
print(a1 > b1) // true

Floating-Point Precision Issues

Comparing floating-point numbers (Double, Float) can lead to unexpected results due to precision limitations.

let a = 0.1 + 0.2
let b = 0.3
print(a == b) // false

let epsilon = 0.0001
print(abs(a - b) < epsilon) // true

String Comparison Sensitivity

String comparisons are case-sensitive and based on Unicode values, which may not align with user expectations.

let str1 = "apple"
let str2 = "Apple"
print(str1 == str2) // false
print(str1.lowercased() == str2.lowercased()) // true

Optional Comparisons

Comparing optionals directly with non-optionals or other optionals can lead to errors unless handled properly.

let optionalInt: Int? = 5
// print(optionalInt > 3) // Error
if let value = optionalInt, value > 3 {
    print("Value is greater than 3")
}

Tips to Avoid Common Mistakes

Avoid Direct Floating-Point Equality Checks

let x = 0.1 + 0.2
let y = 0.3
if abs(x - y) < 0.0001 {
    print("Values are approximately equal")
}

Test Edge Cases

let temperature = 0
if temperature >= 0 {
    print("Non-negative temperature")
} else {
    print("Negative temperature")
}

Use Type Inference Wisely

let intValue: Int = 10
let doubleValue: Double = 10.0
print(Double(intValue) == doubleValue) // true

Handle Optionals Explicitly

let optionalScore: Int? = nil
let defaultScore = 0
let scoreToUse = optionalScore ?? defaultScore
print(scoreToUse >= 50) // false

Use Swift’s Pattern Matching for Complex Comparisons

let grade = 85
switch grade {
case 90...100:
    print("A")
case 80..<90:
    print("B")
default:
    print("C or below")
}

Profile and Test Performance

func someComplexCalculation() -> Int { return 1 }
let result = someComplexCalculation()
for _ in 0..<100 {
    if result > 0 {
        print("Positive")
    }
}

Use Comments for Complex Logic

let userAge = 17
let hasParentalConsent = true
// Check if user can access content: must be 18 or have parental consent if 13-17
if userAge >= 18 || (userAge >= 13 && hasParentalConsent) {
    print("Access granted")
}

Practice Exercise: Comparison Operators with Arithmetic

Question: Create a Swift program that checks the following conditions using variables and arithmetic operators:

let num1 = 10
let num2 = 5
let total = num1 + num2

print(total > 12)    // Check if total is greater than 12
print(total == 15)   // Check if total is equal to 15
print((num1 - num2) <= 6)  // Check if difference is less than or equal to 6

Expected Output:

true
true
true

Explanation: total is 15, so total > 12 is true, total == 15 is true, and (num1 - num2) <= 6 is true.