Search code examples
scalafastutil

How do I combine fastutil maps in scala?


What's the quickest way to combine two Object2IntOpenHashMap[String] in scala? Looking to combine these two maps:

  val foo = new Object2IntOpenHashMap[String]
  foo.put("foo", 1)
  val bar = new Object2IntOpenHashMap[String]
  bar.put("foo", 1)
  bar.put("bar", 1)

And produce an output of {"foo" : 2, "bar" : 1}.


Solution

  • Below is the imperative way to combine the 2 Object2IntOpenHashMap values.

        val foo = new Object2IntOpenHashMap[String]
        foo.put("foo", 1)
        val bar = new Object2IntOpenHashMap[String]
        bar.put("foo", 1)
        bar.put("bar", 1)
    
        bar.keySet().forEach(x => {
            val barValue = bar.getInt(x)
            foo.computeInt(x ,  (_, v) => if(v == null) barValue else barValue + v)
        })
       println(foo)
    

    The above println(foo) will print {bar=>1, foo=>2}.

    But if you want more functional way you should use more functional ibraries like cats or scalaz. I did this using cats -

                import cats.Semigroup
        import cats.implicits._
        import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
    
        implicit val Object2IntOpenHashMapSemiGroup = new Semigroup[Object2IntOpenHashMap[String]] {
    
            override def combine(x: Object2IntOpenHashMap[String], y: Object2IntOpenHashMap[String]): Object2IntOpenHashMap[String] = {
            val result: Object2IntOpenHashMap[String] = y.clone()
    
    
            x.keySet().forEach(x => {
                val barValue = y.getInt(x)
                result.computeInt(x ,  (_, v) => if(v == null) barValue else barValue +v)
            })
            result
            }
        }
        println(foo combine bar)
        println(Object2IntOpenHashMapSemiGroup.combine(foo, bar))
    

    You will get the same result as before. You can see the documentation here for semigroup here.