Menu
Coddy logo textTech

Equatable

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

Equatable מעניק לטיפוס את האופרטורים == ו־!=. עבור מבנים ומנייתים שכל המאפיינים שלהם הם Equatable, מספיק להצהיר על ההתאמה, ו־Swift משווה כל מאפיין:

struct Card: Equatable {
    let rank: Int
    let suit: String
}

let a = Card(rank: 10, suit: "hearts")
let b = Card(rank: 10, suit: "hearts")
print(a == b)
print(a != Card(rank: 2, suit: "hearts"))

פלט:

true
true

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

struct User: Equatable {
    let id: Int
    var name: String

    static func == (lhs: User, rhs: User) -> Bool {
        lhs.id == rhs.id
    }
}

print(User(id: 1, name: "Ada") == User(id: 1, name: "Ada L."))
print(User(id: 1, name: "Ada") == User(id: 2, name: "Ada"))

פלט:

true
false

Equatable מאפשרת להשתמש בשיטות סטנדרטיות שדורשות השוואה, כגון contains(_:), firstIndex(of:) ו-== על מערכים שלמים:

struct Point: Equatable {
    let x: Int, y: Int
}

let path = [Point(x: 0, y: 0), Point(x: 1, y: 2)]
print(path.contains(Point(x: 1, y: 2)))
print(path.firstIndex(of: Point(x: 1, y: 2))!)
print(path == [Point(x: 0, y: 0), Point(x: 1, y: 2)])

פלט:

true
1
true

מחלקות אינן מקבלות == בחינם: הן משוות לפי זהות באמצעות ===. מחלקה שאמורה להשוות לפי ערך חייבת לממש בעצמה את ==:

class Color: Equatable {
    let hex: String
    init(hex: String) { self.hex = hex }
    static func == (lhs: Color, rhs: Color) -> Bool { lhs.hex == rhs.hex }
}
challenge icon

אתגר

קל

ל־Product יש sku,‏ name ו־price. שני מוצרים זהים כאשר ערכי sku שלהם תואמים, בלי קשר לערכים בשדות האחרים. יש להתאים את Product לפרוטוקול Equatable עם מימוש מותאם אישית של ==, ואז להשלים את mergeCatalog(_:), ששומרת את ההופעה הראשונה של כל מוצר (באמצעות contains) ומחזירה שורות בפורמט sku name price ואחריהן removed: 2.

הקוד שסופק קורא את המוצרים כשורות בפורמט sku,name,price ומדפיס כל שורה שהוחזרה.

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

נסו בעצמכם

// קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var input: [String] = []
while let line = readLine() { input.append(line) }
let products = input.map { line -> Product in
    let p = line.split(separator: ",").map(String.init)
    return Product(sku: p[0], name: p[1], price: Int(p[2])!)
}
for line in mergeCatalog(products) { print(line) }
quiz iconבחנו את עצמכם

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

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

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