I do have 2 different tuples of type (Double, Double):
let tuple1: (Double, Double) = (1, 2)
let tuple2: (Double, Double) = (3, 4)
I want t
Update
As Martin R states in the comments, tuples with up to six components can now be compared with ==
. Tuples with different component counts or different component types are considered to be different types so these cannot be compared, but the code for the simple case I described below is now obsolete.
Try this:
func == <T:Equatable> (tuple1:(T,T),tuple2:(T,T)) -> Bool
{
return (tuple1.0 == tuple2.0) && (tuple1.1 == tuple2.1)
}
It's exactly the same as yours, but I called it ==
. Then things like:
(1, 1) == (1, 1)
are true and
(1, 1) == (1, 2)
are false
Similar to the answer of @JeremyP, but more generic:
func ==<T1: Equatable, T2: Equatable>(lhs: (T1, T2), rhs: (T1, T2)) -> Bool {
return lhs.0 == rhs.0 && lhs.1 == rhs.1
}
func ==<T1: Equatable, T2: Equatable, T3: Equatable>(lhs: (T1, T2, T3), rhs: (T1, T2, T3)) -> Bool {
return lhs.0 == rhs.0 && lhs.1 == rhs.1 && lhs.2 == rhs.2
}
func ==<T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable>(lhs: (T1, T2, T3, T4), rhs: (T1, T2, T3, T4)) -> Bool {
return lhs.0 == rhs.0 && lhs.1 == rhs.1 && lhs.2 == rhs.2 && lhs.3 == rhs.3
}
In swift there are tuples as we know. Tuples can be compared with each other using standard C operators. Tuples are compared with each other from LEFT to RIGHT
if (1,"death") < (3,"life") {
print("Life is better than death") // this is true
}
Swift only compares the integer values 1 and 3. That's it, Swift does not compare the strings of death and life. It will only compare them when the first elements of the tuple are the same.
if (99,"life") < (99,"death") {
print("Life is better than death") // this is false
}
In the above case swift does not compare the integer values of 99, instead it will compare life and death. Additionally: Swift can only compare tuples which have max 6 elements. More than 6 elements you have to compare it by yourself.
The following approach compares tuple of any number of members of any size, provided they do not contain collection types like Array
and Dictionary
.
import Darwin // or Foundation
/// here we go
func memeq<T>(var lhs: T, var rhs: T) -> Bool {
return withUnsafePointers(&lhs, &rhs) {
memcmp($0, $1, UInt(sizeof(T)))
} == 0
}
let l = (false, 42, log(exp(1.0)))
let r = (!true, 6*7, exp(log(1.0)))
println(memeq(l, r)) // expectedly true
let l2 = (0, [0])
let r2 = (0, [0])
println(memeq(l2, r2)) // unfortunately false
Note types are already checked via generics. If they differ, it does not even compile thanks to type checking.
I agree that this behavior is not expected, since tuples can be compared in diverse languages such as Python and Haskell, but according to the official documentation:
NOTE
Tuples are useful for temporary groups of related values. They are not suited to the creation of complex data structures. If your data structure is likely to persist beyond a temporary scope, model it as a class or structure, rather than as a tuple. For more information, see Classes and Structures.
So, this might be the Swift equivalent of "you're holding the phone wrong," but by current guidelines, the idiomatic way to do this is to define a Class or Struct (or even an Enum) with a Comparable implementation to provide ==
and related operators.
Swift 4 supports tuple comparison. You won't get the error anymore.
This code runs perfectly
let tuple1 : (Double, Double) = (1,2)
let tuple2 : (Double, Double) = (3,4)
if (tuple1 == tuple2) {
print("equal")
}
else {
print("unequal")
}
Here, unequal is printed in the console of the playground.
One limitation in tuple comparison as mentioned in the apple doc is -
The Swift standard library includes tuple comparison operators for tuples with fewer than seven elements. To compare tuples with seven or more elements, you must implement the comparison operators yourself.