Checking optional isEqualToString

3.6k Views Asked by At

I have a case where I want to check if an optional I have is Equal to a string. First I have to unwrap it to check if it exists, then I want to check if it is equal to another string. However that gives me a problem where I have to write the same code twice. I'll give you an example:

    var person : Person = Person()

    if let name = person.name {
        if name.isEqualToString("John") {
            println("Hello, John!")
        }
        else {
            println("Wait a minute, you're not John!")
    }
    else {
        println("Wait a minute, you're not John!")
    }

As you can see, I have to write the else statement twice. Once, if the name exists and it is not 'John', and another time for when the name does not exist.

My question is, how can this be done the proper way.

Thanks for your help!

3

There are 3 best solutions below

4
On BEST ANSWER

Optional has an == operator defined for it in the Swift standard library:

func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

That means if the optional contains a value that’s equatable, you can compare two optionals. If the two optionals are both nil they’re equal, and if the two optionals wrap values that are equal, then they’re equal.

So if you don’t care about whether person.name is nil or not, just whether it contains a value of "John", you can just write if person.name == "John".

How does that work, when "John" is a String not a String??* Because Swift will implicitly convert any type to an optional wrapping that type if that’s what an argument requires. So because the == function for comparing optionals requires a String? argument, “John” will be implicitly converted to {Some "John"}, allowing the == operator between two optionals to be used.

* well actually "John” isn't a String either, it’s a string literal that is getting converted into a String

1
On
var person : Person = Person()
let name = person.name
if (name != nil && name! == "John")
{
    println("Hello, John!")
}
else
{
    println("Wait a minute, you're not John!")
}
0
On

Since you are testing for three different conditions, correct value, incorrect value, or no value, there will be some amount of duplication.

This can be minimized by extracting the duplication into a new method, such as:

func notJohn() {
    println("Wait a minute, you're not John!")
}

if let name = person.name {
    if (name == "John") {
        println("Hello, John")
    } else {
        notJohn()
    }
} else {
    notJohn()
}