2015-09-28 75 views
2

Swift元组不是可等值的,而且作为复合类型,它们不能通过协议扩展进行等化。解决方法(as documented in another answer)是为每个元组的元素创建==运算符的重载。如何测试命名元组的Swift数组的相等性

有趣的是,一个可以声明==运营商定期元组,并用它与命名字段进行比较的元组:

func ==<T1: Equatable, T2: Equatable>(lhs: (T1,T2), rhs: (T1,T2)) -> Bool { 
    return lhs.0 == rhs.0 && lhs.1 == rhs.1 
} 

var one = ("One", 1) 
let two = ("Two", 2) 
print(one == two) // "false" 

typealias NamedTuple2 = (name: String, value: Int) 
var namedone: NamedTuple2 = (name: "One", value: 1) 
let namedtwo: NamedTuple2 = (name: "Two", value: 2) 
print(namedone == namedtwo) // "false" 
print(namedone == one) // "true" 

元组阵列还需要一个定制的过载进行比较作为一个整体:

func ==<T0: Equatable, T1: Equatable>(lhs: [(T0, T1)], rhs: [(T0, T1)]) -> Bool { 
    if lhs.count != rhs.count { 
     return false 
    } 
    for (index, value) in lhs.enumerate() { 
     if !(value == rhs[index]) { 
      return false 
     } 
    } 
    return true 
} 

let array12: [(String, Int)] = [one, two] 
let array3: [Tuple2] = [("Three", 3)] 
print(array12 == array3) // "false" 

然而,该运营商不接受命名元组的数组:

let namedarray12: [NamedTuple2] = [namedone, namedtwo] 
let namedarray3: [NamedTuple2] = [array3[0]] 
print(namedarray12 == namedarray3) 
// error: binary operator '==' cannot be applied to two '[NamedTuple2]' operands 

有没有一种方法来测试命名元组的数组的相等性,而没有为特定的命名元组声明==的重载?

回答

6

方法SequenceType.elementsEqual(_,isEquivalent:)接受比较元素的谓词。同样的==重载对于命名和未命名的元组都是有效的。因此,不是试图将==作为一个整体应用于阵列,而是使用elementsEqual

func ==<T1: Equatable, T2: Equatable>(lhs: (T1,T2), rhs: (T1,T2)) -> Bool { 
    return lhs.0 == rhs.0 && lhs.1 == rhs.1 
} 

let namedarray: [(name: String, value: Int)] = [(name: "One", value: 1), (name: "Two", value: 2)] 
// namedarray == namedarray12 
namedarray.elementsEqual(namedarray12, isEquivalent: ==) // true 
+0

元组平等功能现已正式斯威夫特的一部分的2.2。请参阅https://github.com/apple/swift-evolution/blob/master/proposals/0015-tuple-comparison-operators.md –