2

What is a simple approach to testing whether a Map[A,B] is bijective, namely for

val m1 = Map( 1 -> "a", 2 -> "b")
val m2 = Map( 1 -> "a", 2 -> "a")

we have that m1 is bijective unlike m2.

elm
  • 20,117
  • 14
  • 67
  • 113
  • This is essentially a math question about the definition of bijection (possible HW help?). I for one got here because I was looking for a Bijective Map, which does not appear to be available in the standard scala library. :( – combinatorist May 24 '23 at 22:33

2 Answers2

8

You could do

val m = Map(1 -> "a", 2 -> "a")
val isBijective = m.values.toSet.size == m.size

A bijection is one-to-one and onto. The mapping defined by a Map is definitely onto. Every value has a corresponding key.

The only way it's not one-to-one is if two keys map to the same value. But that means that we'll have fewer values than keys.

mrmcgreg
  • 2,754
  • 1
  • 23
  • 26
2

As explained here -

For a pairing between X and Y (where Y need not be different from X) to be a bijection, four properties must hold:

1) each element of X must be paired with at least one element of Y
This is inherent nature of Map. In some cases it can be mapped to None which is again one of the element of Y.

2) no element of X may be paired with more than one element of Y,
Again inherent neture of Map.

3) each element of Y must be paired with at least one element of X, and Every element in Y will have some association with X otherwise it won't exist.

4) no element of Y may be paired with more than one element of X.
Map doesnt have this constraint. So we need to check for this. If Y contains duplicates then it is violated.

So, sufficient check should be "No duplicates in Y")

val a = scala.collection.mutable.Map[Int, Option[Int]]()
a(10) = None
a(20) = None
if(a.values.toArray.distinct.size != a.values.size) println("No") else println("Yes") // No

val a = Map("a"->10, "b"->20)
if(a.values.toArray.distinct.size != a.values.size) println("No") else println("Yes") // Yes

val a = scala.collection.mutable.Map[Int, Option[Int]]()
a(10) = Some(100)
a(20) = None
a(30) = Some(300)
if(a.values.toArray.distinct.size != a.values.size) println("No") else println("Yes") // Yes
nil
  • 563
  • 5
  • 8