In Swift can I use a tuple as the key in a dictionary?

后端 未结 9 1167
清酒与你
清酒与你 2020-12-03 04:15

I\'m wondering if I can somehow use an x, y pair as the key to my dictionary

let activeSquares = Dictionary <(x: Int, y: Int), SKShapeNode>()


        
相关标签:
9条回答
  • 2020-12-03 05:00

    Or just use Arrays instead. I was trying to do the following code:

    let parsed:Dictionary<(Duration, Duration), [ValveSpan]> = Dictionary(grouping: cut) { span in (span.begin, span.end) }
    

    Which led me to this post. After reading through these and being disappointed (because if they can synthesize Equatable and Hashable by just adopting the protocol without doing anything, they should be able to do it for tuples, no?), I suddenly realized, just use Arrays then. No clue how efficient it is, but this change works just fine:

    let parsed:Dictionary<[Duration], [ValveSpan]> = Dictionary(grouping: cut) { span in [span.begin, span.end] }
    

    My more general question becomes "so why aren't tuples first class structs like arrays are then? Python pulled it off (duck and run)."

    0 讨论(0)
  • 2020-12-03 05:02

    As mentioned in the answer above, it is not possible. But you can wrap tuple into generic structure with Hashable protocol as a workaround:

    struct Two<T:Hashable,U:Hashable> : Hashable {
      let values : (T, U)
    
      var hashValue : Int {
          get {
              let (a,b) = values
              return a.hashValue &* 31 &+ b.hashValue
          }
      }
    }
    
    // comparison function for conforming to Equatable protocol
    func ==<T:Hashable,U:Hashable>(lhs: Two<T,U>, rhs: Two<T,U>) -> Bool {
      return lhs.values == rhs.values
    }
    
    // usage:
    let pair = Two(values:("C","D"))
    var pairMap = Dictionary<Two<String,String>,String>()
    pairMap[pair] = "A"
    
    0 讨论(0)
  • 2020-12-03 05:03

    I created this code in an app:

    struct Point2D: Hashable{
        var x : CGFloat = 0.0
        var y : CGFloat = 0.0
    
        var hashValue: Int {
            return "(\(x),\(y))".hashValue
        }
    
        static func == (lhs: Point2D, rhs: Point2D) -> Bool {
            return lhs.x == rhs.x && lhs.y == rhs.y
        }
    }
    
    struct Point3D: Hashable{
        var x : CGFloat = 0.0
        var y : CGFloat = 0.0
        var z : CGFloat = 0.0
    
        var hashValue: Int {
            return "(\(x),\(y),\(z))".hashValue
        }
    
        static func == (lhs: Point3D, rhs: Point3D) -> Bool {
            return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z
        }
    
    }
    
    var map : [Point2D : Point3D] = [:]
    map.updateValue(Point3D(x: 10.0, y: 20.0,z:0), forKey: Point2D(x: 10.0, 
    y: 20.0))
    let p = map[Point2D(x: 10.0, y: 20.0)]!
    
    0 讨论(0)
提交回复
热议问题