Is there such a thing as bidirectional maps in Scala?

后端 未结 3 982
栀梦
栀梦 2021-02-12 10:11

I\'d like to link 2 columns of unique identifiers and be able to get a first column value by a second column value as well as a second column value by a first column value. Some

相关标签:
3条回答
  • 2021-02-12 10:34

    Here's a quick Scala wrapper for Guava's BiMap.

    import com.google.common.{collect => guava}
    import scala.collection.JavaConversions._
    import scala.collection.mutable
    import scala.languageFeature.implicitConversions
    
    class MutableBiMap[A, B] private (
        private val g: guava.BiMap[A, B] = new guava.HashBiMap[A, B]()) {
    
      def inverse: MutableBiMap[B, A] = new MutableBiMap[B, A](g.inverse)
    }
    
    object MutableBiMap {
    
      def empty[A, B]: MutableBiMap[A, B] = new MutableBiMap()
    
      implicit def toMap[A, B] (x: MutableBiMap[A, B]): mutable.Map[A,B] = x.g
    }
    
    0 讨论(0)
  • 2021-02-12 10:48

    Guava has a bimap that you can use along with

    import scala.collection.JavaConversions._
    
    0 讨论(0)
  • 2021-02-12 10:53

    My BiMap approach:

    object BiMap {
      private[BiMap] trait MethodDistinctor
      implicit object MethodDistinctor extends MethodDistinctor
    }
    
    case class BiMap[X, Y](map: Map[X, Y]) {
      def this(tuples: (X,Y)*) = this(tuples.toMap)
      private val reverseMap = map map (_.swap)
      require(map.size == reverseMap.size, "no 1 to 1 relation")
      def apply(x: X): Y = map(x)
      def apply(y: Y)(implicit d: BiMap.MethodDistinctor): X = reverseMap(y)
      val domain = map.keys
      val codomain = reverseMap.keys
    }
    
    val biMap = new BiMap(1 -> "A", 2 -> "B")
    println(biMap(1)) // A
    println(biMap("B")) // 2
    

    Of course one can add syntax for <-> instead of ->.

    0 讨论(0)
提交回复
热议问题