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

Arrays 如何检查元组数组是否包含Swift中的特定元组?,arrays,swift,tuples,Arrays,Swift,Tuples,考虑以下Swift代码 var a = [(1, 1)] if contains(a, (1, 2)) { println("Yes") } 我只需要检查a是否包含元组,但代码会导致错误 找不到接受参数列表的“contains”的重载 属于类型“([(Int,Int)],(Int,Int))” 为什么以及如何正确使用包含的内容?在代码中添加以下内容: func contains(a:[(Int, Int)], v:(Int,Int)) -> Bool { let (c1,

考虑以下Swift代码

var a = [(1, 1)]

if contains(a, (1, 2)) {
    println("Yes")
}
我只需要检查
a
是否包含元组,但代码会导致错误

找不到接受参数列表的“contains”的重载 属于类型“([(Int,Int)],(Int,Int))”


为什么以及如何正确使用
包含的内容?

在代码中添加以下内容:

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
}

Swift在元组方面没有那么灵活。它们不符合
均衡协议。因此,您必须定义或使用上述函数。

您不能使用
contains
方法解决您的问题。Swift中也没有嵌入式解决方案。所以你需要自己解决这个问题。 您可以创建一个简单的函数来检查数组中的元组是否与要检查的元组相同:

func checkTuple(tupleToCheck:(Int, Int), theTupleArray:[(Int, Int)]) -> Bool{
    //Iterate over your Array of tuples
    for arrayObject in theTupleArray{
        //If a tuple is the same as your tuple to check, it returns true and ends
        if arrayObject.0 == tupleToCheck.1 && arrayObject.1 == tupleToCheck.1 {
            return true
        }
    }

    //If no tuple matches, it returns false
    return false
}

您可以使用谓词并检查是否相等:

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)
}
您还可以创建自己的包含方法,该方法采用通用元组:

extension Sequence  {
    func contains<T, U>(_ tuple: (T, U)) -> Bool where T: Equatable, U: Equatable, Element == (T,U) {
        contains { $0 == tuple }
    }
    func contains<T, U, V>(_ tuple: (T, U, V)) -> Bool where T: Equatable, U: Equatable, V: Equatable, Element == (T,U,V) {
        contains { $0 == tuple }
    }
    func contains<T, U, V, W>(_ tuple: (T, U, V, W)) -> Bool where T: Equatable, U: Equatable, V: Equatable, W: Equatable,Element == (T, U, V, W) {
        contains { $0 == tuple }
    }
    func contains<T, U, V, W, X>(_ tuple: (T, U, V, W, X)) -> Bool where T: Equatable, U: Equatable, V: Equatable, W: Equatable, X: Equatable, Element == (T, U, V, W, X) {
        contains { $0 == tuple }
    }
    func contains<T, U, V, W, X, Y>(_ tuple: (T, U, V, W, X, Y)) -> Bool where T: Equatable, U: Equatable, V: Equatable, W: Equatable, X: Equatable, Y: Equatable, Element == (T, U, V, W, X, Y) {
        contains { $0 == tuple }
    }
}

虽然元组不可
相等
,但您不需要编写自己版本的
包含
,因为有一个版本的
包含
,它使用匹配的谓词:

if contains(a, { $0.0 == 1 && $0.1 == 2 }) {
     // a contained (1,2)
}
虽然不能将元组扩展为相等的,但可以为元组编写一个版本的
=
,这将使上述代码更简单:

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

对于这个问题来说,可能太老了,希望有人能得到更多选择的帮助

您可以使用
开关
,而不是
如果
条件

    var somePoint = [(0, 1), (1, 0), (0, 0), (-2, 2)]
    for innerSomePoint in somePoint {
        switch innerSomePoint {
        case (0, 0):
            print("\(innerSomePoint) first and second static")
        case (_, 0):
            print("\(innerSomePoint) first dynamic second static")
        case (0, _):
            print("\(innerSomePoint) first static second dynamic")
        case (-2...2, -2...2):
            print("\(innerSomePoint) both in between values")
        default:
            print("\(innerSomePoint) Nothing found")
        }
    }


Swift 4

将代码更改为:

var a = [(1, 1)]

if a.contains(where: { $0 == (1, 2) } ) {
    print("Yes")
}

听起来很奇怪,元组不可
相等
,不能使用
=
检查两个元组是否相等。@Jay元组作为一个整体不能
相等
,因为它们可能包含不相等的类型。选项和数组也是如此,它们也可以(也确实)有一个
==
,但不
相等。元组有一个额外的复杂性,即无法编写适用于2元组、3元组、n元组等的通用代码,因此没有为它们定义默认的
==
。我喜欢函数式编程,但我对它有点怀疑,因为它可能会由于创建额外的集合而降低性能。所以我通常更喜欢迭代。这看起来很优雅。一个缺点是,对于(非常)大的阵列,它必须遍历整个阵列才能最终发现第一个已匹配的阵列,这将是浪费时间的…@JayForeman只要集合中的对象是不变的,就不会对性能产生影响。Swift非常聪明,如果它看到包含的对象是不可变的,就不会创建新的集合。@Leonardosavidabus?@AirspeedVelocity-您能发布Swift 3.0兼容版本的吗“func包含@AirspeedVelocity-请检查以下代码是否在Swift 3.0中正确转换。。。开始func-TupleContains(seq:S,x:(T,U))->Bool其中S.Iterator.Element==(T,U){return-seq.contains(其中:{0.0==x.0&&0.1==x.1}
    var somePoint = [(0, 1), (1, 0), (0, 0), (-2, 2)]
    for innerSomePoint in somePoint {
        switch innerSomePoint {
        case (0, 0):
            print("\(innerSomePoint) first and second static")
        case (_, 0):
            print("\(innerSomePoint) first dynamic second static")
        case (0, _):
            print("\(innerSomePoint) first static second dynamic")
        case (-2...2, -2...2):
            print("\(innerSomePoint) both in between values")
        default:
            print("\(innerSomePoint) Nothing found")
        }
    }
    somePoint = [(1, 1), (1, -1), (0, 0), (-2, 2)]
    for innerSomePoint in somePoint {
        switch innerSomePoint {
        case let (x, y) where x == y:
            print("(\(x), \(y)) is on the line x == y")
        case let (x, y) where x == -y:
            print("(\(x), \(y)) is on the line x == -y")
        case let (x, y):
            print("(\(x), \(y)) is just some arbitrary point")
        }
    }
var a = [(1, 1)]

if a.contains(where: { $0 == (1, 2) } ) {
    print("Yes")
}