Checking optional isEqualToString
Asked Answered
N

3

5

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!

Nagaland answered 20/12, 2014 at 0:21 Comment(0)
B
9

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

Backler answered 20/12, 2014 at 1:12 Comment(4)
P.S. is there ever a reason to use .isEqualToString instead of == in this case? I can’t think of one but maybe I’m missing something. == should work with either NSString or String (or a string literal) on either side.Backler
Thank you for your reply. This works, but only if the person.name has been set. If the name has not been set, I get the warning "unexpectedly found nil while unwrapping an Optional value". I have cases where the name has not been set, so to sum it up I want to check if it is "John" and not nil.Nagaland
Even if name is not set you should be able to use the ==. Checking it is equal to John should be sufficient to also confirm it’s not nil. For example run this in a playground: let s: NSString? = nil; s == “John” // returns false, no error. Are you sure there isn’t some other part of the statement getting force-unwrapped, might there be an as in there?Backler
Yes, you are correct! After playing around with it I got it to work. This is what I ended up with, and it seems to work very well: var person : Person = Person() let name : String? = person.name if name == "John" { println("Hello, \(name!)") } else { println("Wait a minute, you're not John!") } Thank you very much for your help.Nagaland
B
1
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!")
}
Baran answered 20/12, 2014 at 0:33 Comment(1)
Thanks for your reply. This still throws me the error: "unexpectedly found nil while unwrapping an Optional value". This type of code used to work in objective C, but in swift it really does not like to check if something is not nil. Am I missing something?Nagaland
W
0

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()
}
Wintertide answered 20/12, 2014 at 0:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.