In this tutorial, let’s see what is like confirming to Equatable protocol and where exactly it fits in app development.
It’s quite often we compare things/objects.
let currentAddress = "New York, America"
let selectedAddress = "New York, America"
if currentAddress == selectedAddress {
print("Deliver to current address.")
} else {
print("Deliver to selected address.")
}
As these are strings, directly we can use equal to(==) operator.
What If thy are custom objects ?
let currentAddress = Address(city: "Amsterdam",
state: "New York",
country: "America")
let selectedAddress = Address(city: "Amsterdam",
state: "New York",
country: "America")
state: "New York",
country: "America")
let selectedAddress = Address(city: "Amsterdam",
state: "New York",
country: "America")
if currentAddress == selectedAddress {
}
If you compare two custom objects, We get below build error,
// Binary operator '==' cannot be applied to two 'Address' operands
Here what we can do is to write a method in Address struct.
struct Address {
let currentAddress = Address(city: "Amsterdam",
state: "New York",
country: "America")
let selectedAddress = Address(city: "Amsterdam",
state: "New York",
country: "America")
let city: String
let state: String
let country: String
func isEqual(to address: Address) -> Bool {
if city == address.city &&
state == address.state &&
country == address.country {
return true
}
return false
}
}
state: "New York",
country: "America")
let selectedAddress = Address(city: "Amsterdam",
state: "New York",
country: "America")
if selectedAddress.isEqual(to: currentAddress) {
}
This solves the scenario for now.
What if we have an array of addresses and we need to find a address in that?
And we can not directly use contains by passing element like below.
var countries = ["Canada", "Australia", "India", "America"]
let country = "India"
if countries.contains(country) {
}
We have to use the Array’s contains(where) closure.
let addresses = [
Address(city: "Amsterdam", state: "New York", country: "America"),
Address(city: "Belmont", state: "California", country: "America"),
Address(city: "Hartford", state: "Connecticut", country: "America")
]
Address(city: "Amsterdam", state: "New York", country: "America"),
Address(city: "Belmont", state: "California", country: "America"),
Address(city: "Hartford", state: "Connecticut", country: "America")
]
let selectedAddress = Address(city: "Hartford", state: "Connecticut", country: "America")
let contains = addresses.contains { (address) -> Bool in
return (selectedAddress.city == address.city &&
selectedAddress.state == address.state &&
selectedAddress.country == address.country)
}
We need to check with the Array contains method with the same condition we used in Address struct method isEqual()
func isEqual(to address: Address) -> Bool {
if city == address.city &&
state == address.state &&
country == address.country {
return true
}
return false
}
let contains = addresses.contains { (address) -> Bool in
return (selectedAddress.city == address.city &&
selectedAddress.state == address.state &&
selectedAddress.country == address.country)
}
Isn’t it a tedious job?
So, This is the use case of Equatable protocol, where it gives the easy solution/way for comparing two objects and finding an object in a collection.
It is as simple as shown below.
Let our Address structure confirm to Equatable protocol.
Earlier, prior to Swift 4.1 version, we need to implement below == static method where we can write equality logic.
struct Address: Equatable {
let city: String
let state: String
let country: String
public static func == (lhs: Address, rhs: Address) -> Bool {
return lhs.city == rhs.city &&
lhs.state == rhs.state &&
lhs.country == rhs.country
}
}
From Swift 4.1 onwards, we don’t need to write the boilerplate code for Equatable protocol unless we need to change the logic.
struct Address: Equatable {
let city: String
let state: String
let country: String
}
By default, boilerplate code compares all the stored properties.
public static func == (lhs: Address, rhs: Address) -> Bool {
return lhs.city == rhs.city &&
lhs.state == rhs.state &&
lhs.country == rhs.country
}
If you want to customise you can implement the == method. In this case, If you want to compare just city and state.
struct Address: Equatable {
let city: String
let state: String
let country: String
public static func == (lhs: Address, rhs: Address) -> Bool {
return lhs.state == rhs.state &&
lhs.country == rhs.country
}
}
Now, we can compare objects like native things.
let currentAddress = Address(city: "Amsterdam",
state: "New York", country: "America")
state: "New York", country: "America")
let selectedAddress = Address(city: "Amsterdam",
state: "New York", country: "America")
if currentAddress == selectedAddress {
}
And also below. When we call !=, It takes the reverse of == method. No need to write extra code for !=
if currentAddress != selectedAddress {
}
So, comparing objects became easy with Equatable protocol. Let’s see finding an element in a collection if all the objects in the collection confirm to Equatable protocol.
let addresses = [
Address(city: "Amsterdam", state: "New York", country: "America"),
Address(city: "Belmont", state: "California", country: "America"),
Address(city: "Hartford", state: "Connecticut", country: "America")
]
Address(city: "Amsterdam", state: "New York", country: "America"),
Address(city: "Belmont", state: "California", country: "America"),
Address(city: "Hartford", state: "Connecticut", country: "America")
]
let selectedAddress = Address(city: "Hartford", state: "Connecticut", country: "America")
I want to check whether addresses collection contains selected address or not. As Address confirm to Equatable protocol and addresses array is a collection of Address objects. We get another useful and simple contains() method now.
let addresses = [
Address(city: "Amsterdam", state:
"New York", country: "America"),
Address(city: "Belmont", state:
"California", country: "America"),
Address(city: "Hartford", state:
"Connecticut", country: "America")
]
let selectedAddress = Address(city:
"Hartford", state:
"Connecticut", country: "America")
Address(city: "Amsterdam", state:
"New York", country: "America"),
Address(city: "Belmont", state:
"California", country: "America"),
Address(city: "Hartford", state:
"Connecticut", country: "America")
]
let selectedAddress = Address(city:
"Hartford", state:
"Connecticut", country: "America")
if addresses.contains(selectedAddress) {
}
We can simply find objects now using contains.
That’s how Equatable makes it easy of comparing custom objects and finding custom objects in a collection.
Hope this post is useful. Feel free to comment in case of any queries.
No comments:
Post a Comment