检查 Swift 3 或 4 中的 if 条件矩阵
Checking for a matrix of if conditions in Swift 3 or 4
假设我有一个需要检查的条件矩阵:
let one: String? = "one"
let two: String? = nil
func test() {
if one == nil && two == nil {
print("neither are valid")
} else if one == nil {
print("one is nil")
} else if (two == nil) {
print("two is nil")
} else {
print("\(one) and \(two) are valid")
}
}
有没有 Swift 语言的功能可以让我写得更干净 "Swift-like"?相同的语法是否可以很好地扩展到一组三维条件?
我知道使用 guard
,我可以在继续之前检查两个值是否有效,但随后我需要根据一个、两个或两者是否为零来执行某些操作,并且 这显然会导致一些误报(守卫希望在继续之前两者都有效):
guard let one = one, let two = two else {
return
}
if one == nil {
print("one is nil")
} else if (two == nil) {
print("two is nil")
} else {
print("\(one) and \(two) are valid")
}
我确定我也可以使用 switch
,但这似乎并不比无穷无尽的 if/else:
更优雅
switch (one != nil || two != nil) {
case one == nil && two == nil:
print("neither are valid")
case one == nil:
print("one is nil")
case two == nil:
print("two is nil")
default:
print("\(one) and \(two) are valid")
}
这就是我所做的,我认为它非常迅速并且可以扩展以处理任意数量的字符串:
let string1: String? = "A"
let string2: String? = "B"
let string3: String? = "C"
let validStrings = [string1, string2, string3].flatMap { [=10=] }
switch validStrings.count {
case 0:
print("No valid strings")
case 1:
print(validStrings[0] + " is valid")
case _:
let comaSeparated = validStrings[0..<validStrings.count - 1].joined(separator: ", ")
let lastValue = validStrings[validStrings.count - 1]
print([comaSeparated, lastValue].joined(separator: " and ") + " are valid")
}
首先你使用flatMap
得到一个只有非nil字符串的数组,然后使用一个switch并处理三种情况:没有有效字符串、一个有效字符串、两个或更多有效字符串。
在最后一个案例中,我们使用 joined()
两次以使其更易于阅读。
最后,如果所有字符串都不是 nil,就像示例中那样,您将得到:
A, B and C are valid
随便贴在游乐场。
您可以这样使用 Swift switch
:
switch (one, two) {
case (nil, nil):
print("neither are valid")
case (nil, _?):
print("one is nil")
case (_?, nil):
print("two is nil")
default:
print("\(one) and \(two) are valid")
}
你可以使用类似的东西:
enum TwoCondition<L, R> {
case leftNil(R)
case rightNil(L)
case bothNil
case passed(L, R)
static func check(_ l: L?, _ r: R?) -> TwoCondition<L,R> {
if let l = l, let r = r { return .passed(l, r) }
if let l = l { return .rightNil(l) }
if let r = r { return .leftNil(r) }
return .bothNil
}
}
然后您可以检查任何可选值:
let one: String? = "one"
let two: String? = nil
switch TwoCondition.check(one, two) {
case .leftNil(let r):
print("one is nil, two is: \(r)")
case .rightNil(let l):
print("two is nil, one is: \(l)")
case .bothNil:
print("neither are valid")
case .passed(let l, let r):
print("\(l) and \(r) are valid")
}
作为奖励,您将获得未包装的值 ;)
假设我有一个需要检查的条件矩阵:
let one: String? = "one"
let two: String? = nil
func test() {
if one == nil && two == nil {
print("neither are valid")
} else if one == nil {
print("one is nil")
} else if (two == nil) {
print("two is nil")
} else {
print("\(one) and \(two) are valid")
}
}
有没有 Swift 语言的功能可以让我写得更干净 "Swift-like"?相同的语法是否可以很好地扩展到一组三维条件?
我知道使用 guard
,我可以在继续之前检查两个值是否有效,但随后我需要根据一个、两个或两者是否为零来执行某些操作,并且 这显然会导致一些误报(守卫希望在继续之前两者都有效):
guard let one = one, let two = two else {
return
}
if one == nil {
print("one is nil")
} else if (two == nil) {
print("two is nil")
} else {
print("\(one) and \(two) are valid")
}
我确定我也可以使用 switch
,但这似乎并不比无穷无尽的 if/else:
switch (one != nil || two != nil) {
case one == nil && two == nil:
print("neither are valid")
case one == nil:
print("one is nil")
case two == nil:
print("two is nil")
default:
print("\(one) and \(two) are valid")
}
这就是我所做的,我认为它非常迅速并且可以扩展以处理任意数量的字符串:
let string1: String? = "A"
let string2: String? = "B"
let string3: String? = "C"
let validStrings = [string1, string2, string3].flatMap { [=10=] }
switch validStrings.count {
case 0:
print("No valid strings")
case 1:
print(validStrings[0] + " is valid")
case _:
let comaSeparated = validStrings[0..<validStrings.count - 1].joined(separator: ", ")
let lastValue = validStrings[validStrings.count - 1]
print([comaSeparated, lastValue].joined(separator: " and ") + " are valid")
}
首先你使用flatMap
得到一个只有非nil字符串的数组,然后使用一个switch并处理三种情况:没有有效字符串、一个有效字符串、两个或更多有效字符串。
在最后一个案例中,我们使用 joined()
两次以使其更易于阅读。
最后,如果所有字符串都不是 nil,就像示例中那样,您将得到:
A, B and C are valid
随便贴在游乐场。
您可以这样使用 Swift switch
:
switch (one, two) {
case (nil, nil):
print("neither are valid")
case (nil, _?):
print("one is nil")
case (_?, nil):
print("two is nil")
default:
print("\(one) and \(two) are valid")
}
你可以使用类似的东西:
enum TwoCondition<L, R> {
case leftNil(R)
case rightNil(L)
case bothNil
case passed(L, R)
static func check(_ l: L?, _ r: R?) -> TwoCondition<L,R> {
if let l = l, let r = r { return .passed(l, r) }
if let l = l { return .rightNil(l) }
if let r = r { return .leftNil(r) }
return .bothNil
}
}
然后您可以检查任何可选值:
let one: String? = "one"
let two: String? = nil
switch TwoCondition.check(one, two) {
case .leftNil(let r):
print("one is nil, two is: \(r)")
case .rightNil(let l):
print("two is nil, one is: \(l)")
case .bothNil:
print("neither are valid")
case .passed(let l, let r):
print("\(l) and \(r) are valid")
}
作为奖励,您将获得未包装的值 ;)