I'm having trouble figuring out how to use optionals inside a tuple inside a switch. The below .Some(let ...) ... syntax works as non-tuple, but inside a tuple I get expected separator stuff :(
var dict = Dictionary<String,Bool>()
dict["a"] = true
switch (dict["a"],dict["b") {
case (.Some(let a) where !a, .Some(let b) where b):
println("false/nil, true")
case (.Some(let a) where a, .Some(let b) where !b):
println("true, false/nil")
I want to avoid doing the following
if let a = self.beaconList["a"] {
if let b = self.beaconList["b"] {
// a, b
} else {
// a, !b
}
} else {
if let b = self.beaconList["b"] {
// !a, b
} else {
// !a, !b
}
}
The accepted answer is out of date. So I rewrote it in Swift 5.
var dict = Dictionary<String,Bool>()
dict["a"] = true
dict["c"] = false
func matchOneOrTheOtherWithOptionals(_ a: Bool?, _ b: Bool?) -> String {
switch (a, b) {
case (.some(true), .none), (.some(true), .some(false)):
return "a was true, but b was None or false"
case (.none, .some(true)), (.some(false), .some(true)):
return "a was None or false and b was true"
default:
return "They both had a value, or they were both missing a value"
}
}
let xs: [Bool?] = [true, false, .none]
for a in xs {
for b in xs {
print("a = \(String(describing: a)), b=\(String(describing: b))")
print(matchOneOrTheOtherWithOptionals(a,b))
}
}
There are a bunch of ways to do this, but to fix the syntax of what you are trying to do literally, you need to explicitly unbox the Optional, either by matching against .Some(false), or unwrapping it with ! (which I think is kind of weird, as you'll see)
var dict = Dictionary<String,Bool>()
dict["a"] = true
dict["c"] = false
func matchOneOrTheOtherWithOptionals(a: Bool?, b: Bool?) -> String {
switch (a, b) {
case (.Some(true), let b) where b == .None || !b!: // gross
return "a was true, but b was None or false"
case (let a, .Some(true)) where a == .None || a == .Some(false):
return "a was None or false and b was true"
default:
return "They both had a value, or they were both missing a value"
}
}
matchOneOrTheOtherWithOptionals(true, .None) // "a was true, but b was None or false"
matchOneOrTheOtherWithOptionals(true, false) // "a was true, but b was None or false"
matchOneOrTheOtherWithOptionals(.None, true) // "a was None or false and b was true"
matchOneOrTheOtherWithOptionals(false, true) // "a was None or false and b was true"
matchOneOrTheOtherWithOptionals(false, false) // "They both had a value, or they were both missing a value"
matchOneOrTheOtherWithOptionals(true, true) // "They both had a value, or they were both missing a value"
matchOneOrTheOtherWithOptionals(.None, .None) // "They both had a value, or they were both missing a value"
You could also try the following:
func noneToFalse(bool: Bool?) -> Bool {
if let b = bool {
return b
} else {
return false
}
}
func matchOneOrTheOther(a: Bool, b: Bool) -> String {
switch (a, b) {
case (true, false):
return "a is true, b was false or None"
case (false, true):
return "a was false/None, b was true"
default:
return "both were true, or both were false/None"
}
}
matchOneOrTheOther(noneToFalse(dict["a"]), noneToFalse(dict["b"]))
Here's a gist of the Playground I used while writing this answer: https://gist.github.com/bgrace/b8928792760159ca58a1
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