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
ephemient
05/30/2022, 8:22 PM
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,
)
}