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

时间:2022-01-15 16:00:54

Consider the following Swift code.

考虑以下Swift代码。

var a = [(1, 1)]

if contains(a, (1, 2)) {
    println("Yes")
}

All I need is to check if a contains the tuple but the code leads to error.

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

Cannot find an overload for 'contains' that accepts an argument list of type '([(Int, Int)], (Int, Int))'

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

Why so and how to use contains properly?

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

5 个解决方案

#1


6  

Add the following to your code:

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

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 is not that flexible when it comes to tuples. They do not conform to the Equatable protocol. So you must define that or use the above function.

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

#2


9  

While tuples aren’t Equatable, you do not need to go so far as writing your own version of contains, since there is a version of contains that takes a matching predicate:

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

if contains(a, { $0.0 == 1 && $0.1 == 2 }) {
     // a contained (1,2)
}

While you can’t extend tuples to be equatable, you can write a version of == for tuples, which would make the above code simpler:

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

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

It’d be nice to be able to write a version of contains for tuples, but alas, I don’t think the placeholder syntax supports it:

能够为元组编写一个contains版本会很好,但是,我不认为占位符语法支持它:

EDIT: as of Swift 1.2, this does now compile as you can use tuples in placeholder constraints

编辑:从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")
}

#3


6  

Xcode 8.2.1 • Swift 3.0.2

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)
}

#4


2  

You can't use the contains method for your problem. Also there is no embedded solution in Swift. So you need to solve that by yourself. You can create a simple function to check if a tuple in your array is the same as your tuple to check:

您不能对您的问题使用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
}

#5


1  

Maybe too old for this question hope someone will get help with more option.

也许这个问题太老了,希望有人会得到更多选择的帮助。

You may use switch instead of if condition

您可以使用switch而不是if条件

    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")
        }
    }

Also have some more option to do check here from apple doc

还有一些选项可以从apple doc进行检查

    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")
        }
    }

#1


6  

Add the following to your code:

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

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 is not that flexible when it comes to tuples. They do not conform to the Equatable protocol. So you must define that or use the above function.

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

#2


9  

While tuples aren’t Equatable, you do not need to go so far as writing your own version of contains, since there is a version of contains that takes a matching predicate:

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

if contains(a, { $0.0 == 1 && $0.1 == 2 }) {
     // a contained (1,2)
}

While you can’t extend tuples to be equatable, you can write a version of == for tuples, which would make the above code simpler:

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

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

It’d be nice to be able to write a version of contains for tuples, but alas, I don’t think the placeholder syntax supports it:

能够为元组编写一个contains版本会很好,但是,我不认为占位符语法支持它:

EDIT: as of Swift 1.2, this does now compile as you can use tuples in placeholder constraints

编辑:从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")
}

#3


6  

Xcode 8.2.1 • Swift 3.0.2

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)
}

#4


2  

You can't use the contains method for your problem. Also there is no embedded solution in Swift. So you need to solve that by yourself. You can create a simple function to check if a tuple in your array is the same as your tuple to check:

您不能对您的问题使用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
}

#5


1  

Maybe too old for this question hope someone will get help with more option.

也许这个问题太老了,希望有人会得到更多选择的帮助。

You may use switch instead of if condition

您可以使用switch而不是if条件

    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")
        }
    }

Also have some more option to do check here from apple doc

还有一些选项可以从apple doc进行检查

    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")
        }
    }