https://kotlinlang.org logo
l

lazt omen

05/19/2022, 1:22 AM
Is it possible to instantiate a data class with dynamic properties. Let's say I have this.
Copy code
data class Business(
    val id: Int,
    val name: String
)

val columns = listOf("id", "name")
val values = listOf(1, "Hello")
Is it possible to instantiate this class mapping dynamically my columns to contructor parameters?
e

ephemient

05/19/2022, 4:58 AM
Copy code
val cons = Business::class.primaryConstructor!!
val params = columns.map { name ->
    cons.parameters.single { it.name == name }
}
val business = cons.callBy(params.zip(values).toMap())
this does not check for multiple constructors, missing parameters, mismatched types, but may be enough to get you started
1
🙌 1
l

lazt omen

05/19/2022, 7:32 AM
It totally works awesome thanks a lot.
d

DALDEI

05/30/2022, 8:01 PM
If you can control the source for the data class you can achive this by property delegation: data class Business( private val _data : Map<String,Any> ) { val id : Int by _data val name : String by _data } val m = columns.zip( values ) { a,b -> a to b }.toMap()) val v = Business(m)
e

ephemient

05/30/2022, 8:16 PM
that's potentially unsafe, as
Copy code
Business(mapOf())
doesn't fail at construction time, but at some later point in time when the properties are accessed, and loses other features of data classes like copy
you could write
Copy code
data class Business(val id: Int, val name: String)
fun Business(data: Map<String, Any>): Business? {
    return Business(
        data["id"] as? Int ?: return null,
        data["name"] as? String ?: return null,
    )
}
if you want that interface without reflection
9 Views