Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a Map to a Data Class

Tags:

java

kotlin

Is there an easy method in Kotlin to allow me to convert a Map to an arbitrary data class?

The Map I'm trying to convert has all of the keys of the required fields of the data class.

I've hunted around, but haven't been able to find anything that seems to talk about doing this in a very generic way.

I know that I can use ObjectMapper, but that requires an extra library. Looking for something that is available just with Kotlin.

like image 883
samanime Avatar asked Aug 17 '18 15:08

samanime


People also ask

What is a data class Kotlin?

Data class is a simple class which is used to hold data/state and contains standard functionality. A data keyword is used to declare a class as a data class.

How do you create a class on Kotlin?

To define a class in Kotlin, class keyword is used: class ClassName { // property // member function ... .. ... } Here, we defined a class named Lamp . The class has one property isOn (defined in same way as variable), and two member functions turnOn() and turnOff() .

What is .MAP in Kotlin?

Kotlin map is a collection that contains pairs of objects. Map holds the data in the form of pairs which consists of a key and a value. Map keys are unique and the map holds only one value for each key. Kotlin distinguishes between immutable and mutable maps.

How do you make a map with Kotlin?

The first and most standard way of creating a map in Kotlin is by using mapOf . mapOf creates an immutable map of the key-value pairs we provide as parameters. Since the map is immutable, we won't find methods like put , remove or any other modifying functions.


2 Answers

Why not just use a map delegate?

class MyData(val map: Map<String, String>) {
    val foo by map
    val bar by map
}

Or you can wrap it using a companion object and call it using MyData.from(mymap)

data class MyData(val foo: String, val bar: String) {
    companion object {
        fun from(map: Map<String, String>) = object {
            val foo by map
            val bar by map

            val data = MyData(foo, bar)
        }.data
    }
like image 99
killjoy Avatar answered Sep 21 '22 07:09

killjoy


using kotlin reflection to map constructor parameters to map values this generic function will work for any class that receives field data in the primary constructor

Works well with JSON dbs like firebase and was tested with Map objects from Firebase DocumentSnapshot.data

fun <T : Any> mapToObject(map: Map<String, Any>, clazz: KClass<T>) : T {
    //Get default constructor
    val constructor = clazz.constructors.first()
    
    //Map constructor parameters to map values
    val args = constructor
    .parameters
    .map { it to map.get(it.name) }
    .toMap()
   
    //return object from constructor call
    return constructor.callBy(args)
}

with some class

data class Person(val firs: String, val last: String)

use like this

mapToObject(map, Person::class)
like image 44
saulpalv Avatar answered Sep 24 '22 07:09

saulpalv