Menu
Coddy logo textTech

Comparable

Teil des Abschnitts Objektorientierte Programmierung der Swift-Journey von Coddy. Lektion 39 von 57.

Comparable verleiht einem Typ die Operatoren <, <=, > und >=. Du implementierst nur <; Swift leitet den Rest ab. Comparable-Typen können mit sorted() sortiert und mit min() und max() verwendet werden:

struct Version: Comparable {
    let major: Int, minor: Int

    static func < (lhs: Version, rhs: Version) -> Bool {
        (lhs.major, lhs.minor) < (rhs.major, rhs.minor)
    }
}

let versions = [Version(major: 2, minor: 1), Version(major: 1, minor: 9), Version(major: 2, minor: 0)]
let newest = versions.max()!
print("\(newest.major).\(newest.minor)")
print(versions.sorted().map { "\($0.major).\($0.minor)" })

Ausgabe:

2.1
["1.9", "2.0", "2.1"]

Beim Vergleichen von Tupeln werden ihre Bestandteile der Reihe nach verglichen, wodurch Vergleiche mit mehreren Schlüsseln kurz ausfallen. Hier werden die Aufgaben zuerst nach Priorität und anschließend nach Namen sortiert:

struct Task: Comparable {
    let priority: Int
    let name: String

    static func < (lhs: Task, rhs: Task) -> Bool {
        (lhs.priority, lhs.name) < (rhs.priority, rhs.name)
    }
}

let tasks = [Task(priority: 2, name: "email"), Task(priority: 1, name: "fix"), Task(priority: 2, name: "call")]
print(tasks.sorted().map { $0.name })

Ausgabe:

["fix", "call", "email"]

Enums ohne zugehörige Werte können Comparable entsprechen, ohne < zu schreiben: Die Fälle werden in der Reihenfolge verglichen, in der sie deklariert sind:

enum Priority: Comparable {
    case low, medium, high
}

print(Priority.low < Priority.high)
print([Priority.high, .low, .medium].sorted())

Ausgabe:

true
[main.Priority.low, main.Priority.medium, main.Priority.high]

sorted(by:) sortiert bei einem einzelnen Aufruf nach einer beliebigen Regel, während Comparable die natürliche Reihenfolge des Typs definiert, die sorted(), min() und max() überall verwenden:

struct Task: Comparable {
    let priority: Int
    let name: String
    static func < (lhs: Task, rhs: Task) -> Bool { lhs.priority < rhs.priority }
}

let tasks = [Task(priority: 3, name: "c"), Task(priority: 1, name: "a")]
print(tasks.sorted().map { $0.name })
print(tasks.sorted(by: >).map { $0.name })

Ausgabe:

["a", "c"]
["c", "a"]
challenge icon

Aufgabe

Einfach

Lasse Runner (Name und Endzeit als minutes, seconds) Comparable entsprechen, wobei eine schnellere Zeit kleiner ist und gleiche Zeiten nach dem Namen geordnet werden. Vervollständige podium(_:), das die Läufer mit sorted() sortiert und für die ersten drei Läufer (weniger, falls es weniger Läufer gibt) Zeilen im Format 1. Ada 20:05 zurückgibt, wobei die Sekunden auf zwei Ziffern aufgefüllt werden.

Der bereitgestellte Code liest Zeilen im Format name,mm:ss ein und gibt jede zurückgegebene Zeile aus.

Dein Code gehört in Runner.swift und Functions.swift. main.swift enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

// Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
var input: [String] = []
while let line = readLine() { input.append(line) }
let runners = input.map { line -> Runner in
    let p = line.split(separator: ",").map(String.init)
    let t = p[1].split(separator: ":").map { Int($0)! }
    return Runner(name: p[0], minutes: t[0], seconds: t[1])
}
for line in podium(runners) { print(line) }
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Swift-Playground