次のクラスが与えられた場合、2つのインスタンスのすべての値を互いに比較するにはどうすればよいですか?
// Client Object
//
class PLClient {
var name = String()
var id = String()
var email = String()
var mobile = String()
var companyId = String()
var companyName = String()
convenience init (copyFrom: PLClient) {
self.init()
self.name = copyFrom.name
self.email = copyFrom.email
self.mobile = copyFrom.mobile
self.companyId = copyFrom.companyId
self.companyName = copyFrom.companyName
}
}
var clientOne = PLClient()
var clientTwo = PLClient(copyFrom: clientOne)
if clientOne == clientTwo { // Binary operator "==" cannot be applied to two PLClient operands
println("No changes made")
} else {
println("Changes made. Updating server.")
}
この使用例は、サーバーからのデータを表示するアプリケーションです。データがオブジェクトに変換されると、オブジェクトのコピーが作成されます。ユーザーは、オブジェクトの1つの値を変更するさまざまなフィールドなどを編集できます。
更新された可能性のあるメインオブジェクトを、そのオブジェクトのコピーと比較する必要があります。オブジェクトが等しい(すべてのプロパティの値が同じ)場合、何も起こりません。いずれかの値が等しくない場合、アプリケーションは変更をサーバーに送信します。
コードサンプルに示すように、値が指定されていないため、==
演算子は受け入れられません。 ===
を使用しても、常に2つの別個のインスタンスになるため、望ましい結果は得られません。
クラスがEquatableプロトコルに準拠していることを示し、==演算子を実装します。
このようなもの:
class PLClient: Equatable
{
var name = String()
var id = String()
var email = String()
var mobile = String()
var companyId = String()
var companyName = String()
//The rest of your class code goes here
public static func ==(lhs: PLClient, rhs: PLClient) -> Bool{
return
lhs.name == rhs.name &&
lhs.id == rhs.id &&
lhs.email == rhs.email &&
lhs.mobile == rhs.mobile &&
lhs.companyId == rhs.companyId &&
lhs.companyName == rhs.companyName
}
}
Duncan Cの回答に基づいて、カスタムの方法で使用されていることを少し明確にした代替案を考え出しました。
// Client Object
//
class PLClient {
var name = String()
var id = String()
var email = String()
var mobile = String()
var companyId = String()
var companyName = String()
convenience init (copyFrom: PLClient) {
self.init()
self.name = copyFrom.name
self.email = copyFrom.email
self.mobile = copyFrom.mobile
self.companyId = copyFrom.companyId
self.companyName = copyFrom.companyName
}
func equals (compareTo:PLClient) -> Bool {
return
self.name == compareTo.name &&
self.email == compareTo.email &&
self.mobile == compareTo.mobile
}
}
var clientOne = PLClient()
var clientTwo = PLClient(copyFrom: clientOne)
if clientOne.equals(clientTwo) {
println("No changes made")
} else {
println("Changes made. Updating server.")
}
keypath
を使用してフィールドをループできます
私はこれをテストしていませんが、一般的な考え方はそこにあります。有効なフィールドのリストを提供し、すべての赤道を書く代わりにそれらをループします。つまり、@ duncan-cと同じですが、ループが含まれています。
何かのようなもの:
class PLClient:Equatable {
var name = String()
var id = String()
var email = String()
var mobile = String()
var companyId = String()
var companyName = String()
public static func ==(lhs: PLClient, rhs: PLClient) -> Bool{
let keys:[KeyPath<PLClient, String>] = [\.name, \.id, \.email, \.mobile, \.companyId, \.companyName]
return keys.allSatisfy { lhs[keyPath: $0] == rhs[keyPath: $0] }
}
}