Equatable

Equatableプロトコルに準拠したクラスは
static func ==(lhs: Self, rhs: Self) -> Bool 関数を実装する必要があり、
何によって等しいかをこの中で定義してあげることで比較ができるようになります。


EquatableSample.swift
1
2
3
4
5
6
7
8
9
10
class IntegerRef: Equatable {
    let value: Int
    init(_ value: Int) {
        self.value = value
    }

    static func == (lhs: IntegerRef, rhs: IntegerRef) -> Bool {
        return lhs.value == rhs.value
    }
}

参考:https://developer.apple.com/documentation/swift/equatable


これにより、IntegerRef(10) == IntegerRef(10)true となります。
よって、以下のようなテストコードは通るようになります。


EquatableSampleTests.swift
1
2
3
4
func testEquality() {
    XCTAssertTrue(IntegerRef(10) == IntegerRef(10))
    XCTAssertFalse(IntegerRef(10) == IntegerRef(11))
}



どう使うのか

自作クラスのArrayもEquatableプロトコルに準拠していればcontains() を用いた際に、
配列の中に指定したオブジェクトが存在しているかを確認できます。


上記の例を用いて、書くとこのようになります。

EquatableSample.swift
1
2
3
4
let array = [IntegerRef(10), IntegerRef(11), IntegerRef(12)]

array.contains(IntegerRef(10))  // => true
array.contains(IntegerRef(13))  // => false



さらに便利に使う

EquatableSample.swift
1
2
3
4
5
6
7
8
9
10
11
12
/// 重複した要素を削除するArray型の拡張
extension Array where Element: Equatable {
    var unique: [Element] {
        return reduce([], {
            $0.contains($1) ? $0 : $0 + [$1]
        })
    }
}

let array = [IntegerRef(10), IntegerRef(11), IntegerRef(12), IntegerRef(11)]
print(array)  // [IntegerRef(10), IntegerRef(11), IntegerRef(12), IntegerRef(11)]
print(array.unique)  // [IntegerRef(10), IntegerRef(11), IntegerRef(12)]

上記のようにArrayを拡張してあげれば、配列の重複を防ぐことが可能になります。