Menu
Coddy logo textTech

Equatable

CoddyのSwiftジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 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 == を自分で記述します。ここでは、名前に関係なく、id が一致する場合に2つのユーザーを等しいとみなします。

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 が一致する場合、2つの製品は同じものです。カスタム == を使って 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プレイグラウンド