Say I had the below api :
func paths() -> [String?] {
return ["test", nil, "Two"]
}
And I was using this in a method where I needed [String]
, hence I had to unwrap it using the simple map
function. I'm currently doing :
func cleanPaths() -> [String] {
return paths.map({$0 as! String})
}
Here, the force-cast will cause an error. So technically I need to unwrap the Strings in the paths
array. I'm having some trouble doing this and seem to be getting silly errors. Can someone help me out here?
Map over an optional when the closure returns a non-optional and nil is never needed. Flat map over an optional when the closure could return nil . Whether you map or flat map over an optional, the return value is always an optional.
In if let , the defined let variables are available within the scope of that if condition but not in else condition or even below that. In guard let , the defined let variables are not available in the else condition but after that, it's available throughout till the function ends or anything.
If you defined a variable as optional, then to get the value from this variable, you will have to unwrap it. This just means putting an exclamation mark at the end of the variable. Optional("Hello, Swift 4!")
You must unwrap the value of an Optional instance before you can use it in many contexts. Because Swift provides several ways to safely unwrap optional values, you can choose the one that helps you write clear, concise code. The following examples use this dictionary of image names and file paths:
You can declare optional variables using an exclamation mark instead of a question mark. Such optional variables will unwrap automatically and you do not need to use any further exclamation mark at the end of the variable to get the assigned value. var mycodetipsString:String! mycodetipsString = "Hello, Swift !"
The only way to find out is to unwrap it. An implicitly unwrapped optional might contain a value, or might not. But it does not need to be unwrapped before it is used. Swift won’t check for you, so you need to be extra careful. Example: String! might contain a string, or it might contain nil – and it’s down to you to use it appropriately.
If you know that an optional definitely has a value, you can force unwrap it by placing this exclamation mark after it. If you defined a variable as optional, then to get the value from this variable, you will have to unwrap it. Putting an exclamation mark at the end of the variable.
compactMap()
can do this for you in one step:
let paths:[String?] = ["test", nil, "Two"]
let nonOptionals = paths.compactMap{$0}
nonOptionals
will now be a String array containing ["test", "Two"]
.
Previously flatMap()
was the proper solution, but has been deprecated for this purpose in Swift 4.1
You should filter first, and map next:
return paths.filter { $0 != .None }.map { $0 as! String }
but using flatMap
as suggested by @BradLarson is a just better
Perhaps what you want to is a filter
followed by a map
:
func cleanPaths() -> [String] {
return paths()
.filter {$0 != nil}
.map {$0 as String!}
}
let x = cleanPaths()
println(x) // ["test", "two"]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With