检查 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")
}

作为奖励,您将获得未包装的值 ;)