如何在Swift中检查元组数组是否包含特定元组?

Jay*_*man 5 arrays tuples swift

请考虑以下Swift代码.

var a = [(1, 1)]

if contains(a, (1, 2)) {
    println("Yes")
}
Run Code Online (Sandbox Code Playgroud)

我只需要检查是否a包含元组,但代码会导致错误.

无法找到接受"([(Int,Int)],(Int,Int))类型的参数列表的'contains'的重载''

为什么这样以及如何contains正确使用?

Air*_*ity 9

虽然元组不是Equatable,但你不需要编写自己的版本contains,因为有一个版本contains需要一个匹配的谓词:

if contains(a, { $0.0 == 1 && $0.1 == 2 }) {
     // a contained (1,2)
}
Run Code Online (Sandbox Code Playgroud)

虽然你不能将元组扩展为等同,但你可以编写一个==for元组的版本,这将使上面的代码更简单:

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

contains(a) { $0 == (1,2) } // returns true
Run Code Online (Sandbox Code Playgroud)

这将会是不错的,能够写出一个版本的contains元组,但很可惜,我不认为占位符语法支持它:

编辑:从Swift 1.2开始,现在可以编译,因为您可以在占位符约束中使用元组

func contains
  <S: SequenceType, T: Equatable, U: Equatable where S.Generator.Element == (T,U)>
  (seq: S, x: (T,U)) -> Bool {
    return contains(seq) { $0.0 == x.0 && $0.1 == x.1 }
}

let a = [(1,1), (1,2)]

if contains(a, (1,2)) {
    println("Yes")
}
Run Code Online (Sandbox Code Playgroud)


Leo*_*bus 8

Xcode 8.2.1•Swift 3.0.2

let tuples = [(1, 1), (0, 1)]

let tuple1 = (1, 2)
let tuple2 = (0, 1)

if tuples.contains(where: {$0 == tuple1}) {
    print(true)
} else {
    print(false)    // false
}

if tuples.contains(where: {$0 == tuple2}) {
    print(true)    // true
} else {
    print(false)
}
Run Code Online (Sandbox Code Playgroud)


qwe*_*_so 7

将以下内容添加到您的代码中:

func contains(a:[(Int, Int)], v:(Int,Int)) -> Bool {
  let (c1, c2) = v
  for (v1, v2) in a { if v1 == c1 && v2 == c2 { return true } }
  return false
}
Run Code Online (Sandbox Code Playgroud)

当谈到元组时,Swift并不灵活.它们不符合Equatable协议.所以你必须定义它或使用上面的函数.

  • @Jay Tuples作为一个整体不能是"Equatable",因为它们可能包含不可比的类型.对于选项和数组也是如此,它们可以(也可以)具有`==`但不是'Equatable`.元组有一个额外的复杂性,即没有办法编写适用于2元组,3元组,n元组等的通用代码,因此没有为它们定义默认的`==`. (3认同)