Home > front end >  How to convert map and nested map to string and vise versa in Kotlin?
How to convert map and nested map to string and vise versa in Kotlin?

Time:02-17

I have no idea how to convert HashMap and nested Hashmap to string and vise versa:

I use Room to save data in a local database. The "users " hashmap is a parameter of the data class. To save this parameter "users " in the Room database, we must convert it to a primitive such as string, boolen, Integer, etc. Room does not support object references, so type converters are required.

val users = HashMap<String, HashMap<String, Any>>()

    val user1 = HashMap<String, Any>()
    user1["filter"] = 0
    user1["group"] = "groupId"
    user1["labelsVisibility"] = true
    user1["sort"] = 1
    user1["view"] = 3
    users["user1"] = user1

    val user2 = HashMap<String, Any>()
    user2["filter"] = 0
    user2["group"] = "groupId"
    user2["labelsVisibility"] = true
    user2["sort"] = 1
    user2["view"] = 3
    users["user2"] = user2

CodePudding user response:

Solution

There may be a better way to do this, but it works

  1. converting a HashMap<String, HashMap<String, Any>> to a string using special symbols * (a symbols must be unique in string)

     fun fromUsersPreferences(users: HashMap<String, HashMap<String, Any>>): String {
       var usersString = ""
       users.forEach {
         usersString = usersString.plus("${it.key}*${it.value} ")
       }
       usersString = usersString.dropLast(1)
       return usersString
     }
    

output:

"user1*{filter=0, view=3, labelsVisibility=true, sort=1, group=groupId} user2*{filter=1, view=1, labelsVisibility=false, sort=0, group=groupId}"
  1. converting a string to a HashMap<String, HashMap<String, Any>>

    fun toUsersPreferences(users: String): HashMap<String, HashMap<String, Any>> {
     val usersMap = users.split(" ").associateTo(HashMap()){
         val list = it.split("*")
         val userKey = list[0]
         val userValue = list[1].removeSurrounding("{", "}").split(", ").associateTo(HashMap()){
             val (key, value) = it.split("=")
             if (key.equals("group")) {
                 Pair<String, Any>(key, value)
             } else if (key.equals("labelsVisibility")) {
                 Pair<String, Any>(key, value.toBoolean())
             } else {
                 Pair<String, Any>(key, value.toInt())
             }
         }
    
         Pair(userKey, userValue)
     }
    
     return usersMap
    }
    

output:

{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=1, view=1, labelsVisibility=false, sort=0, group=groupId}}

CodePudding user response:

As I said earlier in the comments, it could be easily done with Gson library:

// Configure Gson
val gson = GsonBuilder()
    // Using this strategy Gson first tries converting number to Long. 
    // If it fails (number is float), then it tries converting to Double
    .setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE) 
    .create()

// Convert to JSON string
val jsonString = gson.toJson(users)
println("JSON => $jsonString")

// Store at Room as a string...
// Fetch later from Room as a string...

val type = object : TypeToken<HashMap<String, HashMap<String, Any>>>() {}.type
val fromJsonMap: HashMap<String, HashMap<String, Any>> = gson.fromJson(jsonString, type)

println("ORIGINAL MAP =>\n$users")
println("RESTORED MAP =>\n$fromJsonMap")

Output:

JSON => {
  "user1": {
    "filter": 0,
    "view": 3,
    "labelsVisibility": true,
    "sort": 1,
    "group": "groupId"
  },
  "user2": {
    "filter": 0,
    "view": 3,
    "labelsVisibility": true,
    "sort": 1,
    "group": "groupId"
  }
}

ORIGINAL MAP =>
{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}}
RESTORED MAP =>
{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}}

As you can see both original Map users and restored Map fromJsonMap are identical.

  • Related