Home > Back-end >  How to use OR for a value that can be nil?
How to use OR for a value that can be nil?

Time:09-29

This is very basic but I'm kinda confused why my code isn't working. I have a user that has an optional username and I am trying to check whether the email or username contains my search query

struct ChatUser: Codable, Identifiable {
let email: String    
var username: String?
}

@State var user: ChatUser

if user.email.lowercased().contains(search.lowercased()) || 
user.username.lowercased().contains(search.lowercased()) {...}

It works if I unwrap user.username! but then my App crashes due to unwrapping nil values. How do I check for user.username != nil and then force unwrap in the if check?

CodePudding user response:

Calling lowercased() again and again is unnecessarily expensive.

But with your given syntax this is the swifty way

if user.email.lowercased().contains(search.lowercased()) || 
   user.username?.lowercased().contains(search.lowercased()) == true {...}

The Optional Chaining expression returns nil immediately if username is nil.

However range(of:options: can handle the optional and the case

if user.email.range(of: search, options: .caseInsensitive) != nil ||
    user.username?.range(of: search, options: .caseInsensitive) != nil {

}

CodePudding user response:

You can use nil-coalescing(??) to unwrap your optional value.

if user.email.lowercased().contains(search.lowercased()) || 
user.username?.lowercased().contains(search.lowercased()) ?? false {

}

CodePudding user response:

if user.email.lowercased().contains(search.lowercased()) || 
(user.username.map { $0.lowercased().contains(search.lowercased()) } ?? false) {

}
  • Related