Search code examples
scalatypesafe-config

How to convert ConfigValue to List[ConfigObject] in typesafeconfig


I am new to Scala and to typesafeconfig. I have the following issue - I have a configuration like this -

a = [
      {
        b1 = [
          { 
            c1 = 3, 
            c2 = 4
          }, {
            c1 = 3, 
            c2 = 21
          }
        ]
      }, {
        b2 = [
          {
            c1 = 10, 
            c2 = 56
          }, 
          # ...many more elements
        ]
      }
      # .
      # .
      # .many more elements
    ]

I have been able to put the above in a Map[String, ConfigValue] using the following code -

val list : Iterable[ConfigObject] = config.getObjectList(PathTo 'a').asScala

val pairs = for {
  item: ConfigObject <- list
  entry : Entry[String, Config] <- item.entrySet().asScala
  key = entry.getKey
  value = entry.getValue.atKey(key)
 } yield (key, value)

pairs.toMap

In this Map I am getting keys as b1, b2, etc. - which is fine but the problem is that I am getting values as ConfigValue (and I not finding a good way to capture values List[ConfigObject] or something better). So, for example, at runtime I can see my that the value corresponding to key b1 has two entries - {c1=3, c2=4} and {c1=3, c2=21} but I am unable to traverse these two one by one and get to c1 and c2.

So, my question to folks with a bit of experience in TypeSafeConfig and Scala is - is there a better way I can make my Map so that I can traverse the values in b1, b2, etc. with ease or is there a good way to convert my current value which is a ConfigValue to something better that's iterable.

Thanks in advance!


Solution

  • The method toMap is found on a collection of type Collection[(K, V)] (collections of 2-tuples), and it returns a Map[K, V]. Duplicate keys are lost. Instead of calling pairs.toMap, you need to group each value by its key, first:

    pairs.groupBy(_._1)         // produces a Map[String, Array[(String, ConfigValue)]
      .mapValues(_.map(_._1))   // produces a Map[String, Array[ConfigValue] 
    

    This should give you the ability to iterate through the configurations as you need.