I would like to know if anyone has a more elegant way to check if either of the values in a Tuple are Nil in Swift?
我想知道是否有人有一种更优雅的方式来检查一个元组中的任何一个值在Swift中是否为Nil?
Currently I'm checking like this:
目前我正在检查这样:
var credentials = CredentialHelper.getCredentials() //returns a tuple of two Optional Strings.
if (credentials.username == nil || credentials.password == nil)
{
//continue doing work.
}
I would like something more succinct, if possible.
如果可能的话,我想要更简洁的东西。
2 个解决方案
#1
5
You can do it with a switch case on the tuple values. For example:
您可以使用元组值上的开关案例来完成此操作。例如:
func testTuple(input: (String?, String?)) -> String {
switch input {
case (_, .None), (.None, _):
return "One or the other is nil"
case (.Some(let a), _):
return "a is \(a)"
case (_, .Some(let b)):
return "b is \(b)"
}
}
testTuple((nil, "B")) // "One or the other is nil"
testTuple(("A", nil)) // "One or the other is nil"
testTuple(("A", "B")) // "a is A"
testTuple((nil, nil)) // "One or the other is nil"
The trick is to use let bindings on the tuple values.
诀窍是对元组值使用let绑定。
#2
0
@Abizern nailed it for cases when you need the whole power of if case let
. There're situations when you don't, for example, with mapping optionals or using ReactiveCocoa, in which case good old casting comes to help, especially when you need all values and tuples aren't particularly long:
@Abizern为你需要if case let的全部功能的情况下钉了它。例如,在某些情况下,您没有使用映射选项或使用ReactiveCocoa,在这种情况下,良好的旧版本会有所帮助,尤其是当您需要所有值并且元组不是特别长时:
import ReactiveCocoa
import ReactiveSwift
typealias Credentials = (u: String?, p: String?)
var notification = Notification.Name("didReceiveCredentials")
var c1: Credentials? = ("foo", "bar")
var c2: Credentials? = ("foo", nil)
print("cast:", c1.flatMap({ $0 as? (String, String) }))
print("cast:", c2.flatMap({ $0 as? (String, String) }))
if let (u, p) = c1 as? (String, String) { print("if:", u, p) }
if let (u, p) = c2 as? (String, String) { print("if:", u, p) }
NotificationCenter.default.reactive.notifications(forName: notification)
.filterMap({ $0.object as? Credentials })
.filterMap({ $0 as? (String, String) })
.observeValues({ print("signal:", $0) })
NotificationCenter.default.post(name: notification, object: c1)
NotificationCenter.default.post(name: notification, object: c2)
#1
5
You can do it with a switch case on the tuple values. For example:
您可以使用元组值上的开关案例来完成此操作。例如:
func testTuple(input: (String?, String?)) -> String {
switch input {
case (_, .None), (.None, _):
return "One or the other is nil"
case (.Some(let a), _):
return "a is \(a)"
case (_, .Some(let b)):
return "b is \(b)"
}
}
testTuple((nil, "B")) // "One or the other is nil"
testTuple(("A", nil)) // "One or the other is nil"
testTuple(("A", "B")) // "a is A"
testTuple((nil, nil)) // "One or the other is nil"
The trick is to use let bindings on the tuple values.
诀窍是对元组值使用let绑定。
#2
0
@Abizern nailed it for cases when you need the whole power of if case let
. There're situations when you don't, for example, with mapping optionals or using ReactiveCocoa, in which case good old casting comes to help, especially when you need all values and tuples aren't particularly long:
@Abizern为你需要if case let的全部功能的情况下钉了它。例如,在某些情况下,您没有使用映射选项或使用ReactiveCocoa,在这种情况下,良好的旧版本会有所帮助,尤其是当您需要所有值并且元组不是特别长时:
import ReactiveCocoa
import ReactiveSwift
typealias Credentials = (u: String?, p: String?)
var notification = Notification.Name("didReceiveCredentials")
var c1: Credentials? = ("foo", "bar")
var c2: Credentials? = ("foo", nil)
print("cast:", c1.flatMap({ $0 as? (String, String) }))
print("cast:", c2.flatMap({ $0 as? (String, String) }))
if let (u, p) = c1 as? (String, String) { print("if:", u, p) }
if let (u, p) = c2 as? (String, String) { print("if:", u, p) }
NotificationCenter.default.reactive.notifications(forName: notification)
.filterMap({ $0.object as? Credentials })
.filterMap({ $0 as? (String, String) })
.observeValues({ print("signal:", $0) })
NotificationCenter.default.post(name: notification, object: c1)
NotificationCenter.default.post(name: notification, object: c2)