2015-09-28 34 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 –