How would one implement a bidirectional map in Swift?

廉价感情. 提交于 2019-11-30 18:05:46

问题


I am currently in need of a performant bidirectional map. In Swift, a dictionary can be reversed, however, that will return a tuple of the types it is made of, not a counterpart dictionary.

Is there a library for that or does someone have ideas on how to address this issue?

Thanks


回答1:


With Swift 4 you could easily make your own using a generic struct:

struct BidiMap<F:Hashable,T:Hashable>
{
   private var _forward  : [F:T]? = nil
   private var _backward : [T:F]? = nil

   var forward:[F:T]  
   { 
      mutating get 
      { 
        _forward = _forward ?? [F:T](uniqueKeysWithValues:_backward?.map{($1,$0)} ?? [] ) 
        return _forward!
      }
      set { _forward = newValue; _backward = nil }
   }

   var backward:[T:F]  
   { 
      mutating get 
      { 
        _backward = _backward ?? [T:F](uniqueKeysWithValues:_forward?.map{($1,$0)} ?? [] ) 
        return _backward!
      }
      set { _backward = newValue; _forward = nil }
   }

   init(_ dict:[F:T] = [:])
   { forward = dict  }

   init(_ values:[(F,T)])
   { forward = [F:T](uniqueKeysWithValues:values) }

   subscript(_ key:T) -> F? 
   { mutating get { return backward[key] } set{ backward[key] = newValue } }

   subscript(_ key:F) -> T?
   { mutating get { return forward[key]  } set{ forward[key]  = newValue } }

   subscript(to key:T) -> F? 
   { mutating get { return backward[key] } set{ backward[key] = newValue } }

   subscript(from key:F) -> T?
   { mutating get { return forward[key]  } set{ forward[key]  = newValue } }

   var count:Int { return _forward?.count ?? _backward?.count ?? 0 }
}

var bd = BidiMap( [1:"A", 2:"B", 3:"C"] )
bd[1] // "A"
bd["B"] // 2
bd[4] = "D"
bd[to:"D"] // 4
bd[from:4] // "D"

var int2int = BidiMap( [1:2, 5:3] )
int2int[from:1] // 2
int2int[to:3] // 5

[EDIT] improved performance a bit by delaying rebuilding of mirror dictionary until it is actually referenced.



来源:https://stackoverflow.com/questions/47073888/how-would-one-implement-a-bidirectional-map-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!