# switch on other types

[Swift](../..) ⟩ [Pattern Matching](..) ⟩ [Sentence Patterns]() ⟩

{% tabs %}
{% tab title="tuple" %}
```swift
// CGPoint
let point = CGPoint(x: 7, y: 0)

// switch on Tuple
switch (point.x, point.y) {
    case (0, 0): print("On the origin!")
    case (0, _): print("x=0: on Y-axis!")
    case (_, 0): print("y=0: on X-axis!")
    case let (x, y) where x == y: 
        print("On y = x")
    default: 
        print("Quite a random point here.")
}
```
{% endtab %}

{% tab title="range" %}
```swift
// Range<Int>
switch count {
    case Int.min..<0: print("Negative count, really?")
    case 0     : print("Nothing")
    case 1     : print("One")
    case 2..<5 : print("A few")  // use `2..<5 ~= count` behind the scene
    case 5..<10: print("Some")
    default    : print("Many")
}

// 
switch char {
    case 
        "A", "E", "I", "O", "U", "Y", 
        "a", "e", "i", "o", "u", "y": // ...
    case 
        "A"..."Z", 
        "a"..."z": // ...
    
    default: // ...
}
```
{% endtab %}

{% tab title="optional" %}
{% hint style="info" %}
the following cases are equivalent:

```swift
// match on constant
case 2? == case .some(2)
```

👉 比較： [switch-case](switch-case "mention")
{% endhint %}

```swift
let optionalN: Int? = 2

switch optionalN {
    case 0? : print("Zero")
    case 1? : print("One")
    case 2? : print("Two")
    case nil: print("None")    // == case .none
    default : print("Other")
}
```
{% endtab %}

{% tab title="custom" %}
💾 程式： [replit](https://replit.com/@pegasusroe/Pattern-Matching-on-custom-type#main.swift)

```swift
// ------------
//     Mod
// ------------

/// equivalent classes
struct Mod {
  let mod: Int  // quotient
  let rem: Int  // remainder
}

extension Mod {
    init(_ q: Int, _ r: Int){
        mod = q
        rem = r
    }
}

// -----------------------------
//     ⭐ custom operator ~=
// -----------------------------

/// usage: `Mod(3, 1) ~= 4`
func ~= (pattern: Mod, value: Int) -> Bool {
  return value % pattern.mod == pattern.rem
}

// ------------
//     Book
// ------------

struct Book {
    let title : String
    let author: String
    let year  : Int
}

// -----------------------------
//     ⭐ custom operator ~=
// -----------------------------

/// usage: `1960 ..< 2020 ~= book`
func ~= (yearRange: Range<Int>, book: Book) -> Bool {
    return yearRange ~= book.year
}


// ------------
//     main
// ------------

// switch on `Int`
//     ↱ 1. the `value` ⭐ 
switch 5 {

    // ⭐ custom pattern matching
    //   ╭── 2 ──╮
    case Mod(2, 0): print("2n")         // 2. the `pattern` ⭐ 
    case Mod(3, 1): print("3n+1")
    case Mod(3, 2): print("3n+2")       // 3n+2

    // ⭐ `default` is always required on custom types
    default: print("other kind of number")
}

// Book
let book = Book(
    title : "20,000 leagues under the sea", 
    author: "Jules Vernes", 
    year  : 1870
)

// switch on `Book`
//       ↱ 1. the `value` ⭐ 
switch book {
    //   ╭──── 2 ────╮                          // 2. the `pattern` ⭐
    case 1800 ..< 1900: print("19th century")   // 19th century
    case 1900 ..< 2000: print("20th century")
    default: print("Other century")
}
```
{% endtab %}

{% tab title="📗 參考" %}
* AliSoftware ⟩ Pattern Matching&#x20;
  * [x] [Part 1: switch, enums & where clauses](https://alisoftware.github.io/swift/pattern-matching/2016/03/27/pattern-matching-1/)
  * [x] [Part 2: tuples, ranges & types](https://alisoftware.github.io/swift/pattern-matching/2016/03/30/pattern-matching-2/) ⭐️
  * [ ] [Part 3: Custom pattern matching & syntactic sugar](https://alisoftware.github.io/swift/pattern-matching/2016/04/24/pattern-matching-3/) ⭐️ (有模糊比對文字的例子)
  * [ ] [Part 4: if case, guard case, for case](https://alisoftware.github.io/swift/pattern-matching/2016/05/16/pattern-matching-4/)&#x20;
{% endtab %}

{% tab title="👥 相關" %}
* [operator](../operator "mention") - pattern matching operator.
{% endtab %}
{% endtabs %}
