在Kotlin中合并/合并数据类 [英] Combining/merging data classes in Kotlin
本文介绍了在Kotlin中合并/合并数据类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
是否可以在不指定所有属性的情况下合并kotlin数据类?
Is there a way to merge kotlin data classes without specifying all the properties?
data class MyDataClass(val prop1: String, val prop2: Int, ...//many props)
具有以下签名的功能:
fun merge(left: MyDataClass, right: MyDataClass): MyDataClass
此函数检查两个类上的每个属性,而在其中不同的地方,使用left参数创建一个新的MyDataClass.
where this function checks each property on both classes and where they are different uses the left parameter to create a new MyDataClass.
使用kotlin-reflect或其他方法是否有可能?
Is this possible possible using kotlin-reflect, or some other means?
更清晰
这是对我想做的事的更好描述
Here is a better description of what i want to be able to do
data class Bob(
val name: String?,
val age: Int?,
val remoteId: String?,
val id: String)
@Test
fun bob(){
val original = Bob(id = "local_id", name = null, age = null, remoteId = null)
val withName = original.copy(name = "Ben")
val withAge = original.copy(age = 1)
val withRemoteId = original.copy(remoteId = "remote_id")
//TODO: merge without accessing all properties
// val result =
assertThat(result).isEqualTo(Bob(id = "local_id", name = "Ben", age=1, remoteId = "remote_id"))
}
推荐答案
infix fun <T : Any> T.merge(mapping: KProperty1<T, *>.() -> Any?): T {
//data class always has primary constructor ---v
val constructor = this::class.primaryConstructor!!
//calculate the property order
val order = constructor.parameters.mapIndexed { index, it -> it.name to index }
.associate { it };
// merge properties
@Suppress("UNCHECKED_CAST")
val merged = (this::class as KClass<T>).declaredMemberProperties
.sortedWith(compareBy{ order[it.name]})
.map { it.mapping() }
.toTypedArray()
return constructor.call(*merged);
}
编辑
infix fun <T : Any> T.merge(right: T): T {
val left = this;
return left merge mapping@ {
// v--- implement your own merge strategy
return@mapping this.get(left) ?: this.get(right);
};
}
示例
val original = Bob(id = "local_id", name = null, age = null, remoteId = null)
val withName = original.copy(name = "Ben")
val withAge = original.copy(age = 1)
val withRemoteId = original.copy(remoteId = "remote_id")
val result = withName merge withAge merge withRemoteId;
这篇关于在Kotlin中合并/合并数据类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文