Home > OS >  How to write map from string to function with arguments in Scala
How to write map from string to function with arguments in Scala

Time:08-09

I am working on a project where i supposed to work with conversion based on the key. Since there are lot of key are there I was supposed to write a case for each key and logic for that code. But this approach leads to increase in lines of code.

So I was required to change the code by using map(key ->fun(length ,description, convertionMatchCase)

val h = scala.collection.mutable.Map(
  "01" -> tagfunction(2, "Tag Length", "ToInt"),
  "02" -> tagfunction(1, "Firmware version", "ToInt"),
  "03" -> tagfunction(15, "IMEI", "ToASCII"),
  "04" -> tagfunction(2, "Device ID", "ToInt"),
  "10" -> tagfunction(2, "No of Archive records", "ToInt"),
  "20" -> tagfunction(4, "Date and time", "ToInt"),
  //"30" -> tagfunction(9, "Coordinates", "ToASCII"),
  //"33" -> tagfunction(4, "Speed and direction", "ToASCII"),
  "34" -> tagfunction(2, "Height", "ToSignedShort"),
  "35" -> tagfunction(1, "HDOP", "ToInt"),
  "40" -> tagfunction(2, "Status of device", "ToInt"),
  "41" -> tagfunction(2, "Supply Voltage", "ToInt"),
  "42" -> tagfunction(2, "Battery Voltage", "ToInt"),
  "43" -> tagfunction(1, "Temperature of tracking device", "ToSignedByte"),
)

The problem is that function's inside the map are executing automatically(even when i'm using lazy after calling a single map(key) every thing was executing)

Could any one please suggest me some solution. Thanks you

CodePudding user response:

First of all try to avoid using mutable Map's in favor of immutable ones as it is a more idiomatic approach in Scala.

Secondly - your Map is not a map from key to function, it is a map from key to a value. Possibly you are looking for lambda expressions:

val h = Map(
  "01" -> (() => tagfunction(2, "Tag Length", "ToInt")),
  "02" -> (() => tagfunction(1, "Firmware version", "ToInt")),
  ...
)

This will allow to get invokable function by key, though it is not very clear why do you need to invoke it every time (cause usually having functions with side effects is also considered non-idiomatic approach for Scala, at least by some =).

CodePudding user response:

I am not sure why number of lines matters in the first place ... but here is how you can minnimize it:

    val map = Map( // do not use mutable!
       "foo" -> (1, "bar"),
       "baz" -> (2, "bat"), 
       "bam" -> (3, "baz")
    )
    
    def convert(key: String) = tagfunction.tupled(map(key))

The last line might need a bit of an explanation. tagfunction.tuped converts a function of two arguments Int, String into a function with a single argument, which is a tuple (Int, String). Because tuples are stored in the map, you get one with map(key), and can send it directly into the function.

A longer way to write it would be:

   val (n,s) = map(key)
   tagfunction(n,s)

But since you are after minimizing the number of lines, I thought, I'd show you that little trick.

  • Related