Menu
Coddy logo textTech

Comparable

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 39 מתוך 57.

Comparable מעניק לטיפוס את האופרטורים <, <=, > ו->=. מממשים רק את <; Swift גוזרת את השאר. אפשר למיין טיפוסים תואמי Comparable באמצעות sorted() ולהשתמש בהם עם min() ו-max():

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

פלט:

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

השוואה בין tuples משווה את החלקים שלהם לפי הסדר, וכך ניתן לכתוב השוואות לפי כמה מפתחות בקיצור. כאן המשימות ממוינות קודם לפי עדיפות ואז לפי שם:

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 })

פלט:

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

מקרים של enum ללא ערכים משויכים יכולים להתאים לפרוטוקול Comparable בלי לכתוב את <: המקרים מושווים לפי סדר ההכרזה שלהם:

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

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

פלט:

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

sorted(by:) ממיין לפי כל כלל עבור קריאה אחת, ואילו Comparable מגדיר את הסדר הטבעי של הטיפוס, שבו משתמשים sorted(), min() ו-max() בכל מקום:

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 })

פלט:

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

אתגר

קל

גרום ל־Runner (שם וזמן סיום בתור minutes, seconds) להתאים ל־Comparable, כך שזמן מהיר יותר יהיה קטן יותר, ובמקרה של זמנים שווים הסדר ייקבע לפי השם. השלם את podium(_:), שממיינת את הרצים באמצעות sorted() ומחזירה שורות בפורמט 1. Ada 20:05 עבור שלושת הראשונים (פחות אם יש פחות רצים), כאשר השניות מרופדות לשתי ספרות.

הקוד שסופק קורא שורות בפורמט name,mm:ss ומדפיס כל שורה שמוחזרת.

הקוד שלך צריך להיות ב־Runner.swift וב־Functions.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.

נסו בעצמכם

// קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
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 iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: Swift אונליין