簡體   English   中英

與數組匹配的 Swift 開關模式

[英]Swift switch pattern matching with arrays

好奇是否有辦法在 Swift 中執行以下操作。

let foo = [1, 2, 3]
let bar = [4, 5, 6]

let value = 5

switch value {
case in foo
    print("5 is in foo")
case in bar
    print("5 is in bar")
default:
    break
}

我知道還有其他方法可以使這個人為的示例工作,例如case 4, 5, 6:或者不使用 switch 而是使用bar.contains(value)但我正在尋找一個解決方案,專門涉及 switch 模式匹配一個數組。 謝謝!

怎么樣:

let foo = [1, 2, 3]
let bar = [4, 5, 6]

let value = 5

switch value {
case _ where foo.contains(value):
    print("\(value) is in foo")
case _ where bar.contains(value):
    print("\(value) is in bar")
default:
    print("\(value) is not in foo or bar")
}

您可以定義一個自定義模式匹配運算符~= ,它將數組作為“模式”和一個值:

func ~=<T : Equatable>(array: [T], value: T) -> Bool {
    return array.contains(value)
}

let foo = [1, 2, 3]
let bar = [4, 5, 6]

let value = 5

switch value {
case foo:
    print("\(value) is in foo")
case bar:
    print("\(value) is in bar")
default:
    break
}

類似的運算符已經存在,例如間隔:

public func ~=<I : IntervalType>(pattern: I, value: I.Bound) -> Bool

@Martin R 為什么停在數組上。 所有符合Sequence協議的類型都有一個contains實例方法。 以下與您的答案具有相同的行為,除了它適用於符合Sequence任何類型。

func ~=<S : Sequence>(sequence: S, value: S.Element) -> Bool
        where S.Element: Equatable {

    return sequence.contains(value)
}


let items = [1, 2, 3, 4, 5]
let iterable = items.makeIterator()

let value = 3

switch value {
    case iterable:
        print("\(value) is contained in iterable")
    default:
        print("\(value) is NOT contained in iterable")
}

然而,我們還可以做得更好

我認為case iterable了。 它沒有傳達這樣一個事實,即我們正在測試valueiterable的成員資格。 如果我們能寫case containedIn(iterable)會更好。 事實上,這實際上是可能的:

public func ~=<T>(pattern: (T) -> Bool, value: T) -> Bool {
    return pattern(value)
}

func containedIn<S : Sequence>(_ sequence: S) -> ((S.Element) -> Bool)
        where S.Element: Equatable {

    return { element in sequence.contains(element) }
}

let arrayOfNumbers = [1, 2, 3, 4, 5]
let setOfNumbers: Set = [5, 6, 7, 8, 9, 10]

let value = 8

switch value {
    case containedIn(arrayOfNumbers):
        print("\(value) is contained in arrayOfNumbers")
    case containedIn(setOfNumbers):
        print("\(value) is contained in setOfNumbers")
    default:
        break
}

與此唯一的問題是, containedIn使用switch語句的上下文之外時意外行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM