How do I check if an array of tuples contains a particular one in Swift?

前端 未结 6 965
温柔的废话
温柔的废话 2021-01-12 02:28

Consider the following Swift code.

var a = [(1, 1)]

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

All I need is to check if a

相关标签:
6条回答
  • 2021-01-12 02:47

    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.

    0 讨论(0)
  • 2021-01-12 02:49

    You can use a predicate and check for equality:

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

    You can also create your own contains methods that takes generic tuples:

    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 tuples.contains(tuple1) {
        print(true)
    } else {
        print(false)    // false
    }
    
    if tuples.contains(tuple2) {
        print(true)    // true
    } else {
        print(false)
    }
    
    0 讨论(0)
  • 2021-01-12 02:50

    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:

    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:

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

    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")
    }
    
    0 讨论(0)
  • 2021-01-12 02:55

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

    You may use switch instead of if condition

        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

        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")
            }
        }
    
    0 讨论(0)
  • 2021-01-12 02:58

    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:

    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
    }
    
    0 讨论(0)
  • 2021-01-12 02:59

    Swift 4

    Change your code to:

    var a = [(1, 1)]
    
    if a.contains(where: { $0 == (1, 2) } ) {
        print("Yes")
    }
    
    0 讨论(0)
提交回复
热议问题